Blocking public access: the basics
What does "public" actually mean across AWS services?
"Public" in AWS is not one setting. It is a property that shows up in a dozen different shapes: an S3 bucket with a public policy or ACL, an EC2 instance with a public IPv4 address, an RDS instance marked publicly accessible, a snapshot shared with all accounts, an SNS topic or SQS queue whose resource policy allows a wildcard principal, an SSM document shared publicly, an EMR or MSK cluster on a public subnet. Each service expresses public reachability in its own way, but the risk is identical: data or control planes that anyone on the internet can reach.
AWS Security Hub turns each of these into its own control, which is why a single estate can fail twenty or more public-access checks at once. S3.1, S3.2, S3.8 and S3.19 cover buckets and access points; EC2.9 and EC2.15 cover public IPs; RDS.2 covers publicly accessible databases; SNS.4 and SQS.3 cover open resource policies; SSM.4 covers shared documents. They look like separate problems on the report, but they are one capability: close the doors you did not mean to leave open.
The good news is that most public exposure is drift, not intent. A subnet that auto-assigns public IPs, a snapshot copied with the wrong sharing flag, a bucket policy pasted with a wildcard principal. The job is to find every resource that is reachable from the public internet, decide which handful are public on purpose, route those through a controlled front door such as CloudFront or a load balancer, and then shut the rest.
In this lesson you will learn how AWS expresses public reachability across storage, compute, databases, snapshots and messaging, how to find every publicly exposed resource in an account, and how to close them down without breaking the few that are public on purpose. The Controls this lesson covers section lists every Security Hub control in this capability, each linking to a deep page with the exact check and a copy-and-paste fix.
The decade of leaked buckets
Between 2017 and 2020, before account-level Block Public Access existed and before AWS started enabling it by default, publicly exposed S3 buckets were the dominant source of cloud data leaks: Dow Jones, Verizon, Accenture, the US Department of Defense and Capital One among them. The pattern was always the same, a resource that could be made public was made public by accident. AWS has since shipped account-level and VPC-level public-access blocks, but every resource created before those defaults still needs to be checked and shut explicitly.
Finding public exposure across an estate
Priya is the security lead at a scale-up preparing for its first SOC 2 audit. Security Hub shows public-access failures spread across S3, EC2, RDS and SNS in three accounts that pre-date the team's current guardrails.
Rather than work the findings one by one, she starts by listing what is actually reachable from the internet, so she can separate genuine public services from drift before changing anything.
Start with the resources that expose data directly. Publicly accessible RDS instances are a common and high-impact finding.
Public databases are the highest-value target in this group. Fix these first.
How AWS decides a resource is publicdeep dive
Most public-access controls resolve to one of three mechanisms. The first is a network property: a public IPv4 address or a resource placed on a subnet that routes to an internet gateway, which is how EC2.9, EC2.15, RDS.2 and the EMR and MSK public-subnet checks work. The second is a resource policy with a wildcard principal, which is how SNS.4, SQS.3 and the public snapshot and SSM document checks work. The third is the S3 access model, where bucket and account Block Public Access settings sit in front of policies and ACLs.
Security Hub evaluates these through AWS Config, typically on a several-hour cycle, so a fix does not flip the finding to PASSED instantly. The control plane change itself is immediate, but the report catches up on the next evaluation. This matters when you are gathering audit evidence against a deadline.
The strongest controls are the account-wide and VPC-wide blocks: S3 account-level Block Public Access and VPC Block Public Access act as a backstop that no individual resource can override. Turning those on is the difference between checking that nothing is public today and guaranteeing that nothing can be made public tomorrow.
What is the impact of leaving resources public?
The direct impact is data exposure. A public database, bucket or queue is reachable by anyone who finds it, and internet-facing resources are found quickly by automated scanners. The overwhelming majority of public-exposure incidents were accidents, a resource that could be public was made public by a policy or flag nobody intended to set.
The second-order impact is blast radius. Every public IP and open endpoint is attack surface that has to be defended continuously. Closing public access shrinks that surface to the handful of front doors you actually operate, which are the ones you can monitor, rate-limit and put a WAF in front of.
On the compliance side, every modern framework, SOC 2, ISO 27001, HIPAA, PCI DSS and FedRAMP, expects evidence that data stores are not publicly accessible by default. A passing set of public-access controls across every account is the cheapest and most defensible artefact you can hand an auditor.
How do you close public access safely?
Work the capability as one loop rather than chasing individual findings. The order matters: find the legitimate exceptions before you start shutting things, so you do not take a live service offline.
1. Inventory everything reachable from the internet
Across services, list the resources that are public: buckets and access points, EC2 instances and subnets that assign public IPs, publicly accessible databases, shared snapshots, and SNS topics, SQS queues and SSM documents with wildcard policies. Treat this inventory as the source of truth, not the Security Hub finding count, because one resource can trigger several controls.
2. Separate genuine public services from drift
Most public exposure is unintended. For each resource, decide whether it is public on purpose. Genuine public content (a static site, a public download bucket) belongs behind CloudFront with Origin Access Control or behind a load balancer, never directly exposed. Everything else is drift and can be closed.
3. Close the doors, highest impact first
Remove public IPs, set databases to not publicly accessible, tighten resource policies to remove wildcard principals, and un-share snapshots. Prioritise resources that hold data over those that do not. Each change is a single API call per resource and takes effect immediately.
4. Ratchet it shut with account and VPC blocks
Enable account-level S3 Block Public Access and VPC Block Public Access so no individual resource can be made public again, and disable public IP auto-assignment on subnets. Back this with AWS Config rules and Service Control Policies so the blocks cannot be quietly undone.
# Close the highest-impact public exposure first: databases.
for db in $(aws rds describe-db-instances \
--query 'DBInstances[?PubliclyAccessible==`true`].DBInstanceIdentifier' --output text); do
aws rds modify-db-instance --db-instance-identifier "$db" \
--no-publicly-accessible --apply-immediately
echo "$db: public access removed"
done
# Ratchet S3 shut at the account level so no bucket can be made public again.
aws s3control put-public-access-block --account-id 123456789012 \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true' Quick quiz
Question 1 of 5Security Hub shows public-access failures across S3, EC2, RDS and SNS. What is the most efficient way to think about them?
You scored
0 / 5
Keep learning
Go deeper on how public reachability works across the services in this capability.
- AWS S3 Block Public Access What each toggle blocks and how account and bucket settings interact.
- Amazon VPC Block Public Access The VPC-wide backstop that stops resources reaching the internet by default.
- Hosting a public site with CloudFront and OAC The recommended way to serve public content without a public bucket.
You can now treat public access as one capability rather than a scatter of findings: inventory what is reachable from the internet, separate the genuine public services and route them through a controlled front door, close the rest highest-impact first, and ratchet the estate shut with account-level and VPC-level blocks. The Controls this lesson covers section below links every control in this group to its deep page and fix.
Back to the library