I want to give another AWS account access to an object that is stored in an Amazon Simple Storage Service (Amazon S3) bucket. How can I provide cross-account access to Amazon S3 buckets?

Depending on your use case, use one of the following methods to grant cross-account access to objects that are stored in S3 buckets:

  • Resource-based policies and AWS Identity and Access Management (IAM) policies for programmatic-only access to S3 bucket objects
  • Resource-based Access Control List (ACL) and IAM policies for programmatic-only access to S3 bucket objects
  • Cross-account IAM roles for programmatic and console access to S3 bucket objects

Depending on the type of access that you want to provide, you can use one of the following solutions to grant granular cross-account access to objects stored in S3 buckets. In the following examples, you are granting access to users in another AWS account (Account B) so users can manage objects that are in an S3 bucket owned by your account (Account A).

Note: In the following example policies, be sure to update the policy to include your relevant account ID, bucket name, ARN, and so on.

Resource-based policies and IAM policies

Use bucket policies to manage cross-account control and audit the S3 object's permissions. If you apply a bucket policy at the bucket level, you can define who can access (Principal element), which objects they can access (Resource element), and how they can access (Action element). Applying a bucket policy at the bucket level allows you to define granular access to different objects inside the bucket by using multiple policies to control access. You can also review the bucket policy to see who can access objects in an S3 bucket. To use bucket policies to manage S3 bucket access, follow these steps:

1.    Create an S3 bucket in Account A.

2.    Create an IAM role or user in Account B.

3.    Give the IAM role or user in Account B—at a minimum—permission to download (GET Object) and upload (PUT Object) objects to and from a specific S3 bucket by attaching the following IAM policy. This policy also gives the IAM role or user in Account B permissions to call PUT Object acl to grant object permissions to the bucket owner:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
  "s3:PutObject",
  "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::AccountABucketName/*"
 
        }
    ]
}

Note: You can limit access to a specific bucket folder in Account A by defining the folder name in the resource element, such as "arn:aws:s3:::AccountABucketName/FolderName/*". For more information, see How can I use IAM policies to grant user-specific access to specific folders?

4.    Configure the bucket policy for Account A to grant permissions to the IAM role or user that you created in Account B. Use a bucket policy similar to the following to grant a user the permissions to GetObject and PutObject for objects in a bucket owned by Account A:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AccountB:user/AccountBUserName"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::AccountABucketName/*"
            ]
        }
    ]
}

Note: You can define a specific S3 bucket folder in the resource element to provide granular access for more limited access, such as "Resource": "arn:aws:s3:::AccountABucketName/FolderName/*". By using the s3:PutObject permission with a condition, the bucket owner gets full control over the objects that are uploaded by other accounts by enforcing the ACL with specific headers that are passed in the PutObject API call. For more information, see Granting s3:PutObject permission with a condition requiring the bucket owner to get full control.

Resource-based Access Control List (ACL) and IAM policies

Only use object ACLs to manage permissions for specific scenarios and only if ACLs meet your needs better than IAM and S3 bucket policies. For more information, see When to Use an ACL-based Access Policy (Bucket and Object ACLs). Amazon S3 ACLs allow users to define only the following permissions sets: READ, WRITE, READ_ACP, WRITE_ACP, and FULL_CONTROL. You can use only an AWS account or one of the predefined Amazon S3 groups as a grantee for the Amazon S3 ACL. When specifying email address or the canonical user ID for an AWS account, the ACL applies to all entities in the grantee AWS account. You can't use an ACL to restrict access to individual IAM users or roles, or apply ACLs to different objects that share the same prefixes. Furthermore, because the ACL doesn't support the condition for the S3 operation that the ACL authorizes, the bucket owner might not have full control over the objects uploaded by the ACL grantee (unless the bucket owner is included in the object ACL that is uploaded), and this can't be enforced using the Amazon S3 ACL.

To use bucket and object ACLs to manage S3 bucket access, follow these steps:

