Reading30 min read·Module 1High exam weight

AWS Security Token Service (STS) & Temporary Credentials

Key concepts

  • AssumeRole for cross-account access

  • AssumeRoleWithSAML for federation

  • AssumeRoleWithWebIdentity for web apps

  • GetSessionToken for MFA-protected API calls

  • Temporary credentials expire automatically

The Credential That Destroys Itself

Tuesday, 9:00 a.m. Priya, the external auditor from lesson one, opens a terminal in her own AWS account and runs a single command against Trailbase. AWS hands her back three strings of text. She spends the next hour reading Trailbase's log buckets, and at 10:00 the three strings stop working everywhere, all at once. Nobody at Trailbase revoked anything. Nobody rotated a key or filed a ticket. The credential reached the end of its scheduled life and dissolved on its own.

Lesson one waved at this machinery and made a promise: temporary credentials "are issued by AWS STS, the Security Token Service, which you will meet properly in lesson 4." This is lesson 4, and the promise comes due. AWS Security Token Service (STS) is the web service that mints those self-destructing badges: temporary, limited-privilege credentials for IAM users or federated users (identities that live outside AWS, such as a corporate directory account, that AWS has been told to trust). They behave almost identically to long-term access keys, with one defining difference: they expire automatically after a duration you choose.

That one property repairs everything that made long-term keys dangerous back when Theo could delete a production bucket untraced. There is no permanent secret to distribute or embed, so nothing sits in a config file waiting to leak. A stolen temporary credential is worth minutes or hours instead of forever, which shrinks the blast radius of any compromise. And because STS will mint a badge for anyone a trust policy approves, it powers both cross-account access (Priya) and identity federation (users who never had an IAM identity at all).

Anatomy of a Temporary Credential

Every credential STS issues has three components, and all three must accompany every API call made with it:

  1. Access Key ID: identifies the credential
  2. Secret Access Key: used for signing requests
  3. Session Token: required for all API calls using temporary credentials

Long-term keys have only the first two. The session token is the piece people forget, and forgetting it is the classic failure you will meet again in the pitfalls below.

Exam Tip

STS questions are almost always which-API-fits-this-scenario: AssumeRole for cross-account access, AssumeRoleWithSAML for enterprise federation through Active Directory, AssumeRoleWithWebIdentity for mobile apps and social login, GetSessionToken for adding MFA to an existing IAM user. That mapping converts directly into correct answers.


The Life of One Badge

Follow Priya's 9:00 a.m. badge from birth to death and you have the entire STS model. Her command asks STS for credentials. STS checks the trust policy on the auditor role (the document from lesson one that answers who may assume this role) and, satisfied, returns the three strings. Every request Priya makes for the next hour carries all three, AWS validates them on each call, and at expiration they simply stop being honored.

STS Credential Flow
Figure 1: How temporary credentials are requested and used

Temporary Credentials Lifecycle

Request Phase:

  1. A user or application calls an STS API (for example, AssumeRole)
  2. STS validates the request against the trust policy
  3. STS returns temporary credentials

Usage Phase:

  1. The application uses the credentials for AWS API calls
  2. The credentials include the session token in every request
  3. AWS validates the credentials on each request

Expiration Phase:

  1. Credentials expire automatically, so no revocation step is needed
  2. The application must request new credentials before expiration
  3. Existing credentials cannot be extended; the only move is to request new ones

Notice what is missing from that lifecycle: a cleanup step. Every badge dies of natural causes, and how quickly depends on which API minted it and how the role is configured:

Credential Duration Limits

STS APIDefault DurationMinimumMaximum
AssumeRole1 hour15 minutes12 hours*
AssumeRoleWithSAML1 hour15 minutes12 hours*
AssumeRoleWithWebIdentity1 hour15 minutes12 hours*
GetSessionToken12 hours15 minutes36 hours
GetFederationToken12 hours15 minutes36 hours

*Maximum duration can be set per role (up to 12 hours)

Q

Which components make up a set of temporary security credentials issued by STS?

AAccess Key ID and Secret Access Key only
BAccess Key ID, Secret Access Key, and Session Token
CUsername and Password
DAccess Key ID and Session Token only

Five Ways to Ask for a Badge

STS exposes five APIs, and each one answers the same question in a different accent: who are you, and how did you prove it? Walk through who at Trailbase would trigger each and the exam scenarios sort themselves.

