How can I copy S3 objects from another AWS account?

Last updated: 2021-05-19

I want to copy Amazon Simple Storage Service (Amazon S3) objects across AWS accounts. Then, I want to make sure that the destination account owns the copied objects. How can I do that?

Resolution

By default, an S3 object is owned by the account that uploaded the object. This is true even if the destination bucket is owned by another 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.

To make sure that a destination account owns an S3 object copied from another account, follow these steps:

1.    In the source account, create an AWS Identity and Access Management (IAM) customer managed policy that grants an IAM identity (user or role) proper permissions. The IAM user must have access to retrieve objects from the source bucket and put objects back into the destination bucket. You can use an IAM policy similar to the following:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::source-DOC-EXAMPLE-BUCKET",
                "arn:aws:s3:::source-DOC-EXAMPLE-BUCKET/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET",
                "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET/*"
            ]
        }
    ]
}

Note: This example IAM policy includes only the minimum required permissions for listing objects and copying objects across buckets in different accounts. You must customize the allowed S3 actions according to your use case. For example, if the user must copy objects that have object tags, then you must also grant permissions for s3:GetObjectTagging. If you experience an error, try performing these steps as an admin user.

2.    In the source account, attach the customer managed policy to the IAM identity that you want to use to copy objects to the destination bucket.

3.    In the destination account, set S3 Object Ownership on the destination bucket to bucket owner preferred. After you set S3 Object Ownership, new objects uploaded with the access control list (ACL) set to bucket-owner-full-control are automatically owned by the bucket's account.

4.    In the destination account, modify the bucket policy of the destination bucket to grant the source account permissions for uploading objects. Additionally, include a condition in the bucket policy that requires object uploads to set the ACL to bucket-owner-full-control. You can use a statement similar to the following:

Note: Replace destination-DOC-EXAMPLE-BUCKET with the name of the destination bucket. Then, replace arn:aws:iam::222222222222:user/Jane with the Amazon Resource Name (ARN) of the IAM identity from the source account.

{
    "Version": "2012-10-17",
    "Id": "Policy1611277539797",
    "Statement": [
        {
            "Sid": "Stmt1611277535086",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/Jane"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        },
        {
            "Sid": "Stmt1611277877767",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::222222222222:user/Jane"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::destination-DOC-EXAMPLE-BUCKET"
        }
    ]
}

Note: This example bucket policy includes only the minimum required permissions for uploading an object with the required ACL. You must customize the allowed S3 actions according to your use case. For example, if the user must copy objects that have object tags, you must also grant permissions for s3:GetObjectTagging

5.    After you configure the IAM policy and bucket policy, the IAM identity from the source account must upload objects to the destination bucket. Make sure that the ACL is set to bucket-owner-full-control. For example, the source IAM identity must run the cp AWS CLI command with the --acl option:

aws s3 cp s3://source-DOC-EXAMPLE-BUCKET/object.txt s3://destination-DOC-EXAMPLE-BUCKET/object.txt --acl bucket-owner-full-control

Note: If you receive errors when running AWS CLI commands, make sure that you’re using the most recent version of the AWS CLI.

With S3 Object Ownership set to bucket owner preferred, the objects uploaded with the bucket-owner-full-control ACL are automatically owned by the destination bucket's account.

Important: If your S3 bucket has default encryption with AWS Key Management Service (AWS KMS) enabled, then you must also modify the AWS KMS key permissions. For instructions, see My Amazon S3 bucket has default encryption using a custom AWS KMS key. How can I allow users to download from and upload to the bucket?