Doing AWS STS the right way.
Tags: aws, cloud, sts, awssts
Published: 2021-04-20 19:08:55

---
title: Doing AWS STS the right way.
published: true
date: 2021-03-20 10:50:58 UTC
tags: aws,cloud, sts, awssts
canonical_url: https://www.archerimagine.com/articles/aws/aws-sts.html
---

![AWS Made Easy | AWS STS, Security Token Service](https://www.archerimagine.com/images/aws/IAM/05-AWS-STS.png "AWS Made Easy | AWS STS, Security Token Service")

## Introduction[¶](#introduction "Permanent link")

You have seen in the previous topic on [IAM Roles](https://www.archerimagine.com/articles/aws/aws-iam-roles.html), some users and resource can assume a role, moreover an IAM Roles are like a hat which anyone can wear and gets its power. One important part of this should bother you, how does AWS authenticate such users, if the user is a genuine or not.

AWS STS of Security token service plays an important part in enabling [IAM Roles](https://www.archerimagine.com/articles/aws/aws-iam-roles.html). When you are using a cross account resource or any federated users, you can also use AWS STS to provide temporary user credentials.

AWS STS though can be used to support mobile application using AWS resources, but it is advised to use AWS cognitio, which will be discussed in the future.

You will learn what is AWS STS, what are its benefits, when to use it. You will also learn to use a specific Action/API called `assumerole` to get access to an AWS resource for an AWS cross account.

## AWS STS[¶](#aws-sts "Permanent link")

AWS STS (Security token service) as the name suggest, provides a security token for accessing a AWS resources. You may think AWS STS as the provider of temporary access.

AWS STS has these specific properties when assigning temporary access

- It can range from few minutes to a few hours.
- Once the AWS STS provided temporary token expires, it cannot be reused at any point.
- You can invoke AWS STS only through AWS SDKs or AWS CLIs.

![AWS Made Easy | AWS STS, Properties](https://www.archerimagine.com/images/aws/IAM/AWS-STS-properties.png "AWS Made Easy | AWS STS, Properties")

### Benefits of AWS STS[¶](#benefits-of-aws-sts "Permanent link")

AWS STS solves a very specific problem for you, when you want someone to temporarily access your AWS resource without having concerns of revoking the permission.

AWS STS provides a way to

- You should not embedded long term AWS security credentials into an application.
- You should not create extra IAM identities, using IAM roles with AWS STS is enough to satisfy the temporary access requirement.
- You do not have to worry about deactivating the AWS STS credentials, 36 hours is the maximum you can set the AWS STS expiry time depending on the API invoked.

![AWS Made Easy | AWS STS, Benefits](https://www.archerimagine.com/images/aws/IAM/AWS-STS-Benefits.png "AWS Made Easy | AWS STS, Benefits")

### When to use AWS STS[¶](#when-to-use-aws-sts "Permanent link")

You have now understood what is AWS STS, also what are the benefits of AWS STS. You might also have guessed the use cases for using AWS STS. Here if a breakdown for this.

- In Hybrid Cloud setup, where you have to give access to the non AWS account holder. These methods are generally used for giving access to 3rd party
  - SAML 2.0 Identity federation.
  - Web Identity Federation. (Facebook, Github, etc.)
- Cross Account roles, when you have to give your developer account a temporary access to your production account.
- IAM roles for AWS services.

![AWS Made Easy | AWS STS, UseCase](https://www.archerimagine.com/images/aws/IAM/AWS-STS-UseCase.png "AWS Made Easy | AWS STS, UseCase")

### AWS STS Actions[¶](#aws-sts-actions "Permanent link")

You should learn about these five common AWS STS Actions.

- `AssumeRole` : This is used for getting cross account access.
- `AssumeRoleWithWebIdentity` : This is using any 3rd party web IDP like Google or Facebook.
- `AssumeRoleWithSAML` : This is for hybrid cloud, where you have an entity with SAML 2.0
- `GetFederationToken` : This is used by the AWS root account or any IAM user.
- `GetSessionToken` : This is used by the AWS root account or any IAM user.

Here is a comparison for you on the above APIs.

![AWS Made Easy | AWS STS, API Comparison](https://www.archerimagine.com/images/aws/IAM/AWS-STS-API-Comparision.png "AWS Made Easy | AWS STS, API Comparison.")

## AWS STS | AssumeRole Action[¶](#aws-sts-assumerole-action "Permanent link")

You have the basic understanding of the different Action provided by AWS STS. Let's now try to use `AssumeRole` API to understand how this works.

Here is what you are going to try, or what we call a problem definition.

> You will have a user with no permission on the AWS Account. Now create an IAM Role, with AmazonS3FullAccess permission. Once you have the Role, edit the trust relationship to give ARN of the user which does not have any permission. Now using AWS Boto3 SDK you will make the user connect to AWS.

A pictorial representation of the step to help you understand.

![AWS Made Easy | AWS STS, Cross Account AssumeRole](https://www.archerimagine.com/images/aws/IAM/Cross-Account-Role.png "AWS Made Easy | AWS STS, Cross Account AssumeRole")

### AWS STS | Create Role[¶](#aws-sts-create-role "Permanent link")

You have to follow all the steps mentioned in the article, [IAM Roles](https://www.archerimagine.com/articles/aws/aws-iam-roles.html#how-to-create-an-aws-iam-role). Once change would be this time we should select the **Another AWS account** option. You may need to give the 12 digit account number.

The above steps are the same we will use for cross account access. The steps will not change.

### AWS STS | Change the trust relationship[¶](#aws-sts-change-the-trust-relationship "Permanent link")

When you create the role like it is mentioned in the previous step, by default it will always point to the account root user, you have to change it to the ARN of the user you want to do a `AssumeRole`. Here is how you can do it.

- Select the role.
- Click on **Trust Relationship** options, and select the _Edit trust relationship_ button.
  - ![AWS Made Easy | AWS STS, STS | Edit Trust Relationship](https://www.archerimagine.com/images/aws/IAM/edit-trust-relationship.png "AWS Made Easy | AWS STS, Edit Trust Relationship")
- This will open a JSON Editor and edit the JSON for this particular user shown below, esp. the Principal, AWS option.

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/Test"
      },
      "Action": "sts:AssumeRole",
      "Condition": {}
    }
  ]
}

```

You might be thinking, if we have to edit this option every time we have to assign to a new user, then how is this scalable?

The answer is, most of the time we will add a particular group with the IAM role attached and the required user is added or removed from the group to control the access.

### AWS STS | BOTO3 code to AssumeRole[¶](#aws-sts-boto3-code-to-assumerole "Permanent link")

Now you have to write using the BOTO3 SDK provide for Python, the sample code to `AssumeRole`. Here is the sample code.

```
import boto3
import pprint
from boto3.session import Session

# Below is the ARN of the role.
arn = "arn:aws:iam::123456789012:role/account-s3-full-access"
session_name = "example-role"
client = boto3.client("sts")
account_id = client.get_caller_identity()["Account"]
print(account_id)

# Assume role takes the roles ARN and a sample session name
response = client.assume_role(RoleArn=arn, RoleSessionName=session_name)

pprint.pprint(response)

# Create an S3 resource that can access the account with the temporary credentials.
temp_credentials = response["Credentials"]

# Access the S3 as a resource passing the temporary credentials received from STS.
s3_resource = boto3.resource(
    "s3",
    aws_access_key_id=temp_credentials["AccessKeyId"],
    aws_secret_access_key=temp_credentials["SecretAccessKey"],
    aws_session_token=temp_credentials["SessionToken"],
)
print(f"Listing buckets for the assumed role's account:")
for bucket in s3_resource.buckets.all():
    print(bucket.name)

```

Once you run the above code, you should be getting the list of S3 buckets in your account. Though the user did not have access initially.

### AWS STS | AssumeRole | Return Parameters[¶](#aws-sts-assumerole-return-parameters "Permanent link")

You should be thinking what is returned by STS, here is the JSON response returned by calling `assume_role` BOTO3 API.

```
{
   "AssumedRoleUser":{
      "Arn":"arn:aws:sts::123456789012:assumed-role/acc-s3-full-access/example-role",
      "AssumedRoleId":"AROAUXRIFYXT7BG3ENQGE:example-role"
   },
   "Credentials":{
      "AccessKeyId":"ASIAUXRIFYXTUVPIQWFL",
      "Expiration":datetime.datetime(2021,3,20,9,24,27,"tzinfo=tzutc())",
      "SecretAccessKey":"BsXYZCGNuemA8wevm6CnYVfZtNgdGaoOCJ4VwXnf",
      "SessionToken":"FwoGZXIvYXdzEEoaDFAVerghnmasN971Z76yKwAfJgq3tccU72Gj6Xl28zJwJIUS/UEEMtwYmxUDsplTKg0if/keQ9z1BdoPFdLsmDtUiWDnfvIkICUbCeVk+DKI4c9LtdIAXmhpssg4IAMncYFsmh+ylOdbbcud134TOkDkCtuZMkfKuUbIMG3lTq10k93DsiUFAoH5pqyLAa9IyqHUbKUxwwde0UAcUU1lNFMO/sTZI8kAIQNM4cpGMxdyPsYZaX5M1IGWqr2gPNLqLtKLvi1oIGMi33r+lP9GWX5W+Ich1MHUAfUfhgqIjXHjpmDQY5S0e/WOTBwrPLoorgXQlHMak="
   },
   "ResponseMetadata":{
      "HTTPHeaders":{
         "content-length":"1057",
         "content-type":"text/xml",
         "date":"Sat, 20 Mar 2021 08:24:27 GMT",
         "x-amzn-requestid":"72f38158-1d90-4619-a431-5a2fcf460a31"
      },
      "HTTPStatusCode":200,
      "RequestId":"72f38158-1d90-4619-a431-5a2fcf460a31",
      "RetryAttempts":0
   }
}

```

You should really be concerned about the `Credentials` parameters which is returned. It basically provides 4 information.

- AccessKeyId : The access key id, which is always required for programmatic access.
- Expiration : Generally it is 15 min, but can vary depending on the type of API being called.
- SecretAccessKey : The secret access key, which is also generated only once.
- SessionToken : As the name suggests, a unique way of identifying the session.

## Conclusion[¶](#conclusion "Permanent link")

You might have now understood that [IAM Roles](https://www.archerimagine.com/articles/aws/aws-iam-roles.html) and AWS STS have a symbiotic relationship. AWS STS is required when you need to provide these range of access.

- The cross account use case, ex. the developer account my need a temporary access to the production system.
- The Hybrid cloud use case, ex. On premise user, authenticated using SAML may need access to AWS resources.
- In Hybrid cloud use case and cross account use case, ex. Authenticating the user using the web identity providers.
- Sometimes IAM Services may need permission to another service, ex EC2 wants to write to a S3 bucket.

The above access is provided to you using the AWS STS because.

- AWS STS provides short term credentials, which lives from a few minutes to some hours.
- We should not be bothered to revoke the access as you cannot reuse the expired access.
- AWS STS can be provided using the AWS SDKs or CLIs.

The real benefits of AWS STS are,

- No need to embed long term credentials to the application.
- No need to create multiple identities for each access request.
- No need to revoke the access, as it expires automatically.

The various actions provided by AWS STS are

- `AssumeRole`
- `AssumeRoleWithWebIdentity` 
- `AssumeRoleWithSAML` 
- `GetFederationToken` 
- `GetSessionToken` 

and we discussed `AssumeRole` Action uses the cross account example, where you created an IAM role, edited the trust relationship and then the user assuming the role, by using the Boto3 SDKs. By doing this the IAM user from another account could access AWS resources for a short period of time.

The `AssumeRole` returns these parameters when a call is made it

- AccessKeyId 
- Expiration 
- SecretAccessKey 
- SessionToken 

You might recognize it returns all the parameters created for IAM user having programmatic access, i.e. AccessKeyId and SecretAccessKey. In addition, we get the SessionToken and an expiration time.

Please provide you feedback if you have any other use case for AWS STS.

## Reference[¶](#reference "Permanent link")

- Photo by [Ales Nesetril](https://unsplash.com/@alesnesetril) on [Unsplash](https://unsplash.com/s/photos/technology)
- [How to Use a Single IAM User to Easily Access All Your Accounts by Using the AWS CLI](https://aws.amazon.com/blogs/security/how-to-use-a-single-iam-user-to-easily-access-all-your-accounts-by-using-the-aws-cli/)
- [Introduction to AWS Security Token Service(STS)](https://devopslearning.medium.com/introduction-to-aws-security-token-service-sts-b3049aade3c1)
- [Switching to an IAM role (AWS API)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-api.html)
- [Providing access to an IAM user in another AWS account that you own](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_aws-accounts.html)
- [Requesting temporary security credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html)
- [Switching to a role (console)](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html)
- [Boto3 Python Gist](https://gist.github.com/DaisukeMiyamoto/2d9ed49dc7625adc41835beab7aad58e)