Cloud Computing 14 min read

Two Options to Resolve Cross-Account Amazon S3 Access Issues

This article examines the common “list‑but‑cannot‑download” problem in multi‑account Amazon S3 environments, explains why bucket‑owner and object‑owner separation causes permission failures, and presents two practical solutions—disabling ACLs or adjusting ACL settings—along with detailed bucket policies, IAM roles, and CLI commands to implement them.

Amazon Cloud Developers
Amazon Cloud Developers
Amazon Cloud Developers
Two Options to Resolve Cross-Account Amazon S3 Access Issues

Background

In multi‑account AWS setups, cross‑account access to Amazon S3 buckets is a frequent requirement for scenarios such as centralized log collection and shared data warehouses. When a bucket uses Access Control Lists (ACLs), ownership separation between the bucket owner and the object owner can lead to the “list‑but‑cannot‑download” issue.

S3 Permission Mechanisms

Amazon S3 provides three main permission models:

IAM policies : Identity‑based policies attached to users, groups, or roles.

Bucket policies : Resource‑based policies defined on the bucket to specify who can perform which actions.

ACLs : Legacy, resource‑level grants that list which AWS accounts or predefined groups have specific access types.

ACLs are considered legacy, lack fine‑grained control, and are not recommended for new designs.

Ownership Concepts

Bucket Owner : The AWS account that creates the bucket and pays for its storage and data transfer.

Object Owner : The AWS account that uploads an object; by default it retains full control of that object.

Challenge Illustrated

A real customer case involved three accounts:

Account A : Runs an Amazon EKS cluster with Flink jobs that need to read CloudTrail logs.

Account B : Holds the S3 bucket used for log storage.

Account C : The CloudTrail service account that writes logs into the bucket.

Because the bucket was created in 2022 with ACLs enabled, objects written by Account C became owned by Account C, while the bucket owner (Account B) could only list and delete those objects. Consequently, Account A could list the objects but could not download them.

Root‑Cause Analysis

The bucket was created with ACLs enabled.

Ownership separation: bucket owner = Account B, object owner = Account C.

Bucket policy granted Account A read permissions, but the object‑owner ACL prevented the download.

Solution 1 – Disable ACLs (Recommended)

Preparation steps:

Identify any workloads that still rely on ACLs.

Check the aclRequired field in S3 server‑access logs to confirm whether ACLs are needed.

Verify that no applications depend on specific ACL settings.

Implementation steps in Account B:

Open the S3 console and navigate to the target bucket.

Select the “Permissions” tab.

In the “Object ownership” section, choose “Edit”.

Select “ACLs disabled” and save.

Effect:

Objects uploaded after the change automatically become owned by the bucket owner (Account B).

Existing objects retain their original owner (Account C) but can be accessed by updating the bucket policy to grant Account A permissions for both new and old objects.

Solution 2 – Keep ACLs Enabled and Adjust Configuration

If disabling ACLs is not possible, apply the following:

Set the bucket’s object ownership to “Bucket owner preferred”.

Configure CloudTrail to use the bucket-owner-full-control ACL when writing objects, ensuring new objects are owned by Account B.

Note: Objects uploaded before the change remain owned by Account C and cannot be accessed by Account A through policy updates alone.

Bucket Policy Example

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountAccess",
      "Effect": "Allow",
      "Principal": {"AWS": "arn:aws:iam::ACCOUNT-A-ID:role/EKS-SERVICE-ROLE-NAME"},
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": ["arn:aws:s3:::BUCKET-NAME", "arn:aws:s3:::BUCKET-NAME/*"]
    }
  ]
}

Replace ACCOUNT-A-ID, EKS-SERVICE-ROLE-NAME, and BUCKET-NAME with the actual values.

IAM Role Policy for Account A

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

Attach the policy using the AWS CLI:

aws iam put-role-policy --role-name EKS-SERVICE-ROLE-NAME --policy-name S3CrossAccountAccess --policy-document file://s3-cross-account-policy.json --profile account-a-profile

Verification

From an Amazon EKS pod, test the access:

aws s3 ls s3://BUCKET-NAME/
aws s3 cp s3://BUCKET-NAME/path/to/object local-file

Conclusion

Cross‑account access to S3 buckets with ACLs enabled introduces ownership‑related permission challenges. By either disabling ACLs (the recommended modern practice) or adjusting ACL configurations and CloudTrail settings, you can restore download capability and simplify permission management in a multi‑account AWS environment.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

AWSCross-AccountACLS3IAMBucket Policy
Amazon Cloud Developers
Written by

Amazon Cloud Developers

Official technical community of Amazon Cloud. Shares practical AI/ML, big data, database, modern app development, IoT content, offers comprehensive learning resources, hosts regular developer events, and continuously empowers developers.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.