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

Created 18 Oct 2026 · Modified 23 Oct 2026 · 4 versions

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:

  1. 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.
  2. For a cross-account call, the caller's own identity policy allows sts:AssumeRole on 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

ParameterContractFails when
RoleArnrequiredthe role does not exist, or the trust policy does not allow the caller
RoleSessionNamerequired, 2–64 chars, letters, digits and +=,.@-outside that length or character set
DurationSeconds900–43200, default 3600above 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)
ExternalId2–1224 chars, letters, digits and +=,.@:/-missing or wrong when the trust policy requires sts:ExternalId
SerialNumber + TokenCodeTokenCode is six digitsmissing or expired when the trust policy requires MFA — the call returns access denied
Policyone inline JSON session policyinvalid JSON or grammar (MalformedPolicyDocument)
PolicyArnsup to 10 managed policy ARNs in the role's accounttogether with Policy, the plaintext exceeds 2,048 characters
Tagsup to 50; key ≤ 128 chars, value ≤ 256a key repeats an inherited transitive tag; or the packed token is too large (PackedPolicyTooLarge)
SourceIdentity2–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 RoleSessionName appears 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, GetAccessKeyInfo and DecodeAuthorizationMessage. 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 before Expiration rather 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.

Read this document as markdown — the same bytes an agent receives.