STS Session Limits and Role Chaining Restrictions in AWS IAM
Role chaining in AWS STS limits sessions to 1 hour regardless of role settings, while direct AssumeRole calls support up to 12 hours when configured.
Understanding AWS Security Token Service (STS) session limits and role chaining restrictions is critical for designing secure, long-running cloud architectures. The aws/agent-toolkit-for-aws repository provides detailed guidance on these constraints in skills/core-skills/aws-iam/SKILL.md, clarifying how temporary credentials behave across different API calls and trust relationships.
Understanding STS Session Duration Limits
AWS STS issues temporary security credentials that expire automatically, with maximum durations varying by API operation. The service enforces strict upper bounds to minimize the blast radius of compromised credentials.
AssumeRole and AssumeRoleWithWebIdentity
Both AssumeRole and AssumeRoleWithWebIdentity support a maximum session duration of 12 hours. According to skills/core-skills/aws-iam/SKILL.md, the default duration is 1 hour, but you can raise this to 12 hours by configuring the MaximumSessionDuration attribute on the target IAM role itself.
When you call AssumeRole, the DurationSeconds parameter cannot exceed the role's configured maximum. If you request 12 hours (43200 seconds) but the role's MaximumSessionDuration is set lower, AWS caps the session at the role's limit.
GetSessionToken
The GetSessionToken API also supports up to 12 hours, but with a critical constraint: MFA is required. As documented in skills/core-skills/aws-iam/SKILL.md, this operation is restricted to MFA-protected sessions and cannot be used to call other IAM APIs unless the MFA token is attached to the request.
The Role Chaining Restriction Explained
When you assume a role using credentials that were themselves obtained through AssumeRole, you create a role chain. AWS enforces a hard limit on these chained sessions regardless of individual role configurations.
The 1-Hour Hard Limit
If role A assumes role B, and role B then assumes role C, the resulting session credentials are valid for only 1 hour, even if both roles permit 12-hour sessions. This restriction applies to any chain longer than a single hop. The skills/core-skills/aws-iam/SKILL.md file explicitly states this rule: "Role chaining: max 1-hour session."
Practical Consequences
This limitation has significant architectural implications:
- Long-running workflows must avoid chaining. Design each step to assume roles directly rather than building credential chains.
- Multi-service pipelines (e.g., SES → Firehose → S3) should use separate, purpose-specific roles directly assumed by each service, as recommended in
skills/core-skills/aws-iam/references/aws-iam-role-management.md. - ExpiredTokenException occurs if you attempt to use chained credentials after one hour, potentially causing production failures in automated processes.
Cross-Account and Regional Considerations
STS behavior varies across account boundaries and regions, requiring careful configuration of endpoints and trust policies.
Cross-Account Requirements
When performing cross-account AssumeRole operations, the target account must have the requested region enabled. The calling account's region settings do not influence this requirement. Always verify that the destination account supports the STS endpoint region before deploying cross-account architectures.
STS Region Priority
The AWS SDK selects STS endpoints in the following priority order, as detailed in the SDK credential references:
- Explicit
clientConfig.regionsetting - Region of the current AWS credentials
- Default global endpoint
Pin your STS region explicitly using --region in the CLI or clientConfig.region in SDK configuration to ensure consistent behavior across environments.
Practical Implementation Examples
The following examples demonstrate correct usage patterns and the role chaining limitation using the AWS CLI and boto3.
AWS CLI: AssumeRole with Custom Duration
Request a 12-hour session using the AWS CLI. This call respects the role's MaximumSessionDuration setting and will fail if you request more than the role allows.
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/MyCrossAccountRole \
--role-session-name my-session \
--duration-seconds 43200
Python: Demonstrating the Role Chaining Limit
This Python example shows how role chaining caps the second session at 1 hour regardless of the DurationSeconds request.
import boto3
sts = boto3.client('sts')
# First hop - Role A assumes Role B
resp_a = sts.assume_role(
RoleArn='arn:aws:iam::111122223333:role/RoleA',
RoleSessionName='first-hop',
DurationSeconds=43200
)
creds_a = resp_a['Credentials']
# Create client using Role B credentials
sts_b = boto3.client(
'sts',
aws_access_key_id=creds_a['AccessKeyId'],
aws_secret_access_key=creds_a['SecretAccessKey'],
aws_session_token=creds_a['SessionToken']
)
# Second hop - Role B assumes Role C (chained session)
resp_b = sts_b.assume_role(
RoleArn='arn:aws:iam::444455556666:role/RoleC',
RoleSessionName='second-hop',
DurationSeconds=43200
)
# Expiration will be 1 hour from now, not 12 hours
print("Chained session expiration:", resp_b['Credentials']['Expiration'])
Python: GetSessionToken with MFA
Use this pattern for privileged IAM users requiring MFA-protected sessions up to 12 hours.
import boto3
sts = boto3.client('sts')
resp = sts.get_session_token(
DurationSeconds=43200,
SerialNumber='arn:aws:iam::123456789012:mfa/user',
TokenCode='123456'
)
creds = resp['Credentials']
print(f"Session expires: {creds['Expiration']}")
Summary
- AssumeRole supports up to 12 hours via the
MaximumSessionDurationrole attribute, but defaults to 1 hour. - Role chaining imposes a hard 1-hour limit on all chained sessions regardless of role settings.
- GetSessionToken requires MFA and supports up to 12 hours for IAM user sessions.
- Cross-account operations require the target account to enable the requested region.
- Source files in
aws/agent-toolkit-for-awsdocument these behaviors inskills/core-skills/aws-iam/SKILL.mdand the IAM role management references.
Frequently Asked Questions
What is the maximum session duration for AWS STS AssumeRole?
The maximum session duration for AssumeRole is 12 hours, configurable per role through the MaximumSessionDuration attribute. However, the default is 1 hour, and any request exceeding the role's configured maximum is automatically capped to that value.
Why does role chaining limit sessions to 1 hour?
AWS enforces a 1-hour limit on role chaining as a security safeguard to prevent unbounded credential lifetimes across multiple trust hops. This prevents extremely long-lived sessions from propagating through multiple assumed roles, reducing the risk of credential compromise in complex delegation scenarios.
Can I use GetSessionToken without MFA?
No. Unlike AssumeRole, GetSessionToken requires MFA when called. The operation is specifically designed for MFA-protected IAM user sessions, and the resulting temporary credentials can only be used for IAM API calls when the MFA token is included in the request.
How do I avoid role chaining in multi-service architectures?
Design each service to assume its required role directly using its own identity rather than assuming a chain of roles. As recommended in skills/core-skills/aws-iam/references/aws-iam-role-management.md, create purpose-specific roles for each service link in your pipeline and configure trust policies to allow direct assumption by the preceding service's identity or execution role.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →