GitHub Actions to AWS with OIDC: no more long-lived keys
Federate your workflows into AWS with short-lived tokens scoped to repo and branch. Delete the access keys after.
A long-lived AWS_ACCESS_KEY_ID in GitHub repository secrets never expires, works from anywhere on the internet, and leaks the first time someone echos the wrong variable in a debug step or a fork PR exfiltrates secrets. OIDC federation removes the static key entirely: GitHub mints a short-lived JWT per workflow run, AWS STS exchanges it via AssumeRoleWithWebIdentity, and the job receives temporary credentials scoped to an IAM role — typically one hour, tied to that repository and ref.
The security boundary is the IAM role trust policy — specifically the sub claim condition that pins which repository, ref, or GitHub Environment may assume the role. Get it wrong and any fork or feature branch in your org can deploy to production. The Software supply chain security track covers OIDC federation, secret hygiene, signing, and pipeline hardening end to end.
Register the OIDC provider once per account. Every deploy role trust policy references the same provider ARN.
Register GitHub as an OIDC provider
Create an IAM OIDC identity provider with URL https://token.actions.githubusercontent.com and audience sts.amazonaws.com. AWS documents the thumbprint — verify it against current GitHub documentation when you set this up, as it can rotate. One provider per account; many roles can trust it with different sub conditions.
aws iam create-open-id-connect-provider \--url https://token.actions.githubusercontent.com \--client-id-list sts.amazonaws.com \--thumbprint-list 6938fd4d98bab03fa2718477c8256450588bf45a
A role that only your repo can assume
The trust policy allows sts:AssumeRoleWithWebIdentity from the federated principal. Two conditions matter: aud must equal sts.amazonaws.com, and sub must match the exact repository and ref (or GitHub Environment) you intend. Use StringLike for ref patterns only when you understand the blast radius — refs/heads/main is safer than *.
{"Effect": "Allow","Principal": {"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"},"Action": "sts:AssumeRoleWithWebIdentity","Condition": {"StringEquals": {"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"},"StringLike": {"token.actions.githubusercontent.com:sub": "repo:myorg/myapp:ref:refs/heads/main"}}}
The workflow side
Grant the job permissions.id-token: write — without it GitHub will not issue the OIDC token. Use aws-actions/configure-aws-credentials@v4 with role-to-assume; the action handles the STS exchange. Do not pass aws-access-key-id or aws-secret-access-key. Scope the role's permission policy to what the deploy actually needs — S3 put on one bucket, not AdministratorAccess.
permissions:id-token: write # required to request the OIDC tokencontents: readjobs:deploy:runs-on: ubuntu-latestenvironment: productionsteps:- uses: actions/checkout@v4- uses: aws-actions/configure-aws-credentials@v4with:role-to-assume: arn:aws:iam::123456789012:role/gha-deploy-prodaws-region: us-east-1- run: aws s3 sync ./dist s3://my-artifacts-prod/
aws sts get-caller-identity{ "Account": "123456789012", "Arn": "arn:aws:sts::123456789012:assumed-role/gha-deploy-prod/GitHubActions"}session expires in ~1h — nothing stored in repo secretsDelete the old access keys
Once OIDC works, rotate and delete long-lived IAM user access keys used by the old pipeline. A federated role sitting next to a live static key is the old attack surface with extra steps — attackers take the path of least resistance. Audit with aws iam get-access-key-last-used and remove keys with no recent legitimate use.
Where this goes next
The same federation pattern works for GCP Workload Identity Federation and Azure federated credentials — one OIDC token, many clouds. Layer GitHub Environment protection rules, Cosign keyless signing for artifacts, and OPA policy on Terraform plans so the identity hardening connects to verifiable deploys. The Software supply chain security path covers OIDC, signing, SBOMs, and provenance from commit to cluster.
Go deeper in a courseSoftware supply chain securityOIDC federation, secret hygiene, signing, and provenance across the pipeline.View course