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…
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.