How can I add bucket-owner-full-control ACL to my objects in Amazon S3?

Last updated: 2021-12-10

I'm trying to add the bucket-owner-full-control access control list (ACL) to existing objects in Amazon Simple Storage Service (Amazon S3). How can I do this?

Short description

By default, in a cross-account scenario where other AWS accounts upload objects to your Amazon S3 bucket, the objects remain owned by the uploading account. When the bucket-owner-full-control ACL is added, the bucket owner has full control over any new objects that are written by other accounts.

If the object writer doesn't specify permissions for the destination account at an object ACL level, then the destination account can only delete objects.

When the bucket-owner-full-control ACL is added, the bucket owner has full control over any new objects that are written by other AWS accounts. This ACL is also required if the destination bucket has enabled S3 Object Ownership. When S3 Object Ownership is enabled, it updates the owner of new objects to the destination account.

Important: Granting cross-account access through bucket and object ACLs doesn't work for buckets that have S3 Object Ownership set to Bucket Owner Enforced. In most cases, ACLs aren't required to grant permissions to objects and buckets. Instead, use AWS Identity Access and Management (IAM) policies and S3 bucket policies to grant permissions to objects and buckets.

For existing objects, the object owner can grant the bucket owner full control of the object by updating the ACL of the object. When writing new objects, the bucket-owner-full-control ACL can be specified during a PUT or COPY operation.

For a user in Account A to grant bucket-owner-full-control canned ACL to objects in Account B, the following permissions must be granted:

  • Your IAM role or user in Account A must grant access to the bucket in Account B
  • Your bucket policy in Account B must grant access to the IAM role or user in Account A

You can grant bucket-owner-full-control access to objects in the following ways:

  • Canned ACLs
  • S3 Batch Operations (for large-scale batch operations)

Note: Make sure to review your VPC endpoint policy when you add the bucket-owner-full-control canned ACL to your S3 objects.

Resolution

Your IAM role or user in Account A must grant access to the bucket in Account B

Note: If the IAM user or role must update the object's ACL during the upload, then the user must have permissions for s3:PutObjectAcl in their IAM policy.

Create an IAM role in Account A. Grant the role/user permissions to perform PutObjectAcl on objects in Account B.

The following example policy grants the IAM role in Account A access to perform the GetObject, PutObject, and PutObjectAcl actions on objects in Account B:

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

Your bucket policy in Account B must grant access to the IAM user or role in Account A

Bucket policies can vary based on the canned ACL requirement during object uploads. For example, these two bucket policies grant access to the IAM user or role in Account A in different ways:

  • Policy 1: Allows access to the IAM user or role in Account A without requiring Amazon S3 PUT operations to include bucket-owner-full-control canned ACL.
  • Policy 2: Enforces all Amazon S3 PUT operations to include the bucket-owner-full-control canned ACL.

Policy 1: Allows access to the IAM user or role in Account A without requiring Amazon S3 PUT operations to include a bucket-owner-full-control canned ACL

To allow access to the IAM role in Account A without requiring an ACL, create a bucket policy in Account B (where objects are uploaded). This bucket policy must grant access to the IAM role or user in Account A. The following bucket policy allows the role in Account A to perform GetObject, PutObject, and PutObjectAcl actions on the objects in Account B:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::AccountA:role/AccountARole"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::AccountB-Bucket/*"
            ]
        }
    ]
}

Policy 2: Enforces all Amazon S3 PUT operations to include the bucket-owner-full-control canned ACL

The following bucket policy specifies that a user or role in Account A can upload objects to a bucket in Account B (where objects are to be uploaded). Uploads can be performed only when the object's ACL is set to "bucket-owner-full-control". For example:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Only allow writes to my bucket with bucket owner full control",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::AccountA:role/AccountARole"
                ]
            },
            "Action": [
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::AccountB-Bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

Note: When the preceding bucket policy is applied, the user must include the bucket-owner-full-control canned ACL during the PutObject operation. Otherwise, the operation fails, resulting in an Access Denied error. For information about how Amazon S3 enables object ownership of other AWS accounts, see Controlling ownership of uploaded objects using S3 Object Ownership.

Providing bucket-owner-full-control access

Canned ACLs

To grant bucket-owner-full-control canned ACL during an object upload, run the put-object command from Account A (object owner's account):

aws s3api put-object --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control

To grant bucket-owner-full-control canned ACL during a copy operation, run the copy-object command from Account A (object owner's account):

aws s3api copy-object --copy-source accountA-bucket/example.txt --key example.txt --bucket accountB-bucket --acl bucket-owner-full-control

Or, you can also run the cp command from Account A to grant the bucket-owner-full-control canned ACL:

aws s3 cp s3://accountA-bucket/test.txt s3://accountB-bucket/test2.txt --acl bucket-owner-full-control

For a copy operation of multiple objects, the object owner (Account A) can run the following command:

aws s3 cp s3://accountA-bucket/ s3://accountB-bucket/ --acl bucket-owner-full-control --recursive

If the object exists in a bucket in another account (Account B), then the object owner can grant the bucket owner access with this command:

aws s3api put-object-acl --bucket accountB-bucket --key example.txt --acl bucket-owner-full-control

S3 Batch Operations

To add bucket-owner-full-control canned ACL on a large number of Amazon S3 objects, use S3 Batch Operations. S3 Batch Operations can perform a single operation on a list of objects that you specify. You can even use S3 Batch Operations to set ACLs on a large number of objects. S3 Batch Operations support custom and canned ACLs that Amazon S3 provides with a predefined set of access permissions.

Note: The Replace access control list (ACL) operation replaces the Amazon S3 ACLs for every object that is listed in the manifest.

Additional consideration

Access allowed by a VPC endpoint policy

If an IAM role uploads objects to S3 using an instance that's routed through a virtual private cloud (VPC) endpoint, then check the VPC endpoint policy. For example, if an object is uploaded to S3 using an Amazon Elastic Compute Cloud (Amazon EC2) instance in a VPC, then that VPC endpoint policy must be reviewed. Make sure that your endpoint policy grants access to the PutObjectAcl action, like this:

{
    "Statement": [
        {
            "Sid": "Access-to-specific-bucket-only",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::AccountB-Bucket/*"
        }
    ]
}

Did this article help?


Do you need billing or technical support?