What is AWS Assume Role?

Featured image

image reference link



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:

Key Use Cases


How AWS Assume Role Works

Assume Role Process Flow

  1. Trust relationship: The target role specifies which entities (principals) can assume it
  2. Permission check: The assuming entity must have permission to call the sts:AssumeRole action
  3. STS call: The entity calls the AssumeRole API with the role ARN and optional parameters
  4. Temporary credentials: STS returns temporary security credentials (access key, secret key, session token)
  5. 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:

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

Common Use Cases

Process Flow

  1. OIDC Provider Configuration: Register an OIDC provider in IAM and create a role with a trust policy
  2. Identity Authentication: User/service authenticates with the external IdP and receives an OIDC token
  3. AWS API Call: Application calls AssumeRoleWithWebIdentity API with the OIDC token
  4. Token Verification: AWS verifies the token with the configured OIDC provider
  5. 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:

Identity Source:

Primary Use Cases:

Required Setup:

Credential Duration:

Common Examples:


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



Reference