Credential management is a top concern on the list of security best practices. If there are multiple AWS accounts within the same organization and some users need access to data from other AWS accounts, it may not be easy to enforce password policy or implement keys rotation and set up various other authentication methods.
For example: you have a production environment and multiple images stored in the AWS S3. The testing account wants to replicate the same data for test simulation. How would they access data from the production account? Managing credentials and providing access to various AWS accounts and users is a challenging and complex task.
It may be even more difficult with additional demands like apps accessing the AWS API for developers requiring temporary access to the production environment or third party services providers’ staff and apps.
In this article, we will discuss how to manage multiple AWS accounts securely with cross-account IAM roles, and also review how to use a role to delegate access.
A Cross-account IAM Role is used to define access to resources in a single account, but it isn’t restricted to users in a single account. For example: The EC2 servers in your staging environment can safely get access to an S3 bucket in production by using a properly defined role to do so. Cross-account Role is the right tool to comply with best practices and simplify the credential management, as it gets rid of the need for credential management for third parties.
We will simulate a case where we use a role in Production Account S3 bucket to the users that are in Staging AWS Account.
You’ll share resources of one account with users in a different account. By setting up cross-account access this way, you don’t need to create individual IAM users in each account, and users don’t have to sign out of one account and sign into another in order to access resources that are in different AWS accounts. After configuring the role, you’ll see how to use the role from the AWS Management Console, the AWS CLI, and the API.
Here is a quick walk through of tasks that we will perform:
Stage 1 – Create an S3 Bucket and Roles
First, you use the AWS Management Console to establish trust between the Production Account and the Staging Account by creating an IAM role named StageRole. When you create the role, you define the Staging Account as a trusted entity and specify a permissions policy that allows trusted users to update the production-test-bucket-101.
Stage 2 – Grant Access to the Role
In this step of the tutorial, you modify the IAM bucket policy so that users from Staging Account can access the S3 bucket using StageRole.
Stage 3 – Test Access by Switching Roles
Finally, as a StageAdmin user on Staging Account, you use the StageRole to gain access to production-test-bucket-101 bucket in the Production Account. You’ll see how to access the role through the AWS CLI.
Step-by-step Guide to Provide Cross-Account Access
- Two separate AWS accounts that you can use: one to represent the Staging Account, and one to represent the Production Account
- Production and Staging Account ID and Canonical User ID
- Login to Production/Staging Account and from the My Account/Console drop-down menu, select Security Credentials
- Click Account Identifiers and note down the AWS Account ID and the Canonical User ID. (You will need the Account ID and the Canonical User ID while creating bucket policy further)
- Two users with administrator privileges
- Create ProdAdmin user in Production environment
- Grant user ProdAdmin privileges by attaching AdministratorAccess policy in IAM
- Repeat the preceding step to create administrator StageAdmin user in Staging Account as well
- Setup AWS CLI with Administrator user ProdAdmin and StageAdmin for both Staging and Production Account
STAGE 1 : Create the S3 Bucket and Role
Setup Production Account
- Create a bucket in S3
- Add bucket policy to grant access to Staging Account
- Copy paste this code in Bucket Policy
“Sid”: “Grant permissions to Staging Account”,
- Before creating the role, prepare the policy that defines the permissions that the role requires. Attach this policy to the role at a later step.
- Copy the following access policy and paste it into the Policy Document field
- Create role for Production environment
- In the IAM console, create an IAM role (“StageRole”) that grants Staging Account permission to assume the role
- Under Select Role Type, select Role for Cross-Account Access, and then enter the Staging Account account ID
- You will be asked for an Account ID where you can enter Staging AWS Account ID and proceed further
- Next, select the bucket policy you created in the earlier step and complete the step by clicking onto Create Role
STAGE 2 : Grant Access to the Role
Setup Staging Account
- Create a User StageAdmin and delegate permission to assume role StageRole created in Production Account
Note: You will need StageAdmin credentials to assume the StageRole role
- • Create an inline policy for the StageAdmin IAM user to delegate the sts:AssumeRole permission to StageAdmin on the StageRole role in Production account
- o Click the username StageAdmin
- o On the user details page, select the Permissions tab and then expand Click on Add Inline Policies
- Copy the following policy into the Custom Policy Document field and save it
STAGE 3 : Test Access by Switching Roles
Access objects in the Production S3 bucket from Staging Account
- In order to do this, you will need an Amazon EC2 instance with AWS CLI configured for user StageAdmin
- Once that is done, you can now fetch temporary credentials to access production-test-bucket-101 S3 bucket
- Execute the following command by providing Production Account ID
aws sts assume-role –role-arn arn:aws:iam::ProductionAccount-ID:role/StageRole –profile StagingAccountAdmin –role-session-name test
In response, the AWS Security Token Service (STS) returns temporary security credentials (access key ID, secret access key, and a security token).
- Save the temporary security credentials in the AWS CLI config file under the TempCred profile
aws_access_key_id = temp-access-key-ID
aws_secret_access_key = temp-secret-access-key
aws_security_token = security-token
region = us-west-2
Once you’ve done this, you can access files in Production S3 bucket.
For example, the command specifies the head-object API to retrieve object metadata for the Sunset.jpg object.
aws s3api get-object –bucket production-test-bucket-101 –key Sunset.jpg SunsetStage.jpg –profile TempCred
You can try different access as well, by referring to the AWS CLI documentation.
An Alternative Method : Resource-based Policies
You can also grant cross-account access to your resources with Resource-based policies. To do this, you attach a policy directly to the resource that you want to share, instead of using a role as a proxy. The resource that you want to share must support resource-based policies.
Cross-account access with a resource-based policy has an advantage over a role. With a resource that is accessed through a resource-based policy, the user still works in the trusted account and does not have to give up her user permissions in place of the role permissions. In other words, the user continues to have access to resources in the trusted account at the same time as she has access to the resource in the trusting account. This is useful for tasks such as copying information to or from the shared resource in the other account.
A Resource-based policy is much simpler to configure, as compared to IAM Roles; you can grant access to resources simply by attaching a resource-based policy specifying who (in the form of a list of AWS account ID numbers) can access that resource. The disadvantage of resourced based policy is that it does not support all services. Only a few of the AWS services support resource-based policies, such as the Amazon S3 buckets, Amazon Simple Notification Service (Amazon SNS) and Amazon Simple Queue Service (Amazon SQS).
On the other hand, Cross-account IAM Roles are attached to a user; they are complex to configure, but are supported by all the services of AWS, hence you can create a role with permission to access objects, and grant another AWS account the permission to assume the role temporarily enabling it to access objects.