<< All Blog Posts
Connect GitHub Actions and AWS using OIDC

Connect GitHub Actions and AWS using OIDC

In Fall of 2021 the GitHub Actions team released an OpenID Connect (OIDC) Identity Provider for GitHub Actions, which enables developers to configure workflows that request temporary, on-demand credentials from any service provider on the internet that supports OIDC authentication.

Here at Six Feet Up, we’re most excited about how simply and conveniently this allows for GitHub Actions to interact with AWS. In this post, I’ll walk you through an example Terraform configuration for setting up the authentication and an Actions workflow that uses it.

Setup

  1. Configure AWS Identity and Access Management (IAM) in our AWS account to believe what the GitHub Actions Identity Provider says.
  2. Make an IAM role available to GitHub Actions entities with specific properties.
  3. Add an Actions workflow to request and use credentials from AWS.


Add the GitHub Actions OIDC Provider to AWS IAM (Step #1)

First we use the aws_iam_openid_connect_provider terraform resource to add the Github Actions Identity Provider in the same way as one would any other SSO option.

resource "aws_iam_openid_connect_provider" "github" {
    url = "https://token.actions.githubusercontent.com"
    client_id_list = [
        "sts.amazonaws.com",
    ]
    thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}

ℹ️Note: When GitHub inevitably rotates the certificate for this service, the thumbprint_list value will need to be updated.


Add the IAM Role (Step #2)

Next, with the aws_iam_policy_document terraform data source, we create an assume role policy (which will determine under which circumstances the role we are creating can be used).

Notice specifically that:

  • principles.identifiers is a reference to the aws_iam_openid_connect_provider resource created above.
  • We are testing token.actions.githubusercontent.com:sub (which is the attribute that the GitHub Identity Provider uses to convey the workspace, repository name, and git ref of the GitHub Action making the request) to be sure that it matches the projects and branches we want to provide credentials to. Your values will need to replace github_workspace, application_repo, and the * if you intend to prevent Actions for arbitrary branches from accessing credentials.

Then, we simply create a role using that policy. At this point you can attach whatever permissions policies to the role are necessary for the work you intend the GitHub Action to perform (S3 read/write, ECS deployment, etc.).

data "aws_iam_policy_document" "github" {
    statement {
        effect = "Allow"
        actions = ["sts:AssumeRoleWithWebIdentity"]

        principals {
            type = "Federated"
            identifiers = [aws_iam_openid_connect_provider.github.arn]
        }

        condition {
            test = "StringEquals"
            variable = "token.actions.githubusercontent.com:aud"
            values = ["sts.amazonaws.com"]
        }

        condition {
             test = "StringLike"
             variable = "token.actions.githubusercontent.com:sub"
             values = ["repo:github_workspace/application_repo:*"]
        }
    }
}

resource "aws_iam_role" "github" {
    name = "github-oidc"
    assume_role_policy = data.aws_iam_policy_document.github.json
}

⚠️ In case you didn’t catch that, be sure to set the correct values for your project in the token.actions.githubusercontent.com:sub test. Otherwise, you might allow any GitHub Action from any repository to assume this role in your AWS account.

Add a GitHub Workflow (Step #3)

Finally, we define a workflow in .github/workflows/test-oidc.yml, which will assume the IAM role defined above, and make the credentials available for subsequent steps.

  • Set role-to-assume to the arn of the role created above. Also set region and duration appropriately.
  • Running aws sts get-caller-identity is all you need to prove that your credential workflow has succeeded.

Drop in any other steps needed for the GitHub Action to accomplish its work.

name: test-oidc
permissions:
  id-token: write # required to use OIDC authentication
  contents: read # required to checkout the code from the repo
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        role-to-assume: arn:aws:iam::123456789012:role/github-oidc
        role-duration-seconds: 600
        aws-region: us-west-2
      - name: Test AWS Creds
      run: aws sts get-caller-identity


Wrap Up

Now that you’ve seen it, I’m sure you’ll agree — this approach is much cleaner, simpler, nicer and safer when compared with the old, common practice of creating an IAM user and exporting access keys to GitHub Actions secrets 🤢.

For your reference, here are some docs:

Shout-out to the resources we found when we approached setting this for the first time. These posts really made the path clear:

Read more AWS blogs from Six Feet Up developers, and sign up for our newsletter — ACCELERATE — to get monthly tech tips in your inbox.


Thanks for filling out the form! A Six Feet Up representative will be in contact with you soon.

Connect with us