AssumeRole is the workhorse and the one Priya used at 9:00. It also covers work inside a single account: when Mara, the data engineer, needs elevated permissions for a risky schema migration, she assumes a privileged role for an hour instead of carrying those permissions all day.

AssumeRole

Purpose: Assume an IAM role within your account or cross-account

Use Cases:

  • Cross-account access to resources
  • Privilege escalation for specific tasks
  • Temporary elevated permissions

Requirements:

  • Caller must have sts:AssumeRole permission
  • Role must have a trust policy allowing the caller
  • Optional: MFA requirement in the trust policy

Returns: AccessKeyId, SecretAccessKey, SessionToken, Expiration

AssumeRoleWithSAML exists for companies with a corporate directory. A SAML assertion is a signed XML document from an identity provider (such as Active Directory Federation Services) vouching for who you are; this API exchanges that assertion for AWS credentials. If Trailbase grows to fifty people and Dana wires up a corporate directory, employees will sign in there and never hold IAM users at all.

AssumeRoleWithSAML

Purpose: Exchange a SAML assertion for temporary credentials

Use Cases:

  • Enterprise single sign-on (SSO)
  • Active Directory Federation Services (ADFS)
  • Corporate identity provider integration

Requirements:

  • Valid SAML 2.0 assertion from a trusted IdP
  • IAM SAML identity provider configured
  • Role trust policy allowing SAML federation

No IAM User Required: Federated users never need IAM accounts

AssumeRoleWithWebIdentity is how the Trailbase hiking app itself will work. Hikers sign in with Google or another OIDC provider (OpenID Connect, the web-native standard for proving identity with a signed token), and the app trades that token for AWS credentials scoped to that one hiker. In practice AWS recommends putting Amazon Cognito in front of this flow, because Cognito handles the token juggling for you.

AssumeRoleWithWebIdentity

Purpose: Exchange a web identity token for temporary credentials

Use Cases:

  • Mobile applications
  • Single-page web applications
  • Social login (Amazon, Facebook, Google)
  • OIDC-compatible identity providers

Recommended: Use Amazon Cognito instead for simplified integration

Requirements:

  • Token from a web identity provider
  • IAM OIDC identity provider configured
  • Role trust policy allowing the IdP

GetSessionToken is different in kind: no role changes hands. Mara already has an IAM user with long-term keys, and she calls GetSessionToken with her MFA code to trade them for temporary, MFA-blessed credentials for her CLI session. Same identity, safer badge.

GetSessionToken

Purpose: Get temporary credentials for an existing IAM user

Use Cases:

  • Add MFA protection to IAM user credentials
  • CLI/SDK usage requiring temporary credentials
  • When the user already has long-term credentials

Key Difference: Used by IAM users for their own identity rather than for role assumption

GetFederationToken is the one Trailbase will probably never call. It serves a custom identity broker: a server-side application you build yourself that authenticates users and then vends AWS credentials on their behalf. The caller decides what the federated user may do, always as a subset of its own permissions.

GetFederationToken

Purpose: Get credentials for a federated user (custom federation)

Use Cases:

  • Custom identity broker implementations
  • Proxy/broker services that manage federation
  • Server-side applications managing user access

Note: The caller determines the federated user permissions (a subset of the caller permissions)

Q

An enterprise wants employees to access AWS using their existing Active Directory credentials. Which STS API supports this?

AAssumeRole
BAssumeRoleWithWebIdentity
CAssumeRoleWithSAML
DGetFederationToken

Priya at 9:00, in Slow Motion

Now replay Priya's command frame by frame, because cross-account AssumeRole is the setup the exam tests most. Call Priya's account Account A, the source (111111111111) and Trailbase Account B, the target (222222222222). Access flows only when both sides agree, which takes three steps.

Cross-Account Access with STS
Figure 2: Using STS AssumeRole for cross-account access

Step 1: Trailbase creates the role and its trust policy. Dana creates CrossAccountRole in Account B with read permissions on the logs, plus a trust policy naming Priya's account. The root principal here delegates trust to Account A as a whole, and Account A then controls which of its identities may use that trust. The MFA condition adds a second lock: STS will refuse the assumption unless Priya authenticated with MFA.

JSONTrust Policy (Account B - Target)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::111111111111:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

Step 2: Priya's side grants permission to ask. Trusting the account is only half the handshake. In Account A, Priya's admin attaches a policy allowing her to call sts:AssumeRole on that specific role ARN.

