13.5 Block Public Access: The Four Settings Explained
Right, let’s talk about Block Public Access. This isn’t some optional “nice-to-have” feature you can ignore until later. This is the digital equivalent of remembering to lock your front door. I’ve seen more data breaches caused by a single misconfigured S3 bucket than I care to count. The BPA settings are AWS’s slightly panicked, but absolutely necessary, response to the endless parade of “oops, my customer database was on the open internet” headlines.
Think of it as a master kill switch, sitting on top of all your other bucket policies and ACLs. Its entire job is to say, “I don’t care what clever permissions you think you’ve set up downstream, nothing gets out publicly on my watch.” It’s the cynical, seasoned sysadmin who double-checks the work of the optimistic junior developer.
The Four Guardians at the Gate
There are four distinct settings, and you can apply them at two levels: the entire AWS account (which is a fantastic idea) or on individual buckets (for those special, weird cases). I’ll explain each one, but your default stance should be to turn all four on at the account level and sleep soundly at night.
BlockPublicAcls
This one is the first line of defense. It stops you (or anyone else with permissions) from even creating a public ACL on a bucket or an object. Remember ACLs? Those confusing legacy things we all pretend to understand? This setting makes them a non-issue for public access.
Why it matters: It prevents accidental publicity at the moment of creation. You can’t upload a file and accidentally set x-amz-grant-public-read if this is on. AWS will slap your hand and say “nope.”
IgnorePublicAcls
This is my favorite. It’s the cynical big brother to BlockPublicAcls. Let’s say some old bucket already has horrendous public ACLs set from five years ago, or someone somehow circumvented the first block. IgnorePublicAcls says, “I see those ACLs. I just choose to completely ignore them.” It effectively makes all public ACLs inert.
Why it matters: It neuters any existing “zombie” public ACLs you might have lurking in forgotten buckets. It’s a clean-up crew and a preventative measure all in one.
BlockPublicPolicy
This is where we get serious about modern configuration. This setting blocks the creation of a bucket policy that contains a public principal. We’re talking about the classic "Principal": "*" statement that is the cause of 99% of these breaches.
Example of what it blocks:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*", // This right here is the problem
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-embarrassing-bucket/*"
}
]
}
If you try to apply that policy while this setting is on, AWS will reject it. Thank goodness.
RestrictPublicBuckets
This is the most subtle one. It doesn’t block policy creation. Instead, it renders any existing public bucket policy ineffective. Even if a policy with "Principal": "*" is successfully attached to the bucket (maybe this setting was off when it was applied), this setting will make AWS enforce it as if the principal was not public. It’s like IgnorePublicAcls but for bucket policies.
The Pitfall: This is the one that tricks people. You can have a public-looking policy on your bucket, the AWS console might even show a scary “Public” warning, but if this setting is active, the policy is functionally private. It’s crucial to understand this so you don’t waste an hour debugging why your “public” bucket isn’t actually public.
How to Apply This Sanity
Do it at the account level. Now. Use the AWS CLI, the console, or Terraform—I don’t care, just do it. Here’s how with the CLI:
# Set the account-level Block Public Access settings to ON for all four settings
aws s3control put-public-access-block \
--account-id YOUR_ACCOUNT_ID \
--public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
For a specific bucket (maybe for a static website you intend to be public—you maniac):
# Apply to a single bucket
aws s3api put-public-access-block \
--bucket my-special-bucket \
--public-access-block-configuration BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
The crucial gotcha: Turning these off at the account level doesn’t automatically make a bucket public. It just allows the bucket’s own policies and ACLs to dictate access. You still have to explicitly write a policy that makes it public. The account-level setting is a blanket “no,” and the bucket-level setting can override it to a “maybe, if you insist.”
The bottom line? Enable all four at the account level. It’s the single most effective thing you can do to prevent a career-ending data leak. For the one bucket in a thousand that needs to be public, be explicit and surgical about it at the bucket level. Your future self, who isn’t frantically responding to a security incident, will thank you.