Preporato

SAA-C03 Study Guide

Design Secure ArchitecturesSecure Access to AWS ResourcesAWS 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

AWS Security Token Service (STS) & Temporary Credentials

Overview

AWS Security Token Service (STS) is a web service that enables you to request temporary, limited-privilege credentials for IAM users or federated users. These credentials work almost identically to long-term access keys but expire automatically after a specified duration.

Temporary credentials are foundational to AWS security best practices. They eliminate the need to distribute or embed long-term credentials, reduce the blast radius of compromised credentials, and enable advanced features like cross-account access and identity federation.

Core Concept

Temporary credentials consist of three components:

  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

All three must be included when making AWS API calls with temporary credentials.

Exam Tip

STS questions often focus on which API to use for specific scenarios: AssumeRole for cross-account access, AssumeRoleWithSAML for enterprise federation, and AssumeRoleWithWebIdentity for mobile/web apps.


Architecture Diagram

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

Key Concepts

How Temporary Credentials Work

Temporary Credentials Lifecycle

Request Phase:

  1. User/application calls STS API (e.g., AssumeRole)
  2. STS validates the request against trust policy
  3. STS returns temporary credentials

Usage Phase:

  1. Application uses credentials for AWS API calls
  2. Credentials include session token in every request
  3. AWS validates credentials on each request

Expiration Phase:

  1. Credentials expire automatically (no revocation needed)
  2. Application must request new credentials before expiration
  3. Cannot extend existing credentials - must request new ones

Credential Duration

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)

STS API Operations

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 trust policy allowing the caller
  • Optional: MFA requirement in trust policy

Returns: AccessKeyId, SecretAccessKey, SessionToken, Expiration

AssumeRoleWithSAML

Purpose: Exchange 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 trusted IdP
  • IAM SAML identity provider configured
  • Role trust policy allowing SAML federation

No IAM User Required: Users don't need IAM accounts

AssumeRoleWithWebIdentity

Purpose: Exchange 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 web identity provider
  • IAM OIDC identity provider configured
  • Role trust policy allowing the IdP

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 user already has long-term credentials

Key Difference: Used by IAM users, not for role assumption

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: Caller determines the federated user's permissions (subset of caller's permissions)


How It Works

Cross-Account Access with AssumeRole

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

Step 1: Create Role in Target Account

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: Grant AssumeRole Permission in Source Account

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

Step 3: Assume the Role

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/

Using AssumeRole with MFA

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

Federation with SAML

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

Use Cases

Use Case 1: EC2 Instance Role

Scenario: Application on EC2 needs to access S3 and DynamoDB.

Solution: Attach an IAM role to the EC2 instance.

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

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

Use Case 2: Cross-Account S3 Access

Scenario: Development team in Account A needs read access to production logs in Account B.

Solution:

  1. Account B creates role with S3 read permissions and trust policy for Account A
  2. Account A grants developers permission to assume the role
  3. Developers assume role to access logs, credentials expire after session

Use Case 3: CI/CD Pipeline

Scenario: Jenkins needs to deploy to AWS without long-term credentials.

Solution:

  1. Create IAM role with deployment permissions
  2. Configure Jenkins to assume role using OIDC federation or instance role
  3. Each deployment gets fresh, short-lived credentials

Use Case 4: Mobile App with Cognito

Scenario: Mobile app needs user-specific access to S3 buckets.

Solution:

  1. User authenticates with Amazon Cognito
  2. Cognito exchanges identity token for temporary AWS credentials
  3. App uses credentials scoped to that user's data

Best Practices

STS Best Practices
  1. Use Shortest Practical Duration - Minimize exposure window
  2. Always Require MFA for Sensitive Roles - Add condition to trust policy
  3. Use External ID for Third-Party Access - Prevent confused deputy problem
  4. Log All AssumeRole Calls - CloudTrail captures all STS API calls
  5. Use Regional Endpoints - Reduce latency and improve availability
  6. Implement Credential Refresh - Handle expiration gracefully in applications

External ID for Third-Party Access

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"
        }
      }
    }
  ]
}

Common Exam Scenarios

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

Common Pitfalls

Pitfall 1: Forgetting the Session Token

Mistake: Using only AccessKeyId and SecretAccessKey from temporary credentials.

Why it fails:

  • Temporary credentials REQUIRE the session token
  • API calls will fail with "InvalidAccessKeyId" error
  • Easy to miss when copying credentials manually

Correct Approach:

  • Always include all three: AccessKeyId, SecretAccessKey, SessionToken
  • Use AWS SDKs that handle this automatically
  • Check environment variables include AWS_SESSION_TOKEN
Pitfall 2: Not Handling Credential Expiration

Mistake: Assuming credentials last forever or not refreshing them.

Why it fails:

  • Temporary credentials expire (default 1 hour)
  • Long-running applications will suddenly fail
  • No warning before expiration

Correct Approach:

  • Implement credential refresh logic
  • Use AWS SDKs with built-in refresh (instance roles, credential providers)
  • Request new credentials before expiration
Pitfall 3: Overly Permissive Trust Policies

Mistake: Using "Principal": "*" in role trust policies.

Why it's dangerous:

  • Any AWS account could potentially assume the role
  • No external ID means any caller can assume
  • Defeats the purpose of role-based access

Correct Approach:

  • Specify exact principal ARNs
  • Require External ID for third-party access
  • Require MFA for sensitive roles
  • Use conditions to further restrict
Pitfall 4: Confused Deputy Problem

Mistake: Not using External ID when granting cross-account access to third parties.

Why it matters:

  • Malicious actor could trick third-party service into accessing your resources
  • Third-party service might accidentally access wrong customer's data
  • Common security vulnerability in multi-tenant systems

Correct Approach:

  • Always use External ID for third-party access
  • Generate unique, unpredictable External IDs
  • Validate External ID in trust policy

Test Your Knowledge

Q

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

AGetSessionToken
BGetFederationToken
CAssumeRole
DAssumeRoleWithWebIdentity
Q

What components make up temporary security credentials?

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
Q

An enterprise wants to allow employees to access AWS using their Active Directory credentials. Which STS API should they use?

AAssumeRole
BAssumeRoleWithWebIdentity
CAssumeRoleWithSAML
DGetFederationToken
Q

What is the purpose of 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


Quick Reference

STS API Comparison

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

STS Endpoints

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

CLI Commands

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 AWS Services

STSIAMCognito