JSONIAM Policy (Account A - Source)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::222222222222:role/CrossAccountRole"
    }
  ]
}

Step 3: Priya assumes the role. This is the 9:00 a.m. command. Note the response: the AccessKeyId begins with ASIA, the telltale prefix of temporary credentials (long-term keys begin with AKIA), and the session name she chose appears in the assumed-role ARN, which is exactly what CloudTrail will log.

SHAssuming a Role (CLI)
# Assume the role
aws sts assume-role \
  --role-arn arn:aws:iam::222222222222:role/CrossAccountRole \
  --role-session-name MySession \
  --duration-seconds 3600

# Response includes temporary credentials:
# {
#   "Credentials": {
#     "AccessKeyId": "ASIA...",
#     "SecretAccessKey": "...",
#     "SessionToken": "...",
#     "Expiration": "2024-01-15T13:00:00Z"
#   },
#   "AssumedRoleUser": {
#     "AssumedRoleId": "AROA...:MySession",
#     "Arn": "arn:aws:sts::222222222222:assumed-role/CrossAccountRole/MySession"
#   }
# }

# Use the credentials
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_TOKEN=...

# Now commands run as the assumed role
aws s3 ls s3://bucket-in-account-b/

Because the trust policy demands MFA, Priya actually passes her MFA device and current code with the call:

SHAssuming a Role with MFA
aws sts assume-role \
  --role-arn arn:aws:iam::222222222222:role/SensitiveRole \
  --role-session-name AdminSession \
  --serial-number arn:aws:iam::111111111111:mfa/username \
  --token-code 123456 \
  --duration-seconds 3600

The SAML flavor looks nearly identical from the CLI, except the proof of identity is the assertion document from the identity provider instead of IAM credentials:

SHAssumeRoleWithSAML
aws sts assume-role-with-saml \
  --role-arn arn:aws:iam::123456789012:role/SAMLRole \
  --principal-arn arn:aws:iam::123456789012:saml-provider/ExampleProvider \
  --saml-assertion file://saml-assertion.txt \
  --duration-seconds 3600
Q

Which STS API should be used for cross-account access between two AWS accounts?

AGetSessionToken
BGetFederationToken
CAssumeRole
DAssumeRoleWithWebIdentity

STS Where Nobody Types a Command

Priya asks for her badge explicitly. Most STS traffic at Trailbase happens silently, because the instance role from lesson one is STS underneath. The EC2 app servers that upload hiker photos to trailbase-photos have never held a permanent key; they fetch temporary credentials from the instance metadata service and the SDK refreshes them without any code at Trailbase noticing.

How EC2 Instance Roles Work
  1. The instance metadata service provides temporary credentials
  2. AWS SDKs automatically retrieve and refresh the credentials
  3. Credentials rotate automatically (typically every 6 hours)
  4. No credentials are stored on the instance

Endpoint: http://169.254.169.254/latest/meta-data/iam/security-credentials/role-name

The same silent pattern repeats across the stack. When Trailbase splits into separate dev and prod accounts, developers in the dev account will assume a read-only role to inspect production logs, exactly the Priya handshake with different names. The Jenkins pipeline deploys without long-term credentials by assuming a deployment role through OIDC federation or its own instance role, so every deployment runs on fresh, short-lived keys. And when the mobile app ships, hikers will authenticate with Amazon Cognito, which exchanges their identity token for temporary credentials scoped to that one user's data in S3.


The Confused Deputy at the Door

One more Trailbase scenario, because it hides the sneakiest trap in this lesson. Suppose Dana signs up for a third-party cost-monitoring SaaS that works by assuming a role in each customer's account. An attacker who also uses that SaaS could configure it with Trailbase's role ARN instead of their own. The SaaS, acting in good faith with its legitimate access, would then read Trailbase's data on the attacker's behalf. This is the confused deputy problem: a trusted intermediary tricked into misusing its authority.

The fix is an External ID, a shared secret that the third party must present with every AssumeRole call, enforced as a condition in the trust policy. The attacker can guess the role ARN but cannot supply Trailbase's unique External ID, so the deputy stays unconfused.

