IAM tutorial: Delegate access across AWS accounts using IAM roles
Important
IAM best practices recommend that you require human users to use federation with an identity provider to access AWS using temporary credentials instead of using IAM users with long-term credentials. We recommend that you only use IAM users for specific use cases not supported by federated users.
This tutorial teaches you how to use a role to delegate access to resources in different AWS accounts called Destination and Originating. You share resources in one account with users in a different account. By setting up cross-account access in this way, you don't have to create individual IAM users in each account. In addition, users don't have to sign out of one account and sign in to another account to access resources in different AWS accounts. After configuring the role, you see how to use the role from the AWS Management Console, the AWS CLI, and the API.
In this tutorial, the Destination account manages
application data accessed by different applications and teams. In each account, you store
application information in Amazon S3 buckets. You manage IAM users in the Originating account, where you have two IAM user roles: Developers and Analysts. Developers and
Analysts use the Originating account to generate data shared
by multiple microservices. Both roles have permissions to work in the Originating account and
access resources there. From time to time, a developer must update the shared data in the
Destination account. The developers store this data in an
Amazon S3 bucket called amzn-s3-demo-bucket-shared-container
.
At the end of this tutorial, you have the following:
-
Users in the Originating account (the trusted account) allowed to assume a specific role in the Destination account.
-
A role in the Destination account (the trusting account) allowed to access a specific Amazon S3 bucket.
-
The
amzn-s3-demo-bucket-shared-container
bucket in the Destination account.
Developers can use the role in the AWS Management Console to access the
amzn-s3-demo-bucket-shared-container
bucket in the Destination account. They can also access the bucket by using API calls
authenticated by temporary credentials provided by the role. Similar attempts by an Analyst to
use the role fail.
This workflow has three basic steps:
- Create a role in the Destination Account
-
First, you use the AWS Management Console to establish trust between the Destination account (ID number 999999999999) and the Originating account (ID number 111111111111). You start by creating an IAM role named UpdateData. When you create the role, you define the Originating account as a trusted entity and specify a permissions policy that allows trusted users to update the
amzn-s3-demo-bucket-shared-container
bucket. - Grant access to the role
-
In this section, you modify the role policy to deny Analysts access to the
UpdateData
role. Because Analysts have PowerUser access in this scenario, and you must explicitly deny the ability to use the role. - Test access by switching roles
-
Finally, as a Developer, you use the
UpdateData
role to update theamzn-s3-demo-bucket-shared-container
bucket in the Destination account. You see how to access the role through the AWS console, the AWS CLI, and the API.
Considerations
Before you use IAM roles to delegate resource access across AWS accounts, it's important to consider the following:
-
You cannot switch to a role when you sign in as the AWS account root user.
-
IAM roles and resource-based policies delegate access across accounts only within a single partition. For example, assume that you have an account in US West (N. California) in the standard
aws
partition. You also have an account in China (Beijing) in theaws-cn
partition. You can't use an Amazon S3 resource-based policy in your account in China (Beijing) to allow access for users in your standardaws
account. -
You can use AWS IAM Identity Center to facilitate single sign-on (SSO) for external AWS accounts (accounts outside your AWS Organizations) using Security Assertion Markup Language (SAML). For details, see Integrate external AWS accounts into AWS IAM Identity Center for central access management with independent billing using SAML 2.0
-
You can associate roles to AWS resources like Amazon EC2 instances or AWS Lambda functions. For details, see Create a role to delegate permissions to an AWS service.
-
If you want to have an application assume a role in another AWS account, you can use the AWS SDK for cross account role assumption. For more information, see Authentication and access in the AWS SDKs and Tools Reference Guide.
-
Switching roles using the AWS Management Console only works with accounts that do not require an
ExternalId
. For example, assume that you grant access to your account to a third party and require anExternalId
in aCondition
element in your permissions policy. In that case, the third party can access your account only by using the AWS API or a command line tool. The third party cannot use the console because it must supply a value forExternalId
. For more information about this scenario, see Access to AWS accounts owned by third parties, and How to enable cross account access to the AWS Management Consolein the AWS Security Blog.
Prerequisites
This tutorial assumes that you have the following already in place:
-
Two separate AWS accounts that you can use, one to represent the Originating account, and one to represent the Destination account.
-
Users and roles in the Originating account created and configured as follows:
Job title User Permissions Developer David Both users can sign in and use the AWS Management Console in the Originating account. Analyst Jane -
You do not need to create any users in the Destination account.
-
An Amazon S3 bucket created in the Destination account. You can call it
amzn-s3-demo-bucket-shared-container
in this tutorial, but because S3 bucket names must be globally unique, you must use a bucket with a different name.
Create a role in the Destination Account
You can allow users from one AWS account to access resources in another AWS account. In this tutorial, we'll do this by creating a role that defines who can access it and what permissions it grants to users that switch to it.
In this step of the tutorial, you create the role in the Destination account and specify the Originating account as a trusted entity. You also limit the role permissions
to only read and write access to the amzn-s3-demo-bucket-shared-container
bucket. Anyone granted permission to use the role can read and write to the
shared-container
bucket.
Before you can create a role, you need the account ID of the Originating AWS account. Each AWS account has a unique account ID identifier assigned to it.
To obtain the Originating AWS account ID
-
Sign in to the AWS Management Console as an administrator of the Originating account, and open the IAM console at https://console.aws.amazon.com/iam/
. -
In the IAM console, choose your user name on the navigation bar in the upper right. It typically looks like this:
username
@account_ID_number_or_alias
.For this scenario, you can use the account ID 111111111111 for the Originating account. However, you should use a valid account ID if you use this scenario in your test environment.
To create a role in the Destination account that can be used by the Originating account
-
Sign in to the AWS Management Console as an administrator of the Destination account, and open the IAM console.
-
Before creating the role, prepare the managed policy that defines the permissions for the role requirements. You attach this policy to the role in a later step.
You want to set read and write access to the
amzn-s3-demo-bucket-shared-container
bucket. Although AWS provides some Amazon S3 managed policies, there isn't one that provides read and write access to a single Amazon S3 bucket. You can create your own policy instead.In the navigation pane, choose Policies and then choose Create policy.
-
Choose the JSON tab and copy the text from the following JSON policy document. Paste this text into the JSON text box, replacing the resource ARN (
arn:aws:s3:::shared-container
) with the real one for your Amazon S3 bucket.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:ListAllMyBuckets", "Resource": "*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation" ], "Resource": "
arn:aws:s3:::amzn-s3-demo-bucket-shared-container
" }, { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::amzn-s3-demo-bucket-shared-container/*
" } ] }The
ListAllMyBuckets
action grants permission to list all buckets owned by the authenticated sender of the request. TheListBucket
permission allows users to view objects in theamzn-s3-demo-bucket-shared-container
bucket. TheGetObject
,PutObject
,DeleteObject
permissions allows users to view, update, and delete contents in theamzn-s3-demo-bucket-shared-container
bucket.Note
You can switch between the Visual and JSON editor options anytime. However, if you make changes or choose Next in the Visual editor, IAM might restructure your policy to optimize it for the visual editor. For more information, see Policy restructuring.
-
On the Review and create page, type
read-write-app-bucket
for the policy name. Review the permissions granted by your policy, and then choose Create policy to save your work.The new policy appears in the list of managed policies.
-
In the navigation pane, choose Roles and then choose Create role.
-
Choose the An AWS account role type.
-
For Account ID, type the Originating account ID.
This tutorial uses the example account ID
111111111111
for the Originating account. You should use a valid account ID. If you use an invalid account ID, such as111111111111
, IAM does not let you create the new role.For now you do not need to require an external ID, or require users to have multi-factor authentication (MFA) in order to assume the role. Leave these options unselected. For more information, see AWS Multi-factor authentication in IAM.
-
Choose Next: Permissions to set the permissions associated with the role.
-
Select the checkbox next to the policy that you created previously.
Tip
For Filter, choose Customer managed to filter the list to include only the policies that you created. This hides the AWS created policies and makes it much easier to find the one you need.
Then, choose Next.
-
(Optional) Add metadata to the role by attaching tags as key-value pairs. For more information about using tags in IAM, see Tags for AWS Identity and Access Management resources.
-
(Optional) For Description, enter a description for the new role.
-
After reviewing the role, choose Create role.
The
UpdateData
role appears in the list of roles.
Now you must obtain the Amazon Resource Name (ARN) of the role, a unique identifier for the role. When you modify the Developer's role in the Originating account, you specify the role ARN from the Destination account to grant or deny permissions.
To obtain the ARN for UpdateData
-
In the navigation pane of the IAM console, choose Roles.
-
In the list of roles, choose the
UpdateData
role. -
In the Summary section of the details pane, copy the Role ARN value.
The Destination account has an account ID of 999999999999, so the role ARN is
arn:aws:iam::999999999999:role/UpdateData
. Ensure that you provide the real AWS account ID for the Destination account.
At this point, you have established trust between the Destination and Originating accounts. You
did this by creating a role in the Destination account
that identifies the Originating account as a trusted
principal. You also defined what the users who switch to the UpdateData
role
can do.
Next, modify the permissions for the Developer role.
Grant access to the role
At this point, both Analysts and Developers have permissions that allow them to manage data in the Originating account. Use the following required steps for adding permissions to allow switching to the role.
To modify the Developers role to allow them to switch to the UpdateData role
-
Sign in as an administrator in the Originating account, and open the IAM console.
-
Choose Roles, and then choose Developers.
-
Choose the Permissions tab, choose Add permissions, and then choose Create inline policy.
-
Choose the JSON tab.
-
Add the following policy statement to allow the
AssumeRole
action on theUpdateData
role in the Destination account. Be sure that you changeDESTINATION-ACCOUNT-ID
in theResource
element to the actual AWS account ID of the Destination account.{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::
DESTINATION-ACCOUNT-ID
:role/UpdateData" } }The
Allow
effect explicitly allows the Developers group access to theUpdateData
role in the Destination account. Any developer who tries to access the role succeeds. -
Choose Review policy.
-
Type a Name such as
allow-assume-S3-role-in-destination
. -
Choose Create policy.
In most environments, you may not need the following procedure. If, however, you use
PowerUserAccess permissions, then some groups might already be able to switch roles. The
following procedure shows how to add a "Deny"
permission to the Analysts group
to ensure that they cannot assume the role. If you do not need this procedure in your
environment, then we recommend that you do not add it. "Deny"
permissions make
the overall permissions picture more complicated to manage and understand. Use
"Deny"
permissions only when you do not have a better option.
To modify the Analysts role to deny permission to assume the UpdateData
role
-
Choose Roles, and then choose Analysts.
-
Choose the Permissions tab, choose Add permissions, and then choose Create inline policy.
-
Choose the JSON tab.
-
Add the following policy statement to deny the
AssumeRole
action on theUpdateData
role. Be sure that you changeDESTINATION-ACCOUNT-ID
in theResource
element to the actual AWS account ID of the Destination account.{ "Version": "2012-10-17", "Statement": { "Effect": "Deny", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::
DESTINATION-ACCOUNT-ID
:role/UpdateData" } }The
Deny
effect explicitly denies the Analysts group access to theUpdateData
role in the Destination account. Any analyst who tries to access the role receives an access denied message. -
Choose Review policy.
-
Type a Name like
deny-assume-S3-role-in-destination
. -
Choose Create policy.
The Developers role now has permissions to use the UpdateData
role in the
Destination account. The Analysts role is prevented from using the UpdateData
role.
Next, you can see how David, a developer, can access the
amzn-s3-demo-bucket-shared-container
bucket in the Destination account.
David can access the bucket from the AWS Management Console, the AWS CLI, or the AWS API.
Test access by switching roles
After completing the first two steps of this tutorial, you have a role that grants access to a resource in the Destination account. You also have one role in the Originating account with users allowed to use that role. This step discusses how to test switching to that role from the AWS Management Console, the AWS CLI, and the AWS API.
To get help with common issues that you might encounter when working with IAM roles, see Troubleshoot IAM roles.
Switch roles (console)
If David needs to update data in the Destination
account in the AWS Management Console, he can do so by using Switch Role. He
specifies the account ID or alias and the role name, and his permissions immediately
switch to those permitted by the role. He can then use the console to work with the
amzn-s3-demo-bucket-shared-container
bucket, but cannot work with any
other resources in Destination. While David uses the
role, he also cannot make use of his power-user privileges in the Originating account. That's because only one set of permissions can be in
effect at a time.
IAM provides two ways that David can use to enter the Switch Role page:
-
David receives a link from their administrator that points to a predefined Switch Role configuration. The link is provided to the administrator on the final page of the Create role wizard or on the Role Summary page for a cross-account role. Choosing this link takes David to the Switch Role page with the Account ID and Role name fields already filled in. All David needs to do is choose Switch Roles.
-
The administrator does not send the link in email, but instead sends the Account ID number and Role Name values. To switch roles, David must manually enter the values. This is illustrated in the following procedure.
To assume a role
-
David signs into the AWS Management Console using his normal user in the Originating account.
-
They choose the link that the administrator emailed to them. This takes David to the Switch Role page with the account ID or alias and the role name information already filled in.
—or—
David chooses their name (the Identity menu) on the navigation bar, and then chooses Switch Roles.
If this is the first time that David tries to access the Switch Role page this way, he first lands on a first-run Switch Role page. This page provides additional information on how switching roles can permit users to manage resources across AWS accounts. David must choose Switch Role on this page to complete the rest of this procedure.
-
Next, in order to access the role, David must manually type the Destination account ID number (
999999999999
) and the role name (UpdateData
).Also, David wants to monitor which roles and associated permissions currently active in IAM. To keep track of this information, he types
Destination
in the Display Name text box, chooses the red color option, and then chooses Switch Role. -
David can now use the Amazon S3 console to work with the Amazon S3 bucket, or any other resource to which the
UpdateData
role has permissions. -
When done, David can return to their original permissions. To do that, they choose the Destination role display name on the navigation bar and then choose Back to David @ 111111111111.
-
The next time that David wants to switch roles and chooses the Identity menu in the navigation bar, he sees the Destination entry still there from last time. He can simply choose that entry to switch roles immediately without reentering the account ID and role name.
Switch roles (AWS CLI)
If David needs to work in the Destination
environment at the command line, he can do so by using the AWS CLIaws sts
assume-role
command and passes the role ARN to get temporary security
credentials for that role. He then configures those credentials in environment variables
so subsequent AWS CLI commands work using the role's permissions. While David uses the
role, he cannot use his power-user privileges in the Originating account, because only one set of permissions can be in effect
at a time.
Note that all access keys and tokens are examples only and cannot be used as shown. Replace with the appropriate values from your live environment.
To assume a role
-
David opens a command prompt window, and confirms that the AWS CLI client is working by running the command:
aws help
Note
David's default environment uses the
David
user credentials from his default profile that he created with theaws configure
command. For more information, see Configuring the AWS Command Line Interface in the AWS Command Line Interface User Guide. -
He begins the switch role process by running the following command to switch to the
UpdateData
role in the Destination account. He received the role ARN from the administrator that created the role. The command requires that you provide a session name as well, you can choose any text you like for that.aws sts assume-role --role-arn "arn:aws:iam::999999999999:role/UpdateData" --role-session-name "David-ProdUpdate"
David then sees the following in the output:
{ "Credentials": { "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", "SessionToken": "AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLE CvSRyh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDy EXAMPLE9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3Uuysg sKdEXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLEsnf87e NhyDHq6ikBQ==", "Expiration": "2014-12-11T23:08:07Z", "AccessKeyId": "AKIAIOSFODNN7EXAMPLE" } }
-
David sees the three pieces that they need in the Credentials section of the output.
-
AccessKeyId
-
SecretAccessKey
-
SessionToken
David needs to configure the AWS CLI environment to use these parameters in subsequent calls. For information about the various ways to configure your credentials, see Configuring the AWS Command Line Interface. You cannot use the
aws configure
command because it does not support capturing the session token. However, you can manually enter the information into a configuration file. Because these are temporary credentials with a relatively short expiration time, it is easiest to add them to the environment of your current command line session. -
-
To add the three values to the environment, David cuts and pastes the output of the previous step into the following commands. You might want to cut and paste into a simple text editor to address line wrap issues in the output of the session token. It must be added as a single long string, even though it is shown line wrapped here for clarity.
The following example shows commands given in the Windows environment, where "set" is the command to create an environment variable. On a Linux or macOS computer, you would use the command "export" instead. All other parts of the example are valid in all three environments.
For details on using Tools for Windows Powershell, see Switch to an IAM role (Tools for Windows PowerShell)
set AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE set AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY set AWS_SESSION_TOKEN=AQoDYXdzEGcaEXAMPLE2gsYULo+Im5ZEXAMPLEeYjs1M2FUIgIJx9tQqNMBEXAMPLECvS Ryh0FW7jEXAMPLEW+vE/7s1HRpXviG7b+qYf4nD00EXAMPLEmj4wxS04L/uZEXAMPLECihzFB5lTYLto9dyBgSDyEXA MPLEKEY9/g7QRUhZp4bqbEXAMPLENwGPyOj59pFA4lNKCIkVgkREXAMPLEjlzxQ7y52gekeVEXAMPLEDiB9ST3UusKd EXAMPLE1TVastU1A0SKFEXAMPLEiywCC/Cs8EXAMPLEpZgOs+6hz4AP4KEXAMPLERbASP+4eZScEXAMPLENhykxiHen DHq6ikBQ==
At this point, any following commands run under the permissions of the role identified by those credentials. In David's case, the
UpdateData
role.Important
You can save your frequently used configuration settings and credentials in files that are maintained by the AWS CLI. For more information, see Using existing configuration and credentials files in the AWS Command Line Interface User Guide.
-
Run the command to access the resources in the Destination account. In this example, David lists the contents of their S3 bucket with the following command.
aws s3 ls s3://shared-container
Because Amazon S3 bucket names are universally unique, there is no need to specify the account ID that owns the bucket. To access resources for other AWS services, refer to the AWS CLI documentation for that service for the commands and syntax required to reference its resources.
Using AssumeRole (AWS API)
When David needs to make an update to the Destination account from code, he makes an AssumeRole
call
to assume the UpdateData
role. The call returns temporary credentials that
he can use to access the amzn-s3-demo-bucket-shared-container
bucket in the
Destination account. With those credentials, David
can make API calls to update the amzn-s3-demo-bucket-shared-container
bucket. However, he cannot make API calls to access any other resources in the Destination account, even though he has power-user permissions
in the Originating account.
To assume a role
-
David calls
AssumeRole
as part of an application. They must specify theUpdateData
ARN:arn:aws:iam::999999999999:role/UpdateData
.The response from the
AssumeRole
call includes the temporary credentials with anAccessKeyId
and aSecretAccessKey
. It also includes anExpiration
time that indicates when the credentials expire and you must request new ones. When you set up role chaining with the AWS SDK, many credential providers automatically refresh credentials before they expire. -
With the temporary credentials, David makes an
s3:PutObject
call to update theamzn-s3-demo-bucket-shared-container
bucket. They would pass the credentials to the API call as theAuthParams
parameter. Because the temporary role credentials have only read and write access to theamzn-s3-demo-bucket-shared-container
bucket, any other actions in the Destination account are denied.
For a code example (using Python), see Switch to an IAM role (AWS API).
Additional resources
The following resources can help you learn more about topics in this tutorial:
-
For more information about IAM users, see IAM Identities .
-
For more information about Amazon S3 buckets, see Create a Bucket in the Amazon Simple Storage Service User Guide.
-
To learn whether principals in accounts outside of your zone of trust (trusted organization or account) have access to assume your roles, see What is IAM Access Analyzer?.
Summary
You have completed the cross-account API access tutorial. You created a role to
establish trust with another account and defined what actions trusted entities can take.
Then, you modified a role policy to control which IAM users can access the role. As a
result, developers from the Originating account can make
updates to the amzn-s3-demo-bucket-shared-container
bucket in the Destination account by using temporary credentials.