GitHub Actions OIDC to AWS: fix AssumeRoleWithWebIdentity AccessDenied
Diagnose AWS AssumeRoleWithWebIdentity AccessDenied in GitHub Actions by checking token permissions, audience, role ARN, and IAM trust-policy subject claims.
Published
Problem
A GitHub Actions workflow using AWS OIDC fails with Not authorized to perform sts:AssumeRoleWithWebIdentity or AccessDenied. The failure usually occurs before AWS permission policies are evaluated: AWS does not trust the identity represented by the workflow token.
Quick answer
Check four boundaries in order:
- The job can request an ID token.
- The workflow uses the intended AWS role ARN and Region.
- The AWS OIDC provider has the correct issuer and audience.
- The role trust policy matches the token’s
subclaim for the repository, branch, tag, pull request, or environment.
The workflow needs:
yaml
permissions:
contents: read
id-token: write
steps:
- uses: aws-actions/configure-aws-credentials@<pinned-version>
with:
role-to-assume: arn:aws:iam::<account-id>:role/<role-name>
aws-region: ap-southeast-1Pin third-party actions according to your supply-chain policy, preferably to a reviewed commit SHA.
Check the trust policy
For GitHub’s official AWS credentials flow, the provider URL is https://token.actions.githubusercontent.com and the audience is sts.amazonaws.com. Restrict the subject instead of trusting every repository:
json
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account-id>: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:owner/repository:ref:refs/heads/main"
}
}
}Repository and branch names are case-sensitive in the resulting claim. A workflow using a GitHub Environment produces a different subject form, such as repo:owner/repository:environment:production. Match the actual workflow context and keep the condition as narrow as operationally possible.
Separate trust from role permissions
If configure-aws-credentials cannot obtain credentials, debug the OIDC provider and trust policy. If credentials are issued but a later aws command is denied, debug the role’s identity policy, permission boundary, session policy, or organization SCP instead.
Verify the assumed identity immediately after authentication:
bash
aws sts get-caller-identityThis prevents a later deployment failure from being incorrectly attributed to OIDC.
Common mismatches
id-token: writeis missing or overridden by job-level permissions.- The role exists in a different AWS account than the ARN used by the workflow.
- The audience does not match
sts.amazonaws.com. - The trust policy allows
main, but the workflow runs from a tag, pull request, or environment. - The reusable workflow’s repository context differs from the caller assumptions.
- The IAM provider or role was recently changed but the workflow still references an old ARN.
Do not solve this by changing the subject condition to a global wildcard. Broader trust converts a deployment error into a cross-repository privilege risk.
For local identity confusion, use AWS SSO login and profile verification. For pipeline design, see the Infrastructure as Code platform blueprint.