Example 4 - Bucket owner granting cross-account permission to objects it does not own
Topics
In this example scenario, you own a bucket and you have enabled other AWS accounts to upload objects. If you have applied the bucket owner enforced setting for S3 Object Ownership for the bucket, you will own all objects in the bucket, including objects written by another AWS account. This approach resolves the issue that objects are not owned by you, the bucket owner. Then, you can delegate permission to users in your own account or to other AWS accounts. Suppose the bucket owner enforced setting for S3 Object Ownership is not enabled. That is, your bucket can have objects that other AWS accounts own.
Now, suppose as a bucket owner, you need to grant cross-account permission on objects, regardless of who the owner is, to a user in another account. For example, that user could be a billing application that needs to access object metadata. There are two core issues:
-
The bucket owner has no permissions on those objects created by other AWS accounts. For the bucket owner to grant permissions on objects it doesn't own, the object owner must first grant permission to the bucket owner. The object owner is the AWS account that created the objects. The bucket owner can then delegate those permissions.
The bucket owner account can delegate permissions to users in its own account (see Example 3: Bucket owner granting permissions to objects it does not own). However, the bucket owner account can't delegate permissions to other AWS accounts because cross-account delegation isn't supported.
In this scenario, the bucket owner can create an AWS Identity and Access Management (IAM) role with permission to access objects Then, the bucket owner can grant another AWS account permission to assume the role, temporarily enabling it to access objects in the bucket.
Note
S3 Object Ownership is an Amazon S3 bucket-level setting that you can use to both control ownership of the objects that are uploaded to your bucket and to disable or enable ACLs. By default, Object Ownership is set to the Bucket owner enforced setting, and all ACLs are disabled. When ACLs are disabled, the bucket owner owns all the objects in the bucket and manages access to them exclusively by using access-management policies.
A majority of modern use cases in Amazon S3 no longer require the use of ACLs. We recommend that you keep ACLs disabled, except in unusual circumstances where you need to control access for each object individually. With ACLs disabled, you can use policies to control access to all objects in your bucket, regardless of who uploaded the objects to your bucket. For more information, see Controlling ownership of objects and disabling ACLs for your bucket.
Understanding cross-account permissions and using IAM roles
IAM roles enable several scenarios to delegate access to your resources, and cross-account access is one of the key scenarios. In this example, the bucket owner, Account A, uses an IAM role to temporarily delegate object access cross-account to users in another AWS account, Account C. Each IAM role that you create has the following two policies attached to it:
-
A trust policy identifying another AWS account that can assume the role.
-
An access policy defining what permissions—for example,
s3:GetObject
—are allowed when someone assumes the role. For a list of permissions you can specify in a policy, see Policy actions for Amazon S3.
The AWS account identified in the trust policy then grants its user permission to assume the role. The user can then do the following to access objects:
-
Assume the role and, in response, get temporary security credentials.
-
Using the temporary security credentials, access the objects in the bucket.
For more information about IAM roles, see IAM Roles in the IAM User Guide.
The following is a summary of the walkthrough steps:
-
Account A administrator user attaches a bucket policy granting Account B conditional permission to upload objects.
-
Account A administrator creates an IAM role, establishing trust with Account C, so users in that account can access Account A. The access policy attached to the role limits what user in Account C can do when the user accesses Account A.
-
Account B administrator uploads an object to the bucket owned by Account A, granting full-control permission to the bucket owner.
-
Account C administrator creates a user and attaches a user policy that allows the user to assume the role.
-
User in Account C first assumes the role, which returns the user temporary security credentials. Using those temporary credentials, the user then accesses objects in the bucket.
For this example, you need three accounts. The following table shows how we refer to these accounts and the administrator users in these accounts. In accordance with the IAM guidelines (see About using an administrator user to create resources and grant permissions), we don't use the AWS account root user credentials in this walkthrough. Instead, you create an administrator user in each account and use those credentials when creating resources and granting them permissions.
AWS account ID | Account referred to as | Administrator user in the account |
---|---|---|
|
Account A |
AccountAadmin |
|
Account B |
AccountBadmin |
|
Account C |
AccountCadmin |
Step 0: Preparing for the walkthrough
Note
You might want to open a text editor, and write down some of the information as you go through the steps. In particular, you will need account IDs, canonical user IDs, IAM user Sign-in URLs for each account to connect to the console, and Amazon Resource Names (ARNs) of the IAM users, and roles.
-
Make sure that you have three AWS accounts and each account has one administrator user as shown in the table in the preceding section.
-
Sign up for AWS accounts, as needed. We refer to these accounts as Account A, Account B, and Account C.
-
Using Account A credentials, sign in to the IAM console
and do the following to create an administrator user: -
Create user
AccountAadmin
and note its security credentials. For more information about adding users, see Creating an IAM user in your AWS account in the IAM User Guide. -
Grant administrator privileges to AccountAadmin by attaching a user policy giving full access. For instructions, see Managing IAM policies in the IAM User Guide.
-
In the IAM Console Dashboard, note the IAM User Sign-In URL. Users in this account must use this URL when signing in to the AWS Management Console. For more information, see Sign in to the AWS Management Console as an IAM user in the IAM User Guide.
-
-
Repeat the preceding step to create administrator users in Account B and Account C.
-
-
For Account C, note the canonical user ID.
When you create an IAM role in Account A, the trust policy grants Account C permission to assume the role by specifying the account ID. You can find account information as follows:
-
Use your AWS account ID or account alias, your IAM user name, and your password to sign in to the Amazon S3 console
. -
Choose the name of an Amazon S3 bucket to view the details about that bucket.
-
Choose the Permissions tab and then choose Access Control List.
-
In the Access for your AWS account section, in the Account column is a long identifier, such as
c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6
. This is your canonical user ID.
-
-
When creating a bucket policy, you will need the following information. Note these values:
-
Canonical user ID of Account A – When the Account A administrator grants conditional upload object permission to the Account B administrator, the condition specifies the canonical user ID of the Account A user that must get full-control of the objects.
Note
The canonical user ID is the Amazon S3–only concept. It is a 64-character obfuscated version of the account ID.
-
User ARN for Account B administrator – You can find the user ARN in the IAM Console
.You must select the user and find the user's ARN in the Summary tab. In the bucket policy, you grant
AccountBadmin
permission to upload objects and you specify the user using the ARN. Here's an example ARN value:arn:aws:iam::
AccountB-ID
:user/AccountBadmin
-
-
Set up either the AWS Command Line Interface (CLI) or the AWS Tools for Windows PowerShell. Make sure that you save administrator user credentials as follows:
-
If using the AWS CLI, create profiles,
AccountAadmin
andAccountBadmin
, in the config file. -
If using the AWS Tools for Windows PowerShell, make sure that you store credentials for the session as
AccountAadmin
andAccountBadmin
.
For instructions, see Setting up the tools for the walkthroughs.
-
Step 1: Do the account A tasks
In this example, Account A is the bucket owner. So user AccountAadmin in Account A will do the following:
-
Create a bucket.
-
Attach a bucket policy that grants the Account B administrator permission to upload objects.
-
Create an IAM role that grants Account C permission to assume the role so it can access objects in the bucket.
Step 1.1: Sign in to the AWS Management Console
Using the IAM user Sign-in URL for Account A, first sign in to the AWS Management Console as
AccountAadmin
user. This user will create a bucket and
attach a policy to it.
Step 1.2: Create a bucket and attach a bucket policy
In the Amazon S3 console, do the following:
-
Create a bucket. This exercise assumes the bucket name is
.amzn-s3-demo-bucket1
For instructions, see Creating a bucket.
-
Attach the following bucket policy. The policy grants conditional permission to the Account B administrator permission to upload objects.
Update the policy by providing your own values for
,amzn-s3-demo-bucket1
, and theAccountB-ID
.CanonicalUserId-of-AWSaccountA-BucketOwner
{ "Version": "2012-10-17", "Statement": [ { "Sid": "111", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::
AccountB-ID
:user/AccountBadmin" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::
/*" }, { "Sid": "112", "Effect": "Deny", "Principal": { "AWS": "arn:aws:iam::amzn-s3-demo-bucket1
AccountB-ID
:user/AccountBadmin" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::
/*", "Condition": { "StringNotEquals": { "s3:x-amz-grant-full-control": "id=amzn-s3-demo-bucket1
CanonicalUserId-of-AWSaccountA-BucketOwner
" } } } ] }
Step 1.3: Create an IAM role to allow Account C cross-account access in Account A
In the IAM Consoleexamplerole
) that grants Account C permission to assume
the role. Make sure that you are still signed in as the Account A administrator
because the role must be created in Account A.
-
Before creating the role, prepare the managed policy that defines the permissions that the role requires. You attach this policy to the role in a later step.
-
In the navigation pane on the left, choose Policies and then choose Create Policy.
-
Next to Create Your Own Policy, choose Select.
-
Enter
access-accountA-bucket
in the Policy Name field. -
Copy the following access policy and paste it into the Policy Document field. The access policy grants the role
s3:GetObject
permission so, when the Account C user assumes the role, it can only perform thes3:GetObject
operation.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::
/*" } ] }amzn-s3-demo-bucket1
-
Choose Create Policy.
The new policy appears in the list of managed policies.
-
-
In the navigation pane on the left, choose Roles and then choose Create New Role.
-
Under Select Role Type, select Role for Cross-Account Access, and then choose the Select button next to Provide access between AWS accounts you own.
-
Enter the Account C account ID.
For this walkthrough, you don't need to require users to have multi-factor authentication (MFA) to assume the role, so leave that option unselected.
-
Choose Next Step to set the permissions that will be associated with the role.
-
Select the checkbox next to the access-accountA-bucket policy that you created, and then choose Next Step.
The Review page appears so you can confirm the settings for the role before it's created. One very important item to note on this page is the link that you can send to your users who need to use this role. Users who use the link go straight to the Switch Role page with the Account ID and Role Name fields already filled in. You can also see this link later on the Role Summary page for any cross-account role.
-
Enter
examplerole
for the role name, and then choose Next Step. -
After reviewing the role, choose Create Role.
The
examplerole
role is displayed in the list of roles. -
Choose the role name
examplerole
. -
Select the Trust Relationships tab.
-
Choose Show policy document and verify the trust policy shown matches the following policy.
The following trust policy establishes trust with Account C, by allowing it the
sts:AssumeRole
action. For more information, see AssumeRole in the AWS Security Token Service API Reference.{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::
AccountC-ID
:root" }, "Action": "sts:AssumeRole" } ] } -
Note the Amazon Resource Name (ARN) of the
examplerole
role that you created.Later in the following steps, you attach a user policy to allow an IAM user to assume this role, and you identify the role by the ARN value.
Step 2: Do the Account B tasks
The example bucket owned by Account A needs objects owned by other accounts. In this step, the Account B administrator uploads an object using the command line tools.
-
Using the
put-object
AWS CLI command, upload an object to
.amzn-s3-demo-bucket1
aws s3api put-object --bucket
--keyamzn-s3-demo-bucket1
HappyFace.jpg
--bodyHappyFace.jpg
--grant-full-control id="canonicalUserId-ofTheBucketOwner
" --profileAccountBadmin
Note the following:
-
The
--Profile
parameter specifies theAccountBadmin
profile, so the object is owned by Account B. -
The parameter
grant-full-control
grants the bucket owner full-control permission on the object as required by the bucket policy. -
The
--body
parameter identifies the source file to upload. For example, if the file is on the C: drive of a Windows computer, you specifyc:\HappyFace.jpg
.
-
Step 3: Do the Account C tasks
In the preceding steps, Account A has already created a role, examplerole
,
establishing trust with Account C. This role allows users in Account C to access Account
A. In this step, the Account C administrator creates a user (Dave) and delegates him the
sts:AssumeRole
permission it received from Account A. This approach
allows Dave to assume the examplerole
and temporarily gain access to
Account A. The access policy that Account A attached to the role limits what Dave can do
when he accesses Account A—specifically, get objects in
.amzn-s3-demo-bucket1
Step 3.1: Create a user in Account C and delegate permission to assume examplerole
-
Using the IAM user sign-in URL for Account C, first sign in to the AWS Management Console as
AccountCadmin
user. -
In the IAM Console
, create a user, Dave. For step-by-step instructions, see Creating IAM users (AWS Management Console) in the IAM User Guide.
-
Note the Dave credentials. Dave will need these credentials to assume the
examplerole
role. -
Create an inline policy for the Dave IAM user to delegate the
sts:AssumeRole
permission to Dave on theexamplerole
role in Account A.In the navigation pane on the left, choose Users.
Choose the user name Dave.
On the user details page, select the Permissions tab and then expand the Inline Policies section.
Choose click here (or Create User Policy).
Choose Custom Policy, and then choose Select.
Enter a name for the policy in the Policy Name field.
Copy the following policy into the Policy Document field.
You must update the policy by providing the
.AccountA-ID
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["sts:AssumeRole"], "Resource": "arn:aws:iam::
AccountA-ID
:role/examplerole" } ] }Choose Apply Policy.
-
Save Dave's credentials to the config file of the AWS CLI by adding another profile,
AccountCDave
.[profile AccountCDave] aws_access_key_id =
UserDaveAccessKeyID
aws_secret_access_key =UserDaveSecretAccessKey
region = us-west-2
Step 3.2: Assume role (examplerole) and access objects
Now Dave can access objects in the bucket owned by Account A as follows:
-
Dave first assumes the
examplerole
using his own credentials. This will return temporary credentials. -
Using the temporary credentials, Dave will then access objects in Account A's bucket.
-
At the command prompt, run the following AWS CLI
assume-role
command using theAccountCDave
profile.You must update the ARN value in the command by providing the
whereAccountA-ID
examplerole
is defined.aws sts assume-role --role-arn arn:aws:iam::
AccountA-ID
:role/examplerole --profile AccountCDave --role-session-name testIn response, AWS Security Token Service (AWS STS) returns temporary security credentials (access key ID, secret access key, and a session token).
-
Save the temporary security credentials in the AWS CLI config file under the
TempCred
profile.[profile TempCred] aws_access_key_id =
temp-access-key-ID
aws_secret_access_key =temp-secret-access-key
aws_session_token =session-token
region = us-west-2 -
At the command prompt, run the following AWS CLI command to access objects using the temporary credentials. For example, the command specifies the head-object API to retrieve object metadata for the
HappyFace.jpg
object.aws s3api get-object --bucket
--keyamzn-s3-demo-bucket1
HappyFace.jpg
SaveFileAs.jpg
--profile TempCredBecause the access policy attached to
examplerole
allows the actions, Amazon S3 processes the request. You can try any other action on any other object in the bucket.If you try any other action—for example,
get-object-acl
—you will get permission denied because the role isn't allowed that action.aws s3api get-object-acl --bucket
--keyamzn-s3-demo-bucket1
HappyFace.jpg
--profile TempCredWe used user Dave to assume the role and access the object using temporary credentials. It could also be an application in Account C that accesses objects in
. The application can obtain temporary security credentials, and Account C can delegate the application permission to assumeamzn-s3-demo-bucket1
examplerole
.
Step 4: Clean up
-
After you're done testing, you can do the following to clean up:
-
Sign in to the AWS Management Console
using Account A credentials, and do the following: -
In the Amazon S3 console, remove the bucket policy attached to
. In the bucket Properties, delete the policy in the Permissions section.amzn-s3-demo-bucket1
-
If the bucket is created for this exercise, in the Amazon S3 console, delete the objects and then delete the bucket.
-
In the IAM Console
, remove the examplerole
you created in Account A. For step-by-step instructions, see Deleting an IAM user in the IAM User Guide. -
In the IAM Console
, remove the AccountAadmin user.
-
-
-
Sign in to the IAM Console
by using Account B credentials. Delete the user AccountBadmin. -
Sign in to the IAM Console
by using Account C credentials. Delete AccountCadmin and the user Dave.
Related resources
For more information that's related to this walkthrough, see the following resources in the IAM User Guide: