What is AssumeRole in AWS?
AssumeRole is the STS API that lets a principal take on an IAM role's permissions temporarily. Learn how it works and how to secure it.
What is AssumeRole in AWS?
Definition
AssumeRole is the AWS Security Token Service (STS) API that allows an allowed principal to take on the permissions of an IAM role temporarily, receiving short-lived credentials in return.
It's the foundation of cross-account access, federation, CI/CD, service identity, and JIT privilege patterns in AWS.
In simple terms:
AssumeRole = put on a different identity for an hour, with that identity's permissions.
Why AssumeRole Matters
- Eliminates long-lived credentials for most use cases.
- Enables clean cross-account models.
- Powers federation from external IdPs.
- Provides scoped, time-limited access.
- Generates clear audit trail in CloudTrail.
How AssumeRole Works
Trust Policy (on the role)
Defines who can assume the role:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::111111111111:role/SourceRole" },
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": { "sts:ExternalId": "shared-secret-id" }
}
}]
}
Permission Policy (on the source)
The source principal must have sts:AssumeRole permission to call the API.
API Call
aws sts assume-role \
--role-arn arn:aws:iam::222222222222:role/TargetRole \
--role-session-name dev-session \
--duration-seconds 3600 \
--external-id shared-secret-id
Returned Credentials
- AccessKeyId, SecretAccessKey, SessionToken
- Expiration time
- AssumedRole ARN
The caller now uses these credentials to act as the role.
AssumeRole Variants
sts:AssumeRole— base API for IAM principal assumption.sts:AssumeRoleWithSAML— assume via SAML assertion (federation).sts:AssumeRoleWithWebIdentity— assume via OIDC token (GitHub Actions, Kubernetes IRSA, Cognito).
Common Use Cases
Cross-Account Access
A read-only auditor in account A assumes AuditorRole in account B. Audit work runs as that role; CloudTrail in B logs the activity.
Switch-Role in Console
User in their main AWS account uses console "Switch Role" to operate in a different account without separate sign-in.
CI/CD via OIDC
GitHub Actions presents OIDC token; AWS issues role credentials per workflow run. No stored secrets.
IAM Identity Center
Users SSO; Identity Center assumes Permission Set–backed roles in target accounts.
Service Roles
EC2/Lambda/ECS/EKS assume their service role automatically via AWS-internal flows.
Important Settings
External ID (Third-Party Trust)
A shared secret in the trust policy condition. Required by AWS guidance for vendor cross-account roles to prevent Confused Deputy attacks.
Session Duration
- Default 1 hour.
- Up to 12 hours per role configuration.
- Chained role assumption capped at 1 hour.
Session Tags
Pass tags during assumption for ABAC (Attribute-Based Access Control).
Source Identity
Optional identifier preserved across role chains for audit (sts:SourceIdentity).
MFA
Trust can require MFA: Condition: { Bool: { "aws:MultiFactorAuthPresent": "true" } }.
Common Risks
- Trust policies allowing
Principal: "*"or broad accounts. - No external ID for third-party trust → Confused Deputy.
- No
aws:SourceArn/aws:SourceAccounton service trust. - Excessive session duration widening compromise window.
- OIDC trust with wildcard subject allowing wrong GitHub repos.
- Long role chain that obscures original caller.
- Session credentials persisting in dev environments.
- Role with
AdministratorAccesstrusted broadly.
Real-World Examples
1. GitHub Actions OIDC Done Right
Trust policy:
"Condition": {
"StringLike": {
"token.actions.githubusercontent.com:sub":
"repo:myorg/myrepo:environment:production"
}
}
Only the production environment of myorg/myrepo can assume the role.
2. Vendor Cross-Account With External ID
Trust policy requires external ID known only to your tenant. Without it, vendor's other customers can't assume your role even via the vendor.
3. Lambda Execution Role
Trust policy: Principal: { "Service": "lambda.amazonaws.com" }. Lambda assumes during invocation.
4. Privilege Escalation Path
User has iam:PassRole on AdminRole and lambda:CreateFunction. Creates Lambda with AdminRole; the function can do anything. AssumeRole misuse via PassRole is a textbook escalation.
AssumeRole Best Practices
- Trust policies as narrow as possible — exact ARNs, conditions.
- External ID for any third-party trust.
aws:SourceArn/aws:SourceAccountfor service trust.- MFA conditions on sensitive roles.
- Short session durations by default.
- OIDC trust strictly scoped by repo/branch/environment.
- Avoid trust to root unless intentional.
iam:PassRolepermissions tightly scoped to specific roles.- Source identity required for human assumed-roles where audit matters.
- CloudTrail detection on unusual
AssumeRole: new principals, new IPs, new role/account combinations. - Role tagging with owner / purpose.
- Periodic review of trust relationships.
Checklist
- Trust policies use exact principals + conditions?
- External IDs for third-party trust?
- SourceArn / SourceAccount on service trust?
- OIDC trust scoped tightly?
- MFA on sensitive role assumption?
- Session durations minimized?
iam:PassRolepermissions narrow?- CloudTrail monitoring on AssumeRole anomalies?
- Trust relationships reviewed quarterly?
How Forestall Helps
Forestall maps every AssumeRole relationship across your accounts:
- Trust graph including chains.
- OIDC federation paths.
- External ID and condition coverage.
- Risky trust policies highlighted.
iam:PassRoleescalation patterns.- Session-duration outliers.
Frequently Asked Questions
Can a role assume itself?
Yes if its own trust policy allows; rarely useful.
Can roles be chained?
Yes; chained sessions capped at 1 hour.
Does AssumeRole require IAM permissions?
Yes — the source principal needs sts:AssumeRole on the target role ARN.
How is AssumeRole logged?
CloudTrail logs each AssumeRole call with source identity, role, session name, and conditions.
What's the difference between AssumeRole and Switch Role?
Switch Role is the console UX; under the hood it calls AssumeRole.
Conclusion
AssumeRole is the API that powers nearly every modern AWS access pattern. Used carefully — with narrow trust policies, external IDs, conditions, OIDC scoping, and short sessions — it eliminates long-lived credentials and provides a clean, auditable access model. Used carelessly, it becomes a hidden cross-account exposure or privilege-escalation channel. Audit your trust policies and AssumeRole usage continuously, and AssumeRole becomes one of AWS's strongest security primitives.
Map every AssumeRole path across your AWS estate.
Forestall analyzes role assumption chains and surfaces unsafe trust relationships.