Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


title: “S3 Access Without Public Exposure” created: 2026-07-20 updated: 2026-07-20 type: knowledge tags:

  • aws
  • s3
  • security
  • iam
  • bucket-policy
  • best-practice
  • certification

S3 Access Without Public Exposure

What It Is

A pattern where you grant access to an S3 bucket exclusively through bucket policies with explicit principals, while keeping Block Public Access (BPA) fully enabled and ACLs disabled. No public exposure is needed.

Why It Matters

This is the AWS-recommended approach for S3 access control. It eliminates accidental data exposure while maintaining fine-grained access. Understanding this pattern is essential for certification exams and real-world architecture.

Key Concepts

What BPA Actually Blocks

BPA only blocks public access — meaning anonymous or Principal: "*" access. It does NOT block:

  • Access by a specific IAM role or user (identified ARN)
  • Cross-account access to a named principal
  • Access from AWS services (CloudFront OAC, Lambda, etc.)

The Ideal Combination

LayerSettingPurpose
BPAAll 4 settings ONSafety net — prevents any public access
ACLsDisabled (Bucket Owner Enforced)Eliminates legacy complexity
Bucket PolicyExplicit principals onlySingle source of truth for access

Why It Works

A bucket policy with a specific principal (ARN) is not considered “public” by AWS. BPA’s BlockPublicPolicy setting only rejects policies that use Principal: "*" or have conditions that effectively make them public.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/MyAppRole"
      },
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

→ BPA will not block this policy because the principal is identified, not anonymous.

BPA Behavior Matrix

Bucket Policy PrincipalBPA ONResult
"*" (everyone)ONBlocked by BlockPublicPolicy
"arn:aws:iam::123456:role/X" (specific role)ONAllowed — not public
"arn:aws:iam::999999:root" (cross-account)ONAllowed — identified principal
{"Service": "cloudfront.amazonaws.com"}ONAllowed — AWS service principal

Common Use Cases

  • EC2 to S3: bucket policy grants access to an EC2 instance role
  • Cross-account: bucket policy grants access to another AWS account’s role
  • CloudFront to S3: bucket policy grants access to CloudFront OAC
  • Lambda to S3: bucket policy grants access to Lambda execution role

Gotchas

  • Principal: "*" with a Condition (e.g., VPC endpoint) may still be considered public by BPA — test carefully
  • Account-level BPA overrides bucket-level settings — check both
  • Disabling BPA is not needed for IAM-based access — if someone says “disable BPA to grant access to a role”, that’s wrong
  • ACLs are legacy — prefer “Bucket Owner Enforced” object ownership to disable them entirely

See Also

  • [[s3-block-public-access]] — The four BPA settings explained
  • [[s3-bucket-policies]] — Policy structure and common patterns
  • [[iam-instance-profiles]] — EC2 roles for S3 access without credentials
  • [[aws-arns]] — ARN format for principals and resources
  • [[s3-access-control-lists]] — Why ACLs are legacy