Git, CI/CD & GitOpsXLIII · OIDC and Short-Lived CredentialsAWS
OIDC in AWS — provider, audience, role, trust policy; aws-actions/configure-aws-credentials
What you'll learn
- Register the GitHub Actions OIDC provider in AWS IAM
- Configure an IAM role with a trust policy that gates repo, branch, and workflow path
- Use aws-actions/configure-aws-credentials@v4 to exchange the OIDC token for a short-lived STS session
- Configure the role session duration and the audience to match the trust policy
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
OIDC federation in AWS has four pieces that must agree: the OIDC
provider (the GitHub Actions issuer URL and JWKS endpoint), the
audience (sts.amazonaws.com), the IAM role (the permission grant),
and the trust policy (the subject and audience match). When all four
agree, the aws-actions/configure-aws-credentials@v4 action fetches
the OIDC token from GitHub and calls sts:AssumeRoleWithWebIdentity;
AWS validates the claims and issues a short-lived STS session.
The four pieces
flowchart LR
P["1. OIDC provider\ntoken.actions.githubusercontent.com"] --> C["AWS IAM\ntrusts the provider"]
A["2. Audience\nsts.amazonaws.com"] --> C
R["3. IAM role\ngrants permissions"] --> T["4. Trust policy\ngates repo + branch + workflow"]
T --> C
C --> S["STS session\n(~1 hour)"]
- OIDC provider. An IAM identity provider entry that registers
GitHub Actions as a trusted issuer. The provider URL is
https://token.actions.githubusercontent.com; the audience issts.amazonaws.com. AWS fetches the JWKS endpoint and validates the token’s signature against the published keys. - Audience. The
audclaim in the OIDC token. AWS expectssts.amazonaws.com; the trust policy matches the audience; a different audience is rejected. - IAM role. The role that the workflow assumes. The role’s permission policy grants the AWS permissions the workflow needs.
- Trust policy. The role’s trust policy gates which forge,
repository, branch, and workflow may assume the role. The trust
policy matches the
subandaudclaims in the OIDC token.
The four pieces are registered and configured once per AWS account. The workflow declares the role ARN; AWS validates the token against the trust policy; AWS issues the STS session.
Registering the OIDC provider
The OIDC provider is registered in IAM once per AWS account:
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1
The --url is the GitHub Actions OIDC issuer. The --client-id-list
is the audience the provider may issue tokens for (AWS uses
sts.amazonaws.com). The --thumbprint-list is the SHA-1 thumbprint
of the TLS certificate GitHub uses for the OIDC endpoint.
After registration, the provider ARN is available at
arn:aws:iam::$AWS_ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com.
The trust policy references the provider ARN.
The trust policy
The IAM role’s trust policy declares which workflows may assume the role. A minimal trust policy for a single repository and branch:
{
"Version": "2012-10-17",
"Statement": [
{
"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",
"token.actions.githubusercontent.com:sub": "repo:acme/infra:ref:refs/heads/main"
}
}
}
]
}
The Condition block matches the aud claim to sts.amazonaws.com
and the sub claim to repo:acme/infra:ref:refs/heads/main. A
workflow on a different repository or branch cannot assume the role;
the trust policy denies.
For finer-grained gating, the trust policy can match the
job_workflow_ref claim:
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:acme/infra:ref:refs/heads/main",
"token.actions.githubusercontent.com:job_workflow_ref": "acme/infra/.github/workflows/deploy.yml@refs/heads/main"
}
}
The job_workflow_ref claim matches the workflow file path; only the
specific deploy workflow can assume the role.
The workflow
The workflow uses aws-actions/configure-aws-credentials@v4 to fetch
the OIDC token and exchange it for an STS session:
name: Deploy
on:
push:
branches: [main]
permissions:
id-token: write
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials via OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::"$AWS_ACCOUNT_ID":role/github-actions-deploy
aws-region: us-east-1
- name: Deploy
run: aws s3 sync ./build s3://"$BUCKET_NAME"
The action calls GitHub’s OIDC endpoint to fetch a JWT, calls
sts:AssumeRoleWithWebIdentity to exchange the JWT for an STS
session, and configures the AWS CLI to use the session credentials.
The session is valid for the role’s MaxSessionDuration (default 1
hour, maximum 12 hours).
Configuring the session
The aws-actions/configure-aws-credentials@v4 action supports
several options for the session:
role-to-assume— the ARN of the IAM role to assume (required)aws-region— the AWS region for the session (required)role-session-name— a name for the session (defaults toGitHubActions_${GITHUB_RUN_ID})session-duration— the session duration in seconds (default 1 hour, maximum 12 hours — must not exceed the role’sMaxSessionDuration)role-skip-session-tagging— skip tagging the session with GitHub-specific attributes
The session duration is bounded by the role’s MaxSessionDuration.
A role with a 1-hour MaxSessionDuration rejects session requests
for longer durations; the action fails with an
AccessDenied error.
Multiple roles
A workflow can assume different roles for different jobs by declaring
separate aws-actions/configure-aws-credentials@v4 steps. Each step
fetches a new OIDC token and assumes the role for the duration of
the job.
For cross-account access — a workflow in account A that needs to
assume a role in account B — the trust policy in account B grants
access to the role in account A; the workflow assumes the role in
account B by setting role-to-assume to the account B role ARN.
- name: Configure AWS credentials in account B
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::"$ACCOUNT_B_ID":role/github-actions-deploy
aws-region: us-east-1
Production discipline
- The OIDC provider is registered once per AWS account. The
provider URL is
https://token.actions.githubusercontent.com; the client ID list issts.amazonaws.com. - Trust policies use
StringEqualswith specific values. No wildcards in thesubclaim; noStringLikefor production roles. - Session duration matches the job duration. A 30-minute job should not request a 12-hour session; the longer the session, the larger the replay window if the credentials leak.
- Trust policies are reviewed when workflow files change. A new workflow file may require a new subject pattern; the policy update is part of the pull request.
Cross-course references
- Git, CI/CD & GitOps — Part XLIII-02 (OIDC federation basics) covers the trust relationship and the JWT claim anatomy.
- Git, CI/CD & GitOps — Part XLIII-03 (GitHub Actions OIDC in
practice) covers the
id-token: writepermission and the OIDC token API. - Git, CI/CD & GitOps — Part XLIII-06 (OIDC trust policy deep
dive) covers the
subandjob_workflow_refclaims in detail. - AWS for Production Sysadmins — Part XXXI (IAM) covers IAM roles, trust policies, and permission boundaries.
Quiz
Knowledge check · 4 questions
Q1. Which AWS IAM API does `aws-actions/configure-aws-credentials@v4` call to exchange an OIDC token for a short-lived session?
Q2. A trust policy using `StringLike` with a wildcard pattern in the `sub` claim is the OIDC equivalent of a static access key with no scope.
Q3. Name the four pieces that must agree for OIDC federation in AWS, and state the value each one takes for GitHub Actions.
Q4. Diagnose the OIDC authentication failure and prescribe the fix.
Team T configures OIDC federation between GitHub Actions and AWS. The OIDC provider is registered. The IAM role has a permission policy granting AdministratorAccess on the production account. The trust policy's `Condition` block has `token.actions.githubusercontent.com:aud: sts.amazonaws.com` and `token.actions.githubusercontent.com:sub: repo:acme/infra:ref:refs/heads/main`. The workflow declares `id-token: write` and calls `aws-actions/configure-aws-credentials@v4` with `role-to-assume`. The action fails with: `Error: Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentity`.
Passing score: 75%. Answers are checked in this browser.