For the complete documentation index, see llms.txt. This page is also available as Markdown.

AWS_ASSUME_ROLE

Summary

Forestall ACL Alias

AWS_ASSUME_ROLE

Edge Type

Attack Path

Affected Object Types

IAM Users, IAM Roles, AWS Services

Exploitation Certainty

Certain

AWS IAM Action / Condition

sts:AssumeRole on the target role

Description

AWS_ASSUME_ROLE records that a principal can call sts:AssumeRole against a target IAM role and receive temporary credentials scoped to that role's permissions.

The caller gets back AccessKeyId, SecretAccessKey, and SessionToken, valid for up to 12 hours. Those credentials carry the full permission set of the assumed role, which may far exceed what the caller normally has.

Two things must both be true for this path to work:

  1. The source identity has sts:AssumeRole allowed in its own policies.

  2. The target role's trust policy lists the source identity as a permitted principal.

Cross-account assumption is standard practice in multi-account AWS architectures. The target role in Account B lists an Account A principal in its trust policy. An attacker who controls that Account A identity can pivot to Account B without any credentials native to it.

Common condition keys for restricting this path are aws:MultiFactorAuthPresent, sts:ExternalId, aws:SourceIp, and aws:PrincipalOrgID. Missing or misconfigured conditions are where most over-permissive chains come from.

Identification

AWS CLI

Pull the trust policy to see who can assume the role:

Simulate whether a specific identity can assume the role:

Find all roles whose trust policies list a specific principal:

AWS Console

  1. Open IAM → Roles → select the target role.

  2. Open the Trust relationships tab.

  3. Review the trust policy JSON. Principal defines who can call AssumeRole, and Condition blocks restrict when it is allowed.

  4. To check if a source identity has the permission to call sts:AssumeRole, open that user or role and use Policy Simulator under Actions.

Exploitation

Assume the target role:

Export the returned credentials:

Verify the assumed identity:

Cross-account trust policies often require an ExternalId. If you have or can guess the value, pass it:

Mitigation

  • Trust policies should name specific principals. Remove anything that isn't actively used.

  • Use aws:PrincipalOrgID to keep cross-account assumptions inside your organization.

  • Add aws:MultiFactorAuthPresent: 'true' as a condition on sensitive roles.

  • Treat sts:ExternalId as a shared secret for third-party access. Don't expose it in docs or error messages.

  • Never use "Principal": "*" in a trust policy. Any authenticated AWS principal can attempt the assumption.

  • Set MaxSessionDuration to the shortest viable session length.

Detection

Watch CloudTrail for AssumeRole activity:

  • Event source: sts.amazonaws.com

  • Event name: AssumeRole

Signals worth investigating:

  • Cross-account assumptions from an account you don't recognize.

  • Session names that break your naming convention. Automated tools produce consistent patterns; attackers often don't.

  • Repeated AccessDenied on AssumeRole calls, a sign of trust policy enumeration.

  • Admin, deploy, or break-glass role assumptions outside business hours.

References

Last updated

Was this helpful?