, ,

Configure OpenID Connect for GitHub in AWS CDK

/

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.

If you’re looking to configure OpenID Connect for Bitbucket, then read this article.

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 tokens
  • clientIds: 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/[email protected]
        with:
          role-to-assume: arn:aws:iam::012345678901:role/exampleGitHubDeployRole
          aws-region: eu-west-1
      - name: Checkout repo
        uses: actions/[email protected]
        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 your cdk deploy command.
Danny Steenman

Is a Principal Cloud Consultant with a background in DevOps Engineering and thorough hands-on experience in architecting and building highly scalable distributed systems on AWS Cloud using Infrastructure as Code.

A prominent leader who is passionate about sharing AWS technical expertise by writing technical articles.