DEV Community

Animesh Bhadra 🎯
Animesh Bhadra 🎯

Posted on • Originally published at archerimagine.com on

Doing AWS STS the right way.

AWS Made Easy | AWS STS, Security Token Service

Introduction

You have seen in the previous topic on IAM Roles, 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. 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 (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

Benefits of AWS STS

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

When to use AWS STS

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

AWS STS Actions

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

AWS STS | AssumeRole Action

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

AWS STS | Create Role

You have to follow all the steps mentioned in the article, IAM Roles. 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

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
  • 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": {}
    }
  ]
}

Enter fullscreen mode Exit fullscreen mode

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

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)

Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

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

You might have now understood that IAM Roles 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

Top comments (0)