AWS S3: Security

S3 Security Overview
Amazon S3 offers multiple layers of security and access control through both user-based and resource-based mechanisms.
1. User-Based Access
- Controlled via IAM Policies
- IAM policies define which API actions a user or role can perform on specific resources.
- Example: Allow a developer to
s3:GetObjectbut denys3:DeleteObject.
2. Resource-Based Access
Policies applied directly to S3 resources (buckets or objects):
- Bucket Policies — JSON documents that apply to an entire bucket, supporting cross-account access.
- Object Access Control List (ACL) — Fine-grained permissions at the object level.
- Bucket ACL — Similar, but less commonly used today.
3. Access Evaluation Logic
An IAM principal (user, role, or service) can access an S3 object if:
- The IAM policy allows it OR the resource policy allows it,
- AND there’s no explicit DENY anywhere.
S3 Bucket Policies
Bucket policies are JSON-based documents that define what actions are allowed or denied on a bucket or its contents.
Structure
Each policy includes:
- Resources: Buckets or objects (e.g.,
arn:aws:s3:::mybucket/*) - Actions: Set of allowed or denied API operations (e.g.,
s3:GetObject) - Effect:
AlloworDeny - Principal: The AWS account, user, or role affected by the policy
Example: Public Read Access
{ "Version": "2012-10-17", "Statement": [ { "Sid": "PublicRead", "Effect": "Allow", "Principal": "", "Action": ["s3:GetObject"], "Resource": ["arn:aws:s3:::examplebucket/"] } ] }
Common Uses
- Grant public read access to static website files
- Enforce encryption at upload (
"Condition": {"StringEquals": {"s3:x-amz-server-side-encryption": "AES256"}}) - Allow cross-account access between AWS accounts
Block Public Access Settings
To prevent accidental data exposure, S3 provides “Block Public Access” settings.
Controls Include
- Block public access via:
- New ACLs
- Any ACLs
- New public bucket or access point policies
- Block public and cross-account access from any public bucket or access point policies
Best Practice: Always enable “Block all public access” unless your bucket intentionally hosts public content (e.g., a website).
S3 Static Website Hosting
Amazon S3 can host static websites (HTML, CSS, JS) directly — no servers needed.
Website URL Format
<bucket-name>.s3-website-<aws-region>.amazonaws.com
or
<bucket-name>.s3-website.<aws-region>.amazonaws.com
Notes
- Files must be publicly readable.
- If you see 403 Forbidden, ensure:
- The Bucket Policy allows
s3:GetObject - The public access block is disabled for this bucket.
- The Bucket Policy allows
CORS (Cross-Origin Resource Sharing)
What Is CORS?
CORS is a browser-based mechanism allowing a web app at one origin (domain, protocol, port) to access resources at another.
- Origin = protocol + domain + port
e.g.,https://www.example.com:443
Examples
- Same origin:
http://example.com/app1andhttp://example.com/app2 - Different origins:
http://www.example.comandhttp://api.example.com
Requests are only fulfilled if the target origin includes the proper CORS headers, such as: Access-Control-Allow-Origin: https://www.example.com
S3 CORS (Cross-Origin Resource Sharing)
When web apps hosted on S3 need to request assets from another S3 bucket, you must configure a CORS policy on the destination bucket.
Example Use Case
A static website (bucket-html) wants to load images from another bucket (bucket-assets).
CORS Policy Example
[ { "AllowedOrigins": [""], "AllowedMethods": ["GET"], "AllowedHeaders": [""], "ExposeHeaders": [] } ]
Key Points
- CORS allows cross-origin GET/PUT/POST requests.
- You can restrict it to specific origins for security.
- Frequently tested in AWS Certified Exams.