Configure OpenID Connect for GitHub in AWS CDK
Learn how to build a GitHub OpenID Connect (OIDC) with AWS CDK and create a GitHub Action workflow to authenticate with AWS.
Table of contents
- What is a GitHub OpenID Connect provider (OIDC)?
- Create the GitHub OIDC provider
- Create the IAM role with a WebIdentityPrincipal
- Create the IAM condition for the GitHub repositories and assign it to the WebIdentityPrincipal
- TL;DR just give me the GitHub OIDC AWS CDK code!
- Set up the Configure AWS Credentials Action For GitHub Actions
This guide will explain what is required to create a GitHub OpenID Connect (OIDC) provider in AWS CDK and includes a GitHub actions workflow example on how to authenticate to AWS and access resources using the aws-actions/configure-aws-credentials.
What is a GitHub OpenID Connect provider (OIDC)?
It's an identity provider for GitHub which uses the OpenID Connect protocol and can be set up on an AWS Account to establish trust between the account and your GitHub repository.
The advantage is that it allows you to access resources in AWS using an IAM role instead of using long-lived AWS credentials.
Create the GitHub OIDC provider
We'll start by creating the OpenIdConnectProvider
:
const githubDomain = 'token.actions.githubusercontent.com';
const ghProvider = new iam.OpenIdConnectProvider(this, 'githubProvider', {
url: `https://${githubDomain}`,
clientIds: ['sts.amazonaws.com'],
});
This resource needs the following properties:
url
:https://token.actions.githubusercontent.com
. This is the location where GitHub generated their OIDC tokensclientIds
:sts.amazonaws.com
. This is the AWS Security Token Service (STS) API that's being used for the IAM role authentication.
Create the IAM role with a WebIdentityPrincipal
Next up we'll create the IAM role that will be used to authenticate against the GitHub OIDC provider.
new iam.Role(this, 'exampleGitHubDeployRole', {
assumedBy: new iam.WebIdentityPrincipal(ghProvider.openIdConnectProviderArn, conditions),
managedPolicies: [
iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'),
],
roleName: 'exampleGitHubDeployRole',
description: 'This role is used via GitHub Actions to deploy with AWS CDK or Terraform on the target AWS account',
maxSessionDuration: cdk.Duration.hours(1),
});
The role that gets created needs to be assumed by the GitHub OIDC provider, so we're creating a new iam.WebIdentityPrincipal
for that to allow access.
For example purposes, we assign a managed policy for this role's permission. So basically this policy tells what the role is allowed to access on AWS. In this case with the managed AdministratorAccess
policy, it can access everything on the AWS account.
The maxSessionDuration
decides how long the AWS STS credentials can be used at a time before expiring. In this case, the duration of the session with the STS credentials is set to 1 hour.
Create the IAM condition for the GitHub repositories and assign it to the WebIdentityPrincipal
In the previous part we created the IAM role and as you can see we added conditions to the assumedBy
property:
assumedBy: new iam.WebIdentityPrincipal(ghProvider.openIdConnectProviderArn, conditions),
Now we'll focus on creating the condition for the GitHub repositories that require access to the IAM role so that you can access AWS resources from GitHub actions.
We declare the following variables and interface:
export interface GitHubStackProps extends cdk.StackProps {
readonly repositoryConfig: { owner: string; repo: string; filter?: string }[];
}
const iamRepoDeployAccess = props.repositoryConfig.map(r =>
`repo:${r.owner}/${r.repo}:${r.filter ?? '*'}`);
// grant only requests coming from a specific GitHub repository.
const conditions: iam.Conditions = {
StringLike: {
[`${githubDomain}:sub`]: iamRepoDeployAccess,
},
};
We set up an interface for repositoryConfig
, so we can pass a dictionary containing a list of repositories for example:
repositoryConfig: [
{ owner: 'dannysteenman', repo: 'aws-cdk-examples' },
{ owner: 'dannysteenman', repo: 'aws-toolbox', filter: 'main' },
],
This will map the input to the variable iamRepoDeployAccess
which will then add it to the IAM condition described in the variable conditions
which is assigned to the WebIdentityPrincipal
of the IAM role.
Basically, we've given two GitHub repositories of mine access to access AWS resources on the target account via GitHub actions. The added filter allows you to only give access to a certain branch to assume the IAM role, the default is '*'
which means all branches and tags.
TL;DR just give me the GitHub OIDC AWS CDK code!
If you just need the code, then you can find the full working example on my GitHub repository
Set up the Configure AWS Credentials
Action For GitHub Actions
So now that we've created the OIDC GitHub provider in AWS, we only need to set up the GitHub actions workflow which enables us to authenticate with the IAM role on the target AWS account.
AWS already did the heavy lifting and provided a pre-configured GitHub action aws-actions/configure-aws-credentials
You can add this as a step in your GitHub actions workflow. I've provided an example GitHub workflow file to show how you integrate the configure-aws-credentials
with a cdk deploy
task to an AWS test account.
name: deploy-test
on:
push:
branches:
- main
workflow_dispatch: {}
jobs:
deploy:
name: Deploy CDK stacks to test
runs-on: ubuntu-latest
permissions:
actions: write
contents: read
id-token: write
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::012345678901:role/exampleGitHubDeployRole
aws-region: eu-west-1
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.ref }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: CDK synth
run: npx cdk synth --app "npx ts-node src/main.ts" --output "cdk.out"
- name: CDK deploy
run: npx cdk deploy --all --app "cdk.out" --require-approval never
Note: make sure to change the following keys in the step Configure AWS credentials
role-to-assume: arn:aws:iam::012345678901:role/exampleGitHubDeployRole
. Change the AWS account id of the role ARN which matches the account id where you deployed the GitHub OIDC provider.region: eu-west-1
. Change this to the region where you wish to run yourcdk deploy
command.
๐ Enjoyed this article? Reach out in the comments below or on Twitter to let me know what you think of it.
If you found some value in reading this, please consider showing your support by sponsoring me. Thanks to your support, I'm able to continue doing what I enjoy the most, which is sharing my learnings with the Cloud Community. Donate here ๐