Elevating IaC Workflows with Spacelift Stacks and Dependencies 🛠️

Register for the July 23 demo →

AWS

What is AWS STS – Security Token Service?

What is AWS Security Token Service (STS)?

AWS Security Token Service (STS) is an AWS facility for requesting temporary user credentials with limited privileges. It allows you to acquire short-term access to privileged roles in a controlled manner.

STS is ideal when you must briefly interact with sensitive resources in your AWS account, but don’t want to set up a dedicated IAM identity. The credentials issued by STS function identically to regular IAM access keys, but aren’t stored against users and have a limited lifespan – typically a few minutes or hours, with up to 36 hours permissible.

In this article, we will cover:

  1. What is AWS Security Token Service (STS)?
  2. When to Use AWS STS?
  3. How Does AWS STS Work?
  4. Example: Using AWS STS to Assume a Role

What is AWS Security Token Service (STS)?

AWS Security Token Service (STS) provides a mechanism for issuing existing users with temporary credentials that grant access to additional resources. The credentials are generated dynamically, aren’t stored against the user, and have a short lifetime. After an issued set of credentials expires, the user must make another request to STS to re-obtain their privileges if they still require them.

Using STS-issued temporary credentials helps you increase the protection for your AWS account. You can assign users a reduced set of permissions, then allow them to acquire short-term access to sensitive resources on a per-occasion basis.

What’s the Difference Between STS and IAM Roles?

STS and IAM roles complement each other. STS credentials are typically used to delegate access to the IAM roles in your AWS account. A role is an AWS identity that includes one or more permission policies granting access to specific AWS features.

You can directly assign roles to your AWS users, but this creates a risk of over-privileged accounts. For example, deleting an S3 bucket could be a sensitive but rare operation for your organization. Choosing to directly assign a role with the “delete bucket” permission means anyone with access to the credentials can always delete a bucket though.

STS allows authorized users to assume these privileged roles on the occasions that they actually need them. Instead of permanently holding the bucket deletion role, users are able to temporarily acquire the required privileges, then have them automatically expire. This maintains security by allowing a minimal set of privileges to be persisted against the user account.

When to Use AWS STS?

STS is central to several different AWS authorization flows. Here are four common use cases that it facilitates.

  1. Short-lived access to privileged AWS resources
  2. Accessing AWS within applications
  3. Identity federation scenarios
  4. Cross-account and delegated access

Short-lived access to privileged AWS resources

STS is suitable for any situation where you need to acquire short-term access to privileged AWS resources or features. It allows your existing users to assume a sensitive role without having to set up a dedicated IAM identity or run the risk of forgetting to revoke the credentials later on.

You can use STS to improve the security posture for your AWS accounts by preventing the direct assignment of these roles to your users. Instead, configure STS policies for your users so they can request the role at the time they need it.

Accessing AWS within applications

STS helps you manage credentials that are required by apps and tools that integrate with your AWS account. It’s best to avoid distributing regular IAM credentials, as these provide long-term access to the privileges they’re assigned.

With STS, you get to assign your app a locked-down credential that it can use to assume additional privileges. If you need to change or revoke those privileges, you can do so without having to supply new credentials to the application.

Identity federation scenarios

STS facilitates identity federation scenarios for AWS accounts. The mechanism allows users to log in to AWS through an external OIDC or SAML provider, such as Azure or Google, then receive access to existing AWS resources without having to create dedicated IAM credentials first.

To configure this workflow, you’ll need to register an IAM identity provider that sets up a trust relationship with the external platform. Users can then sign in with the provider to receive access to your AWS account via STS-issued credentials.

Cross-account and delegated access

STS also enables cross-account access sharing. This is designed for organizations that use multiple AWS accounts but want to maintain a central index of user identities in one of the accounts.

STS allows you to delegate temporary access to IAM users belonging to other accounts held by your organization. This avoids the need to set up dedicated IAM identities in each of the AWS accounts, which would be a management overhead that could cause security oversights.

How Does AWS STS Work?

There are five main steps involved in a successful STS transaction that allows a user to assume an IAM role.

Here’s how it works:

  1. The role is created. An AWS administrator creates an IAM role that includes the permissions the user will require.
  2. An administrator configures a trust policy for the target user and role. Once a trust policy has been created, the user can call the STS service to request credentials for that role. Without an applicable trust policy, STS will refuse to issue credentials for the role.
  3. When the role’s privileges are required, the user calls the STS API and requests to assume the role. STS validates the request by checking that an appropriate trust policy exists.
  4. STS dynamically generates a new set of credentials and issues them to the user’s application within an API response. The credentials are not stored against the user and will only be valid until they expire.
  5. The user calls the AWS API they need to interact with, this time supplying their temporary credentials. Access will be granted until the credentials expire.

Let’s see this workflow in action by setting up a demo that uses STS to temporarily acquire access to S3 storage buckets.

Example: Using AWS STS to Assume a Role

