12 min to read
What is AWS Assume Role?

Overview
AWS Assume Role is a fundamental security feature that enables temporary, controlled access to AWS resources across accounts or within the same account. It’s a cornerstone of the AWS security model that implements the principle of least privilege while providing the flexibility needed for modern cloud architectures.
What is AWS Assume Role?
AWS Assume Role is a function provided by AWS Security Token Service (STS) that allows one IAM entity (user or service) to temporarily adopt another role in AWS and use the permissions associated with that role.
This mechanism enhances security and simplifies access management by granting only the necessary permissions for the duration required to complete specific tasks.
The sts:AssumeRole
operation enables a secure delegation model where:
- Temporary access: Credentials expire after a specified duration (15 minutes to 12 hours)
- No sharing of long-term credentials: Eliminates the need to share permanent IAM credentials
- Granular permissions: Access can be restricted based on session policies, source IP, and more
- Centralized management: Simplifies permission management across multiple accounts
Key Use Cases
- Cross-account access: Access resources in another AWS account without creating and managing users in that account
- Within-account delegation: Assume a role with different permissions than your current IAM entity
- Application development: Use different roles for development, testing, and production environments
- Third-party access: Allow external partners to access your AWS resources securely
- Emergency access: Implement break-glass procedures for emergency situations
How AWS Assume Role Works
- Trust relationship: The target role specifies which entities (principals) can assume it
- Permission check: The assuming entity must have permission to call the
sts:AssumeRole
action - STS call: The entity calls the AssumeRole API with the role ARN and optional parameters
- Temporary credentials: STS returns temporary security credentials (access key, secret key, session token)
- Using credentials: Applications use these credentials to make AWS API calls with the role’s permissions
Detailed Example: Cross-Account EKS Access
The following example demonstrates how to use AssumeRole to grant Account A access to EKS resources in Account B.
Step 1: Create IAM Role in Account B (Target Account)
Create an IAM role with a trust policy that allows Account A to assume this role. The role will have permissions to manage EKS resources.
Trust Policy (in Account B):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root" // Account A ID
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalOrgID": "o-exampleorgid" // Optional: Restrict to AWS Organization
}
}
}
]
}
For more granular control, you can specify specific roles or users in Account A:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/DevOpsTeamRole" // Specific role in Account A
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/Department": "DevOps" // Optional: Require specific tags
}
}
}
]
}
Permission Policy (in Account B):
Attach an appropriate permission policy to the role that grants the necessary EKS permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"eks:DescribeCluster",
"eks:ListClusters",
"eks:UpdateClusterConfig",
"eks:DescribeUpdate"
],
"Resource": "arn:aws:eks:region:111122223333:cluster/*"
}
]
}
Step 2: Create IAM Policy in Account A (Source Account)
Create and attach an IAM policy to the users or roles in Account A that need to assume the role in Account B.
Example Policy (in Account A):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::111122223333:role/EKSAdminRole",
"Condition": {
"StringLike": {
"aws:RequestedRegion": [
"us-west-2",
"us-east-1"
]
}
}
}
]
}
Step 3: Assume Role from Account A
A user or service in Account A can now assume the role in Account B using the AWS CLI, SDK, or AWS console.
Using AWS CLI:
This command returns a JSON object containing:
AccessKeyId
SecretAccessKey
SessionToken
Expiration
timestamp
Using AWS SDK (Python example):
import boto3
# Create an STS client
sts_client = boto3.client('sts')
# Assume the role
assumed_role = sts_client.assume_role(
RoleArn='arn:aws:iam::111122223333:role/EKSAdminRole',
RoleSessionName='EKSAdminSession',
DurationSeconds=3600 # 1 hour
)
# Extract the temporary credentials
credentials = assumed_role['Credentials']
# Create an EKS client using the temporary credentials
eks_client = boto3.client(
'eks',
region_name='us-west-2',
aws_access_key_id=credentials['AccessKeyId'],
aws_secret_access_key=credentials['SecretAccessKey'],
aws_session_token=credentials['SessionToken']
)
# Now you can make EKS API calls
clusters = eks_client.list_clusters()
print(clusters)
Step 4: Use Temporary Credentials for Access
These temporary credentials can be used to access EKS resources in Account B. Here’s an example of updating your kubeconfig:
You can also create a shell profile that automatically assumes the role:
# Add to your ~/.bash_profile or ~/.zshrc
function assume-eks-role() {
output=$(aws sts assume-role --role-arn arn:aws:iam::111122223333:role/EKSAdminRole --role-session-name EKSSession)
export AWS_ACCESS_KEY_ID=$(echo $output | jq -r '.Credentials.AccessKeyId')
export AWS_SECRET_ACCESS_KEY=$(echo $output | jq -r '.Credentials.SecretAccessKey')
export AWS_SESSION_TOKEN=$(echo $output | jq -r '.Credentials.SessionToken')
echo "Temporary credentials set for EKS admin role"
}
What is sts:AssumeRoleWithWebIdentity?
The
sts:AssumeRoleWithWebIdentity
operation allows you to obtain temporary AWS credentials by using an OpenID Connect (OIDC) token or SAML 2.0 assertion from an external identity provider.
This mechanism enables federating AWS access with external identity systems without requiring AWS IAM users for each identity.
Key Benefits
- No IAM users needed: Eliminates the need to create IAM users for each external identity
- Centralized identity management: Use your existing identity provider
- Zero IAM credentials: No long-term AWS credentials to manage or rotate
- Auditable access: All access is logged in AWS CloudTrail with the original identity information
Common Use Cases
- GitHub Actions: Authenticate GitHub workflows to access AWS resources
- Kubernetes Service Accounts: Allow pods to access AWS services securely
- Web/Mobile Applications: Allow authenticated application users to access AWS resources directly
- Enterprise SSO: Enable employees to access AWS using their corporate credentials
- Self-developed applications: Authenticate custom applications with your own OIDC provider
Process Flow
- OIDC Provider Configuration: Register an OIDC provider in IAM and create a role with a trust policy
- Identity Authentication: User/service authenticates with the external IdP and receives an OIDC token
- AWS API Call: Application calls
AssumeRoleWithWebIdentity
API with the OIDC token - Token Verification: AWS verifies the token with the configured OIDC provider
- Temporary Credentials: Upon successful verification, AWS issues temporary credentials
Example: GitHub Actions Integration
IAM OIDC Provider Configuration:
aws iam create-open-id-connect-provider \
--url https://token.actions.githubusercontent.com \
--client-id-list sts.amazonaws.com \
--thumbprint-list 6938fd4d98bab03faadb97b34396831e3780aea1
Role Trust Policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
"token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
}
}
}
]
}
GitHub Actions Workflow:
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
role-to-assume: arn:aws:iam::ACCOUNT_ID:role/GitHubActionsRole
aws-region: us-east-1
- name: Deploy infrastructure
run: aws cloudformation deploy --template-file template.yaml --stack-name my-stack
Comparison: AssumeRole vs AssumeRoleWithWebIdentity vs AssumeRoleWithSAML
Authentication:
- sts:AssumeRole: AWS IAM credentials
- sts:AssumeRoleWithWebIdentity: OIDC token
- sts:AssumeRoleWithSAML: SAML 2.0 assertion
Identity Source:
- sts:AssumeRole: AWS IAM
- sts:AssumeRoleWithWebIdentity: External OIDC providers (Google, GitHub, etc.)
- sts:AssumeRoleWithSAML: SAML IdPs (Active Directory, Okta, etc.)
Primary Use Cases:
- sts:AssumeRole: Cross-account access, delegation within AWS
- sts:AssumeRoleWithWebIdentity: Mobile/web apps, CI/CD pipelines, Kubernetes
- sts:AssumeRoleWithSAML: Enterprise SSO, workforce identity federation
Required Setup:
- sts:AssumeRole: IAM roles and policies
- sts:AssumeRoleWithWebIdentity: OIDC provider + IAM role
- sts:AssumeRoleWithSAML: SAML provider + IAM role
Credential Duration:
- sts:AssumeRole: 15 min - 12 hours
- sts:AssumeRoleWithWebIdentity: 15 min - 12 hours
- sts:AssumeRoleWithSAML: 15 min - 12 hours
Common Examples:
- sts:AssumeRole: AWS CLI, AWS console
- sts:AssumeRoleWithWebIdentity: GitHub Actions, Kubernetes ServiceAccounts
- sts:AssumeRoleWithSAML: AWS Console login via corporate SSO
Best Practices for AWS Assume Role
1. Security: - Apply the principle of least privilege to all roles
- Use external IDs for third-party access to prevent confused deputy problems
- Implement condition keys in trust policies (source IP, MFA, etc.)
- Set appropriate session durations (shorter is better)
- Use temporary credentials instead of long-term access keys
2. Implementation: - Define clear, descriptive role names and session names
- Use session tags to enhance logging and authorization
- Implement role chaining carefully (respecting maximum duration limits)
- Consider using permission boundaries to limit maximum permissions
- Use AWS Organizations SCPs to enforce guardrails
3. Monitoring and Compliance: - Enable CloudTrail logging for all STS actions
- Set up alerts for suspicious role assumption activities
- Regularly audit role trust policies and permissions
- Implement automated compliance checks for roles
- Use IAM Access Analyzer to identify unintended access
4. Operational Excellence: - Document role purpose and access patterns
- Implement infrastructure as code for role management
- Develop consistent naming conventions
- Set up a role review process
- Create emergency access procedures
Troubleshooting Common Issues
1. Access Denied Errors: - Check trust relationships in the target role
- Verify the assuming entity has sts:AssumeRole permission
- Examine IAM policy conditions that might be restricting access
- Confirm the role ARN is correct
2. Session Errors: - Ensure session duration is within limits (maximum 12 hours)
- Check that role chaining doesn't exceed maximum duration
- Verify session name contains only allowed characters
3. OIDC/SAML Issues: - Verify OIDC provider configuration is correct
- Check that token claims match the conditions in the trust policy
- Ensure the token is not expired
- Validate that the OIDC provider's TLS certificate is trusted
4. Permission Problems: - Review CloudTrail logs for specific permission denials
- Check for conflicting deny statements in policies
- Ensure required permissions are included in the role policy
- Look for organization SCPs that might be restricting access
Comments