When GitHub Actions OIDC Breaks on a Brand-New Repo
I added a new repo to an IAM role that already trusted a dozen others, pushed, and the deploy died on the first step:
Error: Could not assume role with OIDC: Not authorized to perform sts:AssumeRoleWithWebIdentityThe trust policy listed the repo and branch, exactly like the entries that worked:
"token.actions.githubusercontent.com:sub": [ "repo:my-org/my-new-repo:ref:refs/heads/main"]A debug step printed the same subject back at me. That match was the trap: the step built the string from github.repository instead of reading the token, so it only confirmed my own assumption.
Ask AWS what it received
Failed calls land in CloudTrail:
aws cloudtrail lookup-events \ --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRoleWithWebIdentity \ --max-results 5 --query 'Events[].CloudTrailEvent' --output textThe userName field held the real subject:
repo:my-org@181155774/my-new-repo@1309212742:ref:refs/heads/mainNumeric IDs, glued onto the org and repo names. GitHub is rolling out immutable OIDC subjects, and new repositories get them by default, so renaming an org or repo can no longer be used to impersonate it. Check any repo with gh api /repos/my-org/my-new-repo/actions/oidc/customization/sub.
The fix
Match the subject AWS actually gets, and keep the old entry if the role is shared:
"token.actions.githubusercontent.com:sub": [ "repo:my-org/my-new-repo:ref:refs/heads/main", "repo:my-org@181155774/my-new-repo@1309212742:ref:refs/heads/main"]There’s no going back for the new repo. use_immutable_subject is opt-in for repos created before the change, and the IDs can’t be stripped once a repo has them. Want one convention everywhere? Move the old repos forward.
When OIDC works everywhere except the repo you created this morning, read CloudTrail first. It shows what AWS saw, which is the only version that counts.
