How can I provide cross-account access to objects that are in Amazon S3 buckets?

Last updated: 2020-05-07

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?

Short Description

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, use one of the following solutions to grant granular cross-account access to objects stored in S3 buckets. In the following examples, you grant access to users in another AWS account (Account B) so that users can manage objects that are in an S3 bucket owned by your account (Account A).

Note: Be sure to update the policy to include your account ID, bucket name, ARN, and so on.

Resolution

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 permission to download (GET Object) and upload (PUT Object) objects to and from a specific S3 bucket with this 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 this bucket policy 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 uploaded by other accounts. Enforcing the ACL with specific headers are then 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

Use object ACLs to manage permissions only 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. You can't apply ACLs to different objects that share the same prefixes.

Note: The bucket owner may not have full control over the objects uploaded by the ACL grantee. This is because the ACL doesn't support the condition for the S3 operation that the ACL authorizes.

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

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

2.    Configure the bucket ACL to include at least WRITE permission for Account B. This ensures 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. This ensures 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

Not all AWS services support resource-based policies. This means that 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, removing the need to manage multiple policies for S3 buckets. This method allows cross-account access to objects that are owned or uploaded by another AWS account or AWS services. 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. Then, 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:

{
  "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, 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. The IAM role is deemed as an API call made by a local IAM entity in Account A. A bucket policy or an ACL for cross-account access isn't required. For more information, see Amazon S3 Actions.