Introduction

AWS Secure Token Service (STS) is a service provided by AWS that enables you to request temporary credentials with limited privilege for AWS IAM users. In this article, we will learn how to use the AWS CLI with STS to temporarily assume a different role.

Table of contents

Prerequisites

  • AWS CLI
  • AWS Credentials: If you haven’t set up your AWS credentials before, this resource from AWS is helpful.

Create an IAM User with no permissions

For this tutorial, we will use an IAM user that has no permissions. This is what the user looks like in the AWS console:

AWS IAM User

We can confirm that this user has no permissions by running the following command:

aws s3 ls

An error occurred (AccessDenied) when calling the ListBuckets operation: Access Denied

How to create a new IAM role that can be assumed?

Next, we will create a new IAM role that our IAM user will assume. This IAM role has read-only access to all S3 buckets in our account.

To ensure that our IAM user can assume this role, we need to add a Trust policy in the IAM role where the Principal is our IAM user. The trust policy for this IAM role looks something like this:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::641879703613:user/learnaws-test-user"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

AWS IAM Role

How to assume an IAM role?

We will assume this new IAM role that we created using the assume-role subcommand in the aws sts command. The command returns a set of temporary credentials that will allow us to access AWS resources associated with the IAM Role that we want to assume. These temporary credentials consist of an access key ID, a secret access key, and a security token.

The arguments for this command are:

  • role-arn: ARN for the IAM role we want to assume
  • role-session-name: Name for session to uniquely identify

We will also pipe the output of this command so that we can store the credentials directly in our session. This will reduce the number of steps needed to manually add the credentials. This post on Stack Overflow provides a few ways on how you could do this.

export $(printf "AWS_ACCESS_KEY_ID=%s AWS_SECRET_ACCESS_KEY=%s AWS_SESSION_TOKEN=%s" \
$(aws sts assume-role \
--role-arn arn:aws:iam::xxxx:role/s3-read-only-assume-role \
--role-session-name TestSessionName \
--query "Credentials.[AccessKeyId,SecretAccessKey,SessionToken]" \
--output text))

We can now query S3 to verify that our credentials are working as expected:


aws s3 ls
2022-01-29 17:11:02 my-learnaws-test-bucket

These credentials are valid for an hour by default, after which they expire. If you try to use these credentials after they have expired, you will get an Access Denied error.