January 14, 2023

AWS STS – The most important information

Share this

By Andrei Maksimov

January 14, 2023

sts

Understanding how AWS Secure Token Service (STS) service works is important because it provides a secure way of managing access to AWS services and resources. AWS STS allows users to request temporary security credentials for managing specific AWS services and resources. By understanding the mechanisms of how STS works, you can improve the security of your AWS environment and prevent any potential misuse of credentials.

This article provides the most important information about AWS STS you need to know while using AWS cloud daily.

What is AWS Security Token Service (STS) on AWS?

AWS Security Token Service is an Amazon Web Services (AWS) service that allows you to get temporary security credentials (up to 1 hour) to users who need access to AWS resources. STS enables secure cross-account access and short-term, limited privilege credentials for applications that use AWS Identity and Access Management (IAM).

The most well-known AWS STS API calls are:

  • AssumeRole – allows assuming IAM roles within your AWS account or cross-account
  • GetCallerIdentity – returns information details about the IAM user or role used in the API call and answers the question about who you are and what’s your account number
  • AssumeRoleWithSAML – returns IAM credentials for users logged in using SAML
  • GetSessionToken – allows assuming an IAM role for MFA-protected API operations

Other important API calls you are worth knowing:

AWS STS use cases

AWS Secure Token service covers the following use cases:

  • It allows you to temporarily assume AWS IAM roles in the same AWS account or cross-account
  • It supports Identity federation (SAML or IdP)

AWS STS regional endpoints

By default, the AWS Security Token Service (AWS STS) is available as a global service, and all AWS STS requests go to a single endpoint at https://sts.amazonaws.com. AWS recommends using Regional AWS STS endpoints instead of the global endpoint to reduce latency, build redundancy, and increase session token validity.

Additionally, using Regional AWS STS endpoints isolates your application API calls to AWS to a specific region which might be necessary for organizations following strict compliance and regulatory requirements.

Assume an IAM Role using AWS STS

To assume an IAM role using STS, you need to:

AWS STS - AssumeRole API Call

To assume an IAM role using Boto3, you need to use the assume_role() method of the STS client.

import boto3
CURRENT_ACCOUNT_SESSION = boto3.Session()
STS_CLIENT = CURRENT_ACCOUNT_SESSION.client('sts')
AWS_ACCOUNT_ID = '585584209241'
ROLE_NAME = 'demo-role'
assumed_role_object = STS_CLIENT.assume_role(
    RoleArn=f'arn:aws:iam::{AWS_ACCOUNT_ID}:role/{ROLE_NAME}',
    RoleSessionName=f'{ROLE_NAME}-Session'
)
assumed_role_credentials = assumed_role_object['Credentials']
ASSUMED_ROLE_SESSION = boto3.Session(
    aws_access_key_id=assumed_role_credentials['AccessKeyId'],
    aws_secret_access_key=assumed_role_credentials['SecretAccessKey'],
    aws_session_token=assumed_role_credentials['SessionToken'],
)
instances = ASSUMED_ROLE_SESSION.resource('ec2', region_name="us-east-2").instances.all()
for instance in instances:
    print(f'Instance ID: {instance.id}')

Here’s an execution output:

AWS STS - Assuming IAM role

MFA-protected API calls

There are several ways of making MFA-protected API calls.

AssumeRole with MFA

To use MFA with AssumeRole, you need to pass values for the SerialNumber and TokenCode parameters:

import boto3
DEFAULT_SESSION = boto3.Session()
def get_user_mfa_serial_number():
    sts_client = DEFAULT_SESSION.client('sts')
    user_arn = sts_client.get_caller_identity()['Arn']
    return user_arn.replace(':user/', ':mfa/')

def assume_role_with_mfa(role_arn='arn:aws:iam::585584209241:role/demo-mfa-s3-full-access'):
    sts_client = DEFAULT_SESSION.client('sts')
    mfa_serial_number = get_user_mfa_serial_number()
    mfa_token_code = input("Enter MFA token: ")
    role_creds = sts_client.assume_role(
        RoleArn=role_arn,
        DurationSeconds=900,
        SerialNumber=mfa_serial_number,
        TokenCode=mfa_token_code,
        RoleSessionName=f'assumed-{role_arn.split("/")[1]}'
    )
    access_key = role_creds['Credentials']['AccessKeyId']
    secret_key = role_creds['Credentials']['SecretAccessKey']
    session_token = role_creds['Credentials']['SessionToken']
    session = boto3.Session(
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key,
        aws_session_token=session_token
    )
    return session

assumed_session = assume_role_with_mfa()
buckets = assumed_session.resource('s3').buckets.all()
for bucket in buckets:
    print(f'Bucket name: {bucket.name}')

GetSessionToken

If your AWS user uses AWS Access Key and Secret Access Key to make API calls, you can enable MFA support using the GetSessionToken API call.

import csv
import boto3
csv_data = []
with open('admin_accessKeys.csv', 'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        csv_data.append(row)

ACCOUNT_ID = '585584209241'
ACCESS_KEY = csv_data[0]['Access key ID']
SECRET_KEY = csv_data[0]['Secret access key']

def get_mfa_enabled_session():
    session = boto3.Session(
        aws_access_key_id=ACCESS_KEY,
        aws_secret_access_key=SECRET_KEY,
    )
    mfa_token = input("Enter MFA token: ")
    sts_client = session.client('sts')
    session_token = sts_client.get_session_token(
        DurationSeconds=900,
        SerialNumber=f'arn:aws:iam::{ACCOUNT_ID}:mfa/admin',
        TokenCode=mfa_token
    )
    access_key = session_token['Credentials']['AccessKeyId']
    secret_key = session_token['Credentials']['SecretAccessKey']
    session_token = session_token['Credentials']['SessionToken']
    session = boto3.Session(
        aws_access_key_id=access_key,
        aws_secret_access_key=secret_key,
        aws_session_token=session_token
    )
    return session

mfa_enabled_session = get_mfa_enabled_session()
buckets = mfa_enabled_session.resource('s3').buckets.all()
for bucket in buckets:
    print(f'Bucket name: {bucket.name}')

GetSessionToken API call requires session initiated from the static credentials and it will not work from credentials provided by the session.

An error occurred (AccessDenied) when calling the GetSessionToken operation: Cannot call GetSessionToken with session credentials

FAQ

What Is The Difference Between AWS IAM And STS?

AWS IAM controls who can access what resources in AWS infrastructure. AWS STS relies on AWS IAM and helps secure access to AWS resources by exchanging temporary credentials for a user or role. It provides short-term limited privilege credentials so that users don’t have to store long-term authentication tokens.

What Is The Difference Between AWS STS vS. Cognito?

The main difference between AWS STS and Amazon Cognito is the purpose they serve. AWS STS provides temporary credentials to grant users access to AWS services, while Amazon Cognito primarily focuses on providing user authentication and authorization for applications. AWS STS gives trusted users secure access to other services within the same account, while Amazon Cognito allows developers to easily add user authentication and authorization to their applications with minimal configuration.

Andrei Maksimov

I’m a passionate Cloud Infrastructure Architect with more than 15 years of experience in IT.

Any of my posts represent my personal experience and opinion about the topic.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Related Posts

How to install AWS CLI – Windows, Linux, OS X
AWS Activate – Maximize Your Startup’s Potential
AWS Spot Instance – The most important information
AWS Elastic IP – Everything you need to know

Subscribe now to get the latest updates!

>