The problem:
GitHub Actions workflow was failing with Could not assume role with ARN arn:aws:iam::123456789:role/my-role. Error: Not authorized to perform sts:AssumeRoleWithWebIdentity.
Everything looked correct — OIDC provider was registered, IAM role existed. But it kept failing.
The fix:
# The trust policy had the wrong subject format
# WRONG:
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:my-org/my-repo"
}
# CORRECT (must include ref):
"StringEquals": {
"token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:ref:refs/heads/main"
}
# Or use StringLike to allow any branch/tag:
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:my-org/my-repo:*"
}# workflow fix — permissions block is mandatory:
permissions:
id-token: write # THIS IS REQUIRED — missing this = silent failure
contents: readWhy it happens:
Two issues can cause this independently. First: the IAM trust policy sub condition must exactly match the OIDC token subject, which includes the branch ref. Second: the workflow permissions.id-token: write must be explicitly set — without it, GitHub doesn't issue the OIDC token at all, but the error message still says "assume role failed."