AssumeRole: the exact request, what it changes and what it costs
The request shape for sts:AssumeRole in CLI, TypeScript SDK v3 and raw API form, the parameter limits that make it fail, and what the call leaves behind.
markdownreferencev4H09T-EQXWstage: operatetrust: officialservice: stsinterface: cliinterface: sdkAssumeRolests assume-roleDurationSecondsRoleSessionNameExternalIdsession policysession tagsrole chaining
AssumeRole
What it does: exchanges the caller's credentials for temporary credentials (access key ID, secret access key, session token) that act as the target role. The new session has the role's permissions, narrowed by any session policies you pass. It works within one account and across accounts.
Before you call it, two things must be true:
- The role's trust policy names the caller (or the caller's account) as a principal allowed
sts:AssumeRole, and any trust-policy conditions (MFA, external ID, source identity) are met. - For a cross-account call, the caller's own identity policy allows
sts:AssumeRoleon the role ARN. Within one account, the trust policy alone is enough when it names the caller directly.
The request
CLI
aws sts assume-role \
--role-arn arn:aws:iam::<account-id>:role/<role-name> \
--role-session-name <session-name> \
--duration-seconds 3600
Optional: --external-id <id>, --serial-number <mfa-device-arn> --token-code <6 digits>, --policy file://session-policy.json, --policy-arns arn=<policy-arn>, --tags Key=<k>,Value=<v>, --transitive-tag-keys <k>, --source-identity <id>.
TypeScript, AWS SDK for JavaScript v3
import { STSClient, AssumeRoleCommand } from "@aws-sdk/client-sts";
const sts = new STSClient({ region: "<region>" });
const { Credentials, AssumedRoleUser } = await sts.send(
new AssumeRoleCommand({
RoleArn: "arn:aws:iam::<account-id>:role/<role-name>",
RoleSessionName: "<session-name>",
DurationSeconds: 3600,
// ExternalId: "<id>",
// SerialNumber: "<mfa-device-arn>", TokenCode: "<6 digits>",
// Policy: JSON.stringify(sessionPolicy),
// PolicyArns: [{ arn: "<policy-arn>" }],
// Tags: [{ Key: "<k>", Value: "<v>" }],
// SourceIdentity: "<id>",
}),
);
// Credentials: { AccessKeyId, SecretAccessKey, SessionToken, Expiration }
To use the role from code without handling credentials yourself, configure a profile with role_arn and source_profile and let the SDK's provider chain assume it and refresh it; see reference/sts/credential-sources.md.
Raw API (query protocol)
POST https://sts.<region>.amazonaws.com/
Action=AssumeRole&Version=2011-06-15
&RoleArn=arn:aws:iam::<account-id>:role/<role-name>
&RoleSessionName=<session-name>
&DurationSeconds=3600
The request must be signed like any AWS API request; hand-signing is a known source of denials. Prefer the SDK.
Parameters that make it fail
| Parameter | Contract | Fails when |
|---|---|---|
RoleArn | required | the role does not exist, or the trust policy does not allow the caller |
RoleSessionName | required, 2–64 chars, letters, digits and +=,.@- | outside that length or character set |
DurationSeconds | 900–43200, default 3600 | above the role's maximum session duration (1–12 hours, set on the role), or above 3600 when role chaining (assuming a role with credentials from another role) |
ExternalId | 2–1224 chars, letters, digits and +=,.@:/- | missing or wrong when the trust policy requires sts:ExternalId |
SerialNumber + TokenCode | TokenCode is six digits | missing or expired when the trust policy requires MFA — the call returns access denied |
Policy | one inline JSON session policy | invalid JSON or grammar (MalformedPolicyDocument) |
PolicyArns | up to 10 managed policy ARNs in the role's account | together with Policy, the plaintext exceeds 2,048 characters |
Tags | up to 50; key ≤ 128 chars, value ≤ 256 | a key repeats an inherited transitive tag; or the packed token is too large (PackedPolicyTooLarge) |
SourceIdentity | 2–64 chars, cannot start with aws: | the trust policy requires sts:SourceIdentity and it is missing |
Error codes and their fixes: reference/sts/errors.md. A trust-policy refusal reads … is not authorized to perform: sts:AssumeRole … because no role trust policy allows …: see reference/iam/errors.md.
What it changes
- Creates no resource and changes no policy. It issues credentials that stay valid until
Expiration; there is no AssumeRole parameter to end them early (revoking sessions from the role side is not covered here). - Is visible to the role's owner. The
RoleSessionNameappears in the assumed-role ARN (arn:aws:sts::<account-id>:assumed-role/<role-name>/<session-name>) and in the role owner's CloudTrail logs for every call made with the session. Do not put secrets or personal data in it. - Session permissions are fixed at issuance to the intersection of the role's identity-based policies and the session policies you passed. Session tags override role tags with the same key (keys are case-insensitive).
What it costs
- Request quota. AssumeRole shares a per-account, per-Region requests-per-second quota with
GetCallerIdentity,GetSessionToken,GetFederationToken,GetAccessKeyInfoandDecodeAuthorizationMessage. Only the calling account's quota is consumed, not the role's account. Calls made by AWS service principals do not count. The value is on the IAM and STS quotas page; raising it takes a support ticket, not Service Quotas. Cache credentials until shortly beforeExpirationrather than calling per request. - Money. No charge for this call was found in the collected sources (UNVERIFIED); check AWS pricing before assuming none.
Endpoint choice
Use a Regional endpoint (sts.<region>.amazonaws.com) where you can; AWS recommends it. Since April 2025 the global endpoint sts.amazonaws.com is served in the caller's Region for Regions enabled by default, but requests from opt-in Regions still go to US East (N. Virginia). If STS is not active in the Region you call, the error is RegionDisabled.