AWS Solutions Architect Handbook SAA-C03, from zero Bipin Singh
Storage

Securing Amazon S3

2 min readChapter 23 of 48By Bipin Singh

Misconfigured buckets are a classic source of data breaches, so S3 security is heavily tested. Modern S3 defaults are secure; your job is to grant exactly the access needed and nothing more.

Layers of S3 access control

Control Scope Notes
Block Public Access Account and bucket Overrides any policy or ACL that would make data public. On by default for new buckets
IAM policies Users/roles in your account What identities can do on S3
Bucket policies The bucket Resource-based; grant cross-account access, enforce conditions
ACLs Bucket/object (legacy) Disabled by default (Object Ownership = bucket owner enforced); use policies instead
Access points Named endpoints with their own policies Simplify access for many teams/apps on shared buckets; can be restricted to a VPC
Pre-signed URLs A single object, temporarily Time-limited access without credentials
VPC endpoint policies Traffic through an endpoint Restrict which buckets can be reached from a VPC

An access is allowed only if no explicit Deny applies and an Allow exists in an identity or resource policy (and Block Public Access doesn't prevent it).

Bucket policy examples

Require HTTPS:

{
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": ["arn:aws:s3:::secure-data", "arn:aws:s3:::secure-data/*"],
  "Condition": { "Bool": { "aws:SecureTransport": "false" } }
}

Allow only from a specific VPC endpoint:

{
  "Effect": "Deny",
  "Principal": "*",
  "Action": "s3:*",
  "Resource": ["arn:aws:s3:::internal-data", "arn:aws:s3:::internal-data/*"],
  "Condition": { "StringNotEquals": { "aws:SourceVpce": "vpce-0abc1234" } }
}

Allow a CloudFront distribution (Origin Access Control) to read objects — and nobody else from the internet:

{
  "Effect": "Allow",
  "Principal": { "Service": "cloudfront.amazonaws.com" },
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::site-assets/*",
  "Condition": { "StringEquals": { "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE" } }
}

Encryption

Option Keys managed by Notes
SSE-S3 S3 Default for all new objects
SSE-KMS KMS (AWS managed or customer managed key) Audit key use in CloudTrail; control via key policy; use S3 Bucket Keys to cut KMS request costs
DSSE-KMS KMS Two layers of encryption, for strict compliance
SSE-C You supply the key with each request AWS doesn't store your key
Client-side You, before upload Data is encrypted before it reaches AWS

Set default encryption on the bucket, and use bucket policies to deny uploads that don't meet your requirement (e.g. not using a specific KMS key).

Cross-origin resource sharing (CORS)

Browsers block requests from one website domain to another unless allowed. If a web app on app.example.com loads assets directly from a bucket, configure a CORS rule on the bucket.

Monitoring and data protection

Exam patterns

Bipin Singh
Written by Bipin Singh

Senior Full-Stack Engineer · AI & AWS. I design and run production systems on AWS — serverless, data and AI.

Work with me