1.    Create an IAM role or user in Account B, and then grant that role or user permissions to perform required Amazon S3 operations. Users who call PutObject and GetObject need the permissions listed in Resource-based policies and IAM policies.

2.    Configure bucket ACL to include at least WRITE permission for Account B so that Account B IAM roles or users can upload objects (call PutObject API) to a bucket owned by Account A:

…
<AccessControlPolicy>
  <Owner>
    <ID> AccountACanonicalUserID </ID>
    <DisplayName> AccountADisplayName </DisplayName>
  </Owner>
  <AccessControlList>
…
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
        <ID> AccountBCanonicalUserID </ID>
        <DisplayName> AccountBDisplayName </DisplayName>
      </Grantee>
      <Permission> WRITE </Permission>
    </Grant>
    ...
  </AccessControlList>
</AccessControlPolicy>

Note: To find your CanonicalUserID, see Finding an AWS Account Canonical User ID.

3.    Configure object ACLs to include at least READ permission for Account B so that IAM roles or users in Account B can download an object (call GetObject API) from a bucket owned by Account A:

…
<AccessControlPolicy>
  <Owner>
    <ID> AccountACanonicalUserID </ID>
    <DisplayName> AccountADisplayName </DisplayName>
  </Owner>
  <AccessControlList>
…
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
        <ID> AccountBCanonicalUserID </ID>
        <DisplayName> AccountBDisplayName </DisplayName>
      </Grantee>
      <Permission> READ </Permission>
    </Grant>
    ...
  </AccessControlList>
</AccessControlPolicy>

ACL permissions vary based on which S3 resource, bucket, or object that an ACL is applied to. For more information, see Access Control List (ACL) Overview. You can configure bucket and object ACLs when you create your bucket or when you upload an object to an existing bucket. For more information, see Managing ACLs.

Cross-account IAM roles

Because not all AWS services support resource-based policies, you can use cross-account IAM roles to centralize permission management when providing cross-account access to multiple services. Using cross-account IAM roles simplifies provisioning cross-account access to S3 objects that are stored in multiple S3 buckets while removing the need to manage multiple policies for S3 buckets. Using this method allows cross-account access to objects that are owned or uploaded by another AWS account or AWS services, such as AWS CloudTrail logs and Amazon CloudFront logs. If you don't use cross-account IAM roles, the object ACL must be modified. For more information, see How Amazon S3 Authorizes a Request for an Object Operation.

To use cross-account IAM roles to manage S3 bucket access, follow these steps:

1.    Create an IAM role in Account A and grant the role permissions to perform required S3 operations. In the role's trust policy, grant a role or user from Account B permissions to assume the role in Account A by using a policy similar to the following:

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

The following access policy allows a user who has assumed this role to download and upload objects programmatically and using the Amazon S3 console. For more information about how to grant user-specific access to a specific folder, see How can I use IAM policies to grant user-specific access to specific folders?

Note: If only programmatic access is required, the first two statements in the following policy can be removed:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListAllMyBuckets"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:s3:::*"
            ]
        },
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetBucketLocation"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::AccountABucketName"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::AccountABucketName/*"
        }
    ]
}

2.    Grant an IAM role or user in Account B permissions to assume the IAM role that you created in Account A.

{
  "Version": "2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Action": "sts:AssumeRole",
    "Resource": "arn:aws:iam::AccountA:role/AccountARole"
  }
}

3.    From a role or user in Account B, assume the role in Account A programmatically so that IAM entities in Account B can perform required S3 operations. For more information, see Switching to a Role (Console).

Note: By assuming an IAM role in Account A, the Amazon S3 operation is determined by the access policy of the role and is deemed as an API call made by a local IAM entity in Account A, so a bucket policy or an ACL for cross-account access isn't required. For more information about available Amazon S3 API actions and additional permissions, see Specifying Permissions in a Policy.


Did this page help you? Yes | No

Back to the AWS Support Knowledge Center

Need help? Visit the AWS Support Center

Published: 2018-07-11