Drop the access key: OIDC for GitHub Actions and AWS

A long-lived access key in CI is a credential you cannot see being used, cannot scope tightly, and will forget to rotate. GitHub Actions has supported OIDC for years, and the migration is smaller…

Share
Drop the access key: OIDC for GitHub Actions and AWS

A long-lived access key in CI is a credential you cannot see being used, cannot scope tightly, and will forget to rotate. GitHub Actions has supported OIDC for years, and the migration is smaller than it looks.

The shape of it

Instead of storing AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY as repository secrets, the workflow requests a short-lived token from GitHub and exchanges it for an IAM role:

permissions:
  id-token: write
  contents: read

steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::111122223333:role/github-actions-deploy
      aws-region: us-east-1

The role trusts GitHub's OIDC provider, with a condition on the sub claim so only the repository you intend can assume it.

The detail people get wrong

Trust the immutable form of the claim as well as the readable one:

repo:my-org/my-repo:*
repo:my-org@79019803/my-repo@1330095362:*

The second form encodes numeric org and repository IDs. It survives a rename; the first does not. Renaming a repository with only the readable form in the trust policy silently breaks every deploy, and the error you get back says nothing about renames.

What you gain

Credentials that expire in minutes, a CloudTrail entry that names the workflow rather than a shared key, and one fewer secret whose rotation nobody owns.