How can I copy S3 objects from another AWS account?

Last updated: 2019-10-17

I want to copy Amazon Simple Storage Service (Amazon S3) objects to a bucket in another AWS account. Then, I want to be sure that the destination account owns the copied objects. How can I do that? 

Short Description

To be sure that a destination account owns an S3 object copied from another account, grant the destination account the permissions to perform the cross-account copy. Follow these steps to configure cross-account permissions to copy objects from a source bucket in Account A to a destination bucket in Account B:

1.    Attach a bucket policy to the source bucket in Account A.

2.    Attach an AWS Identity and Access Management (IAM) policy to a user or role in Account B.

3.    Use the IAM user or role in Account B to perform the cross-account copy.

By default, an S3 object is owned by the account that uploaded the object. That's why granting the destination account the permissions to perform the cross-account copy makes sure that the destination owns the copied objects. You can also change the ownership of an object by changing its access control list (ACL) to bucket-owner-full-control. However, object ACLs can be difficult to manage for multiple objects, so it's a best practice to grant programmatic cross-account permissions to the destination account.

Object ownership is important for managing permissions using a bucket policy. For a bucket policy to apply to an object in the bucket, the object must be owned by the account that owns the bucket. You can also manage object permissions using the object's ACL. However, object ACLs can be difficult to manage for multiple objects, so it's a best practice to use the bucket policy as a centralized method for setting permissions.

Resolution

Attach a bucket policy to the source bucket in Account A

1.    Get the AWS account ID number of Account B (destination account).

2.    From Account A, attach a bucket policy to the source bucket that allows Account B to get objects, similar to the following:

Important: For the value of Principal, replace 222222222222 with the AWS account ID of Account B.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DelegateS3Access",
            "Effect": "Allow",
            "Principal": {"AWS": "222222222222"},
            "Action": ["s3:ListBucket","s3:GetObject"],
            "Resource": [
                "arn:aws:s3:::awsexamplesourcebucket/*",
                "arn:aws:s3:::awsexamplesourcebucket"
            ]
        }
    ]
}

Attach an IAM policy to a user or role in Account B

1.    From Account B, create an IAM customer managed policy that allows an IAM user or role to copy objects from the source bucket in Account A to the destination bucket in Account B. The policy can be similar to the following example:

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

2.    Attach the customer managed policy to the IAM user or role that you want to use to copy objects between accounts.

Use the IAM user or role in Account B to perform the cross-account copy

After you set up the bucket policy and IAM policy, the IAM user or role in Account B can perform the copy from Account A to Account B. Then, Account B owns the copied objects.

To synchronize all content from a source bucket in Account A to a destination bucket in Account B, the IAM user or role in Account B can run the sync command using the AWS Command Line Interface (AWS CLI):

aws s3 sync s3://awsexamplesourcebucket s3://awsexampledestinationbucket