We will use the AWS CLI for this tutorial. Before continuing, ensure you’ve got the CLI installed and connected to your AWS account.

1. Create an S3 bucket

First, create an AWS bucket to use for the tutorial. We’re calling ours spacelift-sts-demo:

$ aws s3api create-bucket --bucket spacelift-sts-demo
{
    "Location": "/spacelift-sts-demo"
}

2. Create an IAM user

Next, create a new IAM user for the tutorial. This is the user who’ll use STS to gain temporary access to S3.

Our user is called spacelift-demo:

$ aws iam create-user --user-name spacelift-demo
{
    "User": {
        "Path": "/",
        "UserName": "spacelift-demo",
        "UserId": "AIDAWFS5FVUBOP6S5UXMH",
        "Arn": "arn:aws:iam::424323427586:user/spacelift-demo",
        "CreateDate": "2023-05-18T16:54:03+00:00"
    }
}

Note down the Arn value that’s displayed in the response – you’ll need it later in this guide, as it’s the user’s unique AWS ID.

Next, create an access key for your new IAM user, which will allow you to authenticate as that identity:

$ aws iam create-access-key --user-name spacelift-demo
{
    "AccessKey": {
        "UserName": "spacelift-demo",
        "AccessKeyId": "REDACTED",
        "Status": "Active",
        "SecretAccessKey": "REDACTED",
        "CreateDate": "2023-05-18T16:55:26+00:00"
    }
}

Note down the AccessKeyId and SecretAccessKey values displayed in the response.

Next, open a new terminal window and change the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_TOKEN environment variables to the values displayed in the previous access key generation response.

This will configure the AWS CLI to authenticate as your new IAM user:

$ export AWS_ACCESS_KEY_ID=<your_access_key_id>
$ export AWS_SECRET_ACCESS_KEY=<your_secret_access_key>

Try to list the S3 buckets available to the account:

$ aws s3api list-buckets
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

Access denied! The brand new IAM user doesn’t have any roles or privileges, so it can’t perform the action.

Let’s set up STS and use it to acquire short-term access rights.

3. Allow the user to assume roles with STS

The ability for a user to assume roles through STS is itself gated on an IAM permission – sts:AssumeRole. Consequently, the demo user must be assigned a role that includes this permission.

Create an IAM policy document JSON file that defines the role:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "*"
        }
    ]
}

Save the file as sts-role.json in your working directory, then use the AWS CLI to add it to your account:

$ aws iam create-policy --policy-name sts-assume-roles --policy-document file://sts-role.json
{
    "Policy": {
        "PolicyName": "sts-assume-roles",
        "PolicyId": "ANPAWFS5FVUBOEBA2NDNG",
        "Arn": "arn:aws:iam::424323427586:policy/sts-assume-roles",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2023-05-18T17:11:56+00:00",
        "UpdateDate": "2023-05-18T17:11:56+00:00"
    }
}

Copy the value of the Arn field shown in the response, then substitute it into the following command. This will assign the role to your IAM user, allowing the identity to assume other roles through STS.

$ aws iam attach-user-policy --user-name <your_iam_user_name> --policy-arn "<your_policy_arn>"

4. Create the role that your user will assume

Next, create an IAM role that gives users read-only access to S3 data. This is the role your user will assume through STS.

Copy the following JSON and save it to s3-readonly-role.json:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": "*"
        }
    ]
}

Use the AWS CLI to create the policy:

$ aws iam create-policy --policy-name s3-readonly --policy-document file://s3-readonly-role.json
{
    "Policy": {
        "PolicyName": "s3-readonly",
        "PolicyId": "ANPAWFS5FVUBHQHFGVFVH",
        "Arn": "arn:aws:iam::424323427586:policy/s3-readonly",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2023-05-18T17:06:28+00:00",
        "UpdateDate": "2023-05-18T17:06:28+00:00"
    }
}

Once again, note down the Arn that’s displayed, as you’ll need it in the next step.

5. Create a trust policy that allows your user to assume the role

The next step is to set up an IAM trust policy that connects your IAM user and your role. The trust policy will allow the user to assume the rule through STS.

Copy the following policy file to user-trust-policy.json, then replace the Principal.AWS value with the ARN of your IAM user, which you noted in Step 1:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Principal": {
            "AWS": "<your_iam_user_arn>"
        },
        "Action": "sts:AssumeRole"
    }
}

Then add the trust policy to your account:

$ aws iam create-role --role-name user-trust-policy-role --assume-role-policy-document file://user-trust-policy.json
{
    "Role": {
        "Path": "/",
        "RoleName": "user-trust-policy-role",
        "RoleId": "AROAWFS5FVUBHSJJPNHR3",
        "Arn": "arn:aws:iam::424323427586:role/user-trust-policy-role",
        "CreateDate": "2023-05-18T19:12:14+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::424323427586:user/spacelift-demo"
                },
                "Action": "sts:AssumeRole"
            }
        }
    }
}

