Interactive tool
Why can’t my GitHub Actions job assume this AWS role?
Describe the job and paste the role’s trust policy. See the sub claim GitHub sends, and which condition AWS rejects it on, when all AWS says is “Not authorized to perform sts:AssumeRoleWithWebIdentity”.
Runs in your browser · nothing is sent anywhere
The job
configure-aws-credentials sends sts.amazonaws.com unless you set its audience.
The sub claim GitHub sends
repo:octo-org/octo-repo:ref:refs/heads/main
This job can assume the role
Statement 1 · Allow · matches
- pass
StringEquals token.actions.githubusercontent.com:audMatches. - pass
StringEquals token.actions.githubusercontent.com:subMatches.
The link holds the job details and the whole policy, including the account ID in it. Remove passwords and tokens before you send it.
Related troubleshooting
What OIDC does here
OpenID Connect (OIDC) lets a GitHub Actions job get short-lived AWS credentials without storing any keys. GitHub gives the job a signed token that says which repository, branch or environment it runs for. AWS checks that token against the trust policy of the role the job asks for, and hands out credentials only if every condition matches.
When one does not, AWS says only “Not authorized to perform sts:AssumeRoleWithWebIdentity”. This tool shows which condition failed.
Using it
Describe the job: its repository, and whether a branch, a tag, a pull request or an environment runs it. Paste the role’s trust policy from the IAM console’s Trust relationships tab, or from aws iam get-role. Each condition is shown as passing, failing or not checked, with the value GitHub actually sends.
If the repository was created, renamed or transferred on github.com after 15 July 2026, tick the immutable format and add its numeric IDs. That change is the most common reason a deploy that used to work suddenly stops.
What this checks
- Builds the sub claim GitHub sends for your job (branch, tag, pull request or environment, in the name-only or immutable form) and evaluates your role's trust policy the way IAM documents StringEquals, StringLike and their IgnoreCase and negated forms.
What it cannot know
- Call AWS or GitHub, so it cannot see the OIDC provider in your account, its thumbprints or audiences, or session policies and SCPs that can also deny.
- Evaluate conditions on claims it does not build, such as job_workflow_ref or repository custom properties. It marks them as not checked rather than passed.
Check it for real
aws iam get-role --role-name <role> --query Role.AssumeRolePolicyDocument
Prints the trust policy AWS actually holds, to paste here instead of a copy that may be out of date. The real test is the workflow run: configure-aws-credentials succeeds or fails with the same error. AWS IAM — Configuring a role for GitHub OIDC identity provider
How the claim and the match work
The sub claim. GitHub builds it from the repository and what triggered the job: repo:ORG/REPO:ref:refs/heads/BRANCH, or :ref:refs/tags/TAG, or :pull_request for a pull request, or :environment:NAME when the job uses an environment, which takes precedence. A colon inside a name becomes %3A. The immutable form adds the numeric IDs after each name: repo:ORG@ORG_ID/REPO@REPO_ID:….
The match. In IAM, StringEquals is exact and case-sensitive. StringLike is also case-sensitive, with * matching any run of characters and ? exactly one. Several values for one key mean any of them, and every condition in a statement must hold.
What IAM refuses. For GitHub’s provider, IAM rejects a trust policy with no condition on token.actions.githubusercontent.com:sub, or one that is only a wildcard. Without it, workflows in repositories outside your control could assume the role.
Questions people ask about this
Why does Not authorized to perform sts:AssumeRoleWithWebIdentity give no details?
AWS returns the same message whichever condition failed: the audience, the sub claim, the principal or the action. Comparing the claims GitHub sends against each condition in the trust policy is the way to find which one, and that is what this checker does.
My deploy stopped working after renaming the repository. Why?
Since 15 July 2026, GitHub sends the immutable subject claim, with numeric owner and repository IDs, for repositories renamed or transferred after that date, as well as for new ones. A trust policy that matches the old name-only form no longer matches. Add the immutable form, for example repo:ORG@ORG_ID/REPO@REPO_ID:*, and drop the name-only entry once nothing uses it.
What audience should the trust policy check?
sts.amazonaws.com, if you use aws-actions/configure-aws-credentials: that is the audience it requests unless you set its audience input.
Did this get you to an answer?
No text box on purpose — please do not paste production logs anywhere
Something wrong or out of date? Report it
Tools that go with this
- YAML and JSON ValidatorWhere the file breaks, in a sentence rather than "unexpected token" — with the line, the column, and conversion between the two formats.
- Container Exit Code ExplainerWhat 137, 143 and 139 mean, and the rule behind them.
- systemd Service Unit GeneratorA service unit with its own user, restarts and sandboxing, and the commands to check it.