AWSHow-To & HardeningRetrospectives

How to Use S3 Bucket Policies and Access Points to Enforce Least Privilege

By OnCloudSec Research Team · Published Oct 6, 2026 · 1 min read

Retrospective: this article looks back at events from July 2017, written in 2026 with the benefit of hindsight.

Bucket policies decide who can access data in Amazon S3. Written loosely, they leak data; written tightly, they make many attacks impossible. Here is how to write S3 bucket policies and access points that enforce least privilege.

Principles

  • Grant access to specific IAM roles, not users or whole accounts.
  • Allow only the actions needed (for example s3:GetObject, not s3:*).
  • Scope to specific prefixes where possible.
  • Add explicit denies for anything that must never happen.

Step 1: Deny unencrypted transport

Require TLS for every request:

{
  "Sid": "DenyInsecureTransport",
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": ["arn:aws:s3:::example-bucket", "arn:aws:s3:::example-bucket/*"],
  "Condition": {"Bool": {"aws:SecureTransport": "false"}}
}

Step 2: Restrict access to your organization

Use the aws:PrincipalOrgID condition to deny any principal outside your AWS Organization, so a mistaken grant to another account has no effect.

Step 3: Restrict network paths

For internal data, require access through your VPC endpoint with the aws:SourceVpce condition.

Step 4: Use access points for shared buckets

When several applications or teams share a bucket, create an S3 access point for each, with its own policy limited to its prefix. Delegate access control from the bucket policy to access points owned by your account.

Step 5: Disable ACLs

Set Object Ownership to "Bucket owner enforced" so ACLs no longer apply and policies are the only access mechanism.

Verify

Use IAM Access Analyzer policy validation and external access findings to confirm the result matches your intent.

s3 bucket policy least privilegeVerizon S3 exposure2017

More on this story