Creating this trust policy role allows the specific user identified in the Principal field to assume the roles it refers to.

However, we haven’t connected any roles to the trust policy yet – run the following command to achieve this after substituting the value of the --policy-arn flag with the ARN of your s3-readonly role:

$ aws iam attach-role-policy --role-name user-trust-policy-role --policy-arn "<your_s3_role_arn>"

The role that permits access to the S3 buckets is now attached to the trust policy role. In turn, the trust policy is associated with the IAM user you created. As a result, that user can now use STS to assume the S3 role.

6. Using STS to assume the role

Switch back to your second terminal, where you’re authenticated as the IAM user.

Run the following command to assume the role through STS. You must input the ARN of the trust policy role created in the previous step, as well as a session name that uniquely identifies this use of the assumed role:

$ aws sts assume-role --role-arn "<your_trust_policy_role_arn>" --role-session-name demo-session
{
    "Credentials": {
        "AccessKeyId": "ASIAWFS5FVUBHPU6KX55",
        "SecretAccessKey": "gO5gN32bdvjPnzZubC9hwYSx/JLJVfzdTLA11V0D",
        "SessionToken": "FwoGZXIvYXdzEE0aDGYneSNgwccSdEr9UCKwAU90LpGn8qMc5o2x67ZpNuql04Ym47CP3iUEYSwxn3IWG9tF8JohsZkYllId46MOWxarw/dkGQO9oZtuibNKf3fxLw/fzgLCWFsoFCymNrbIVKp5jU78RhgM4FV3K5sRlo4c+rQx90BegoARu31VxKK193iBqrH+V51FTryAzrnO7tmfNFzZDX3rN0Tad7aa91ByX1MqgrbPXOuCcn+e8xHrYcnQg5YbtA7O0/DKJ8xkKNLzmaMGMi0RmfuaQTgfMeJgkC0TEnFj9g5iy53hSeS68sUkdRdx6lmrrCQCz6Fv+eZFioc=",
        "Expiration": "2023-05-18T20:17:38+00:00"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAWFS5FVUBHSJJPNHR3:demo-session",
        "Arn": "arn:aws:sts::424323427586:assumed-role/user-trust-policy-role/demo-session"
    }
}

The response data shows that STS has provided a new set of credentials with a default lifetime of 1 day. To generate credentials with a specific lifetime, include the --duration-seconds flag when you run the sts assume-role command:

# Expires after 5 minutes
$ aws sts assume-role --role-arn "<your_trust_policy_role_arn>" --role-session-name demo-session --duration-seconds 300

Next, update your shell environment variables to make the AWS CLI now authenticate with your temporary STS credentials. Unlike regular credentials, you must also supply the session token included in the STS response, which provides an additional layer of security protection:

$ export AWS_ACCESS_KEY_ID=ASIAWFS5FVUBHPU6KX55
$ export AWS_SECRET_ACCESS_KEY=gO5gN32bdvjPnzZubC9hwYSx...
$ export AWS_SESSION_TOKEN=FwoGZXIvYXdzEE0aDGYneSNgwccS...

Finally, you should now be able to successfully list your S3 buckets while authenticated with your temporary credentials:

$ aws s3api list-buckets
{
    "Buckets": [
        {
            "Name": "spacelift-sts-demo",
            "CreationDate": "2023-05-18T16:52:05+00:00"
        }
    ]
}

You’ve used STS to assume a role that grants the privileges to interact with S3! If you check the identity that’s presented to AWS, it will report the temporary user ID assigned to your STS session:

$ aws sts get-caller-identity
{
    "UserId": "AROAWFS5FVUBHSJJPNHR3:demo-session",
    "Account": "424323427586",
    "Arn": "arn:aws:sts::424323427586:assumed-role/user-trust-policy-role/demo-session"
}

Key Points

AWS STS provides controlled short-term access to privileged roles, without requiring the use of dedicated IAM identities. With STS, you can safely assume a role to access sensitive resources. Your access will automatically expire, and no credentials will be stored.

STS is also used to integrate tools and services which require temporary access to your AWS account. Spacelift can integrate with STS to automatically assume IAM roles for your Spacelift runs and tasks, facilitating the use of authenticated AWS sessions without any manual configuration.

Here you can learn more about self-hosting Spacelift in AWS, to ensure your organization’s compliance, control ingress, egress, internal traffic, and certificates, and have the flexibility to run it within GovCloud. You can also see Spacelift integration with AWS, with our Cloud Integrations section and our update to support account-level AWS integrations.

The Most Flexible CI/CD Automation Tool

Spacelift is an alternative to using homegrown solutions on top of a generic CI. It helps overcome common state management issues and adds several must-have capabilities for infrastructure management.

Start free trial

The Practitioner’s Guide to Scaling Infrastructure as Code

Transform your IaC management to scale

securely, efficiently, and productively

into the future.

ebook global banner
Share your data and download the guide