sts:AssumeRole failure — cross-account or service role switch denied
App or pipeline fails with 'not authorized to perform sts:AssumeRole'
Focused incident mode — strips away everything but this runbook.
Symptoms
- App or pipeline fails with 'not authorized to perform sts:AssumeRole'
- Cross-account deploys suddenly stop working
- aws sts assume-role in tests returns AccessDenied
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Reproduce the assume call
aws sts assume-role --role-arn arn:aws:iam::<ACCOUNT>:role/<ROLE-NAME> --role-session-name diagTrust policy of the target role
aws iam get-role --role-name <ROLE-NAME> --query 'Role.AssumeRolePolicyDocument'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- get-role shows no matching Principal for the caller
- Trust policy conditions (aws:PrincipalArn/OrgAccount) exclude the caller
Confirm before fixing
aws iam get-role --role-name <ROLE-NAME> --query 'Role.AssumeRolePolicyDocument.Statement[].Principal'List trusted principals
Fix
aws iam update-assume-role-policy --role-name <ROLE-NAME> --policy-document file://trust-policy.jsonAdd the caller (or its account/OU) to the trusted principals
Expected: AssumeRolePolicy updated
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
aws sts get-caller-identityConfirm the caller
aws iam get-role --role-name <ROLE-NAME> --query 'Role.AssumeRolePolicyDocument'Sanity-check the trust policy
aws iam update-assume-role-policy --role-name <ROLE-NAME> --policy-document file://trust-policy.jsonFix the trust policy when wrong
aws sts assume-role --role-arn arn:aws:iam::<ACCOUNT>:role/<ROLE-NAME> --role-session-name verifyVerify the fix
Expected: Credentials (no error)
Prevention
- Centralize trust policies on a perimeter account with explicit aws:PrincipalArn/aws:SourceArn conditions.
- Version role ARNs in one config and lint pipelines against it.
- Add sts:AssumeRole tests to your CI in every account boundary you rely on.
Related runbooks
Same stack, same failure family — worth a skim.
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.