JSONTrust Policy with External ID
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::THIRD-PARTY-ACCOUNT:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "unique-external-id-12345"
        }
      }
    }
  ]
}
STS Best Practices
  1. Use the shortest practical duration to minimize the exposure window
  2. Always require MFA for sensitive roles via a trust policy condition
  3. Use an External ID for third-party access to prevent the confused deputy problem
  4. Log all AssumeRole calls: CloudTrail captures every STS API call
  5. Use regional endpoints to reduce latency and improve availability
  6. Implement credential refresh so applications handle expiration gracefully
Q

What is the purpose of an External ID in a role trust policy?

ATo identify the AWS region
BTo prevent the confused deputy problem
CTo encrypt the session token
DTo extend credential duration

Reading the Exam Scenarios

SAA-C03 rarely says the word STS out loud. It describes a Trailbase-shaped situation and lets the vocabulary point at the API: Active Directory means SAML, social login means Cognito or web identity, two account IDs mean AssumeRole, and a third-party SaaS means External ID.

STS Exam Scenarios

ScenarioSTS APIWhy
User in Account A needs access to S3 in Account BAssumeRoleCross-account access via IAM role
Enterprise users login via Active DirectoryAssumeRoleWithSAMLSAML 2.0 federation with ADFS
Mobile app users authenticate with GoogleAssumeRoleWithWebIdentity (or Cognito)OIDC federation for social login
IAM user needs MFA-protected temporary credentialsGetSessionTokenAdds MFA to existing IAM user
Application on EC2 needs DynamoDB accessAutomatic (Instance Role)EC2 instance role provides credentials automatically
Third-party SaaS needs access to your S3AssumeRole with External IDPrevents confused deputy problem
Lambda function needs cross-account accessAssumeRole (in code)Lambda execution role + assume target role
Exam Tip

Watch for the trap where an answer choice creates an IAM user with access keys for something a role handles: EC2 to S3, Lambda cross-account, third-party access. Whenever an AWS resource or an outsider needs credentials, the role-plus-STS answer beats the permanent-key answer.


Common Pitfalls

Forgetting the Session Token

Copying only the AccessKeyId and SecretAccessKey from a temporary credential set feels complete because that is all a long-term key has. The calls then fail with an InvalidAccessKeyId error, since temporary credentials require the session token on every request. Always carry all three values, make sure AWS_SESSION_TOKEN is set alongside the other environment variables, and prefer SDKs that handle the trio automatically.

Not Handling Credential Expiration

Temporary credentials expire, by default after one hour, and there is no warning beforehand. A long-running application that treats them as permanent will suddenly start failing mid-job. Implement refresh logic, or lean on the AWS SDK credential providers and instance roles that refresh for you, and always request new credentials before the old ones lapse.

Overly Permissive Trust Policies

A trust policy with Principal star invites any AWS account to attempt the assumption, which defeats the entire point of role-based access. Name exact principal ARNs, require an External ID for third parties, require MFA for sensitive roles, and add conditions to narrow the door further.

Skipping the External ID

Granting a third party cross-account access without an External ID leaves the confused deputy door open: a malicious actor can point the third-party service at your role and ride its legitimate access into your resources, a common vulnerability in multi-tenant systems. Generate a unique, unpredictable External ID for every such relationship and validate it in the trust policy.


Quick Reference

STS API Quick Reference

APIUse CaseRequires IAM User?
AssumeRoleCross-account access, role switchingNo (caller needs permission)
AssumeRoleWithSAMLEnterprise SSO via SAMLNo
AssumeRoleWithWebIdentityMobile/web app social loginNo
GetSessionTokenMFA for IAM user credentialsYes
GetFederationTokenCustom identity brokerYes
TEXTSTS Endpoint URLs
Global:     https://sts.amazonaws.com
US East:    https://sts.us-east-1.amazonaws.com
EU West:    https://sts.eu-west-1.amazonaws.com
AP Tokyo:   https://sts.ap-northeast-1.amazonaws.com

Regional endpoints reduce latency - credentials work globally
SHCommon STS CLI Commands
# Assume a role
aws sts assume-role --role-arn <role-arn> --role-session-name <name>

# Assume role with MFA
aws sts assume-role --role-arn <role-arn> --role-session-name <name> \
  --serial-number <mfa-arn> --token-code <code>

# Get session token (with MFA)
aws sts get-session-token --serial-number <mfa-arn> --token-code <code>

# Get caller identity
aws sts get-caller-identity

# Decode authorization message
aws sts decode-authorization-message --encoded-message <message>


Further Reading

Related services

STSIAMCognito