AWS Certified Cloud Practitioner / Amazon S3

S3 Security: Bucket Policy

๐Ÿ” Amazon S3 Security โ€“ Overview

Amazon S3 provides multiple layers of security to control who can access your buckets and objects and how objects are protected.


๐Ÿ‘ค User-Based Security (IAM Policies)

IAM policies define what actions a user or role can perform on S3 resources.

Examples:

  • โœ… Upload objects (s3:PutObject)

  • โœ… Download objects (s3:GetObject)

  • โœ… Delete objects (s3:DeleteObject)

  • โœ… List buckets (s3:ListBucket)

๐Ÿ’ก Best for granting permissions to users, groups, and IAM roles.


๐Ÿชฃ Resource-Based Security

  • JSON-based resource policy attached to the bucket

  • Can grant permissions to other AWS accounts, IAM users/roles, or make objects public

  • Supports fine-grained conditions (IP address, time, HTTPS-only, etc.)

  • Centralized โ€” one policy document manages all access rules for the bucket

  • AWS's recommended approach for most access control needs

  • Grants permissions to individual objects.

  • Provides fine-grained access control.

  • Can be disabled (recommended in most cases).

  • Legacy, simpler XML-based permission system

  • Grants basic permissions (READ, WRITE, FULL_CONTROL) to specific grantees (AWS accounts or predefined groups like "All Users")

  • Very limited โ€” no conditions, no fine-grained control

  • Mostly used now for edge cases like cross-account object ownership scenarios (e.g., a different account uploads objects to your bucket)

๐Ÿ’ก AWS recommends disabling ACLs (via "Bucket owner enforced," the default for new buckets) and using bucket + IAM policies instead. ACLs are legacy.


โ€ผ๏ธ How Access is Determined

An IAM principal can access an S3 object if all these conditions are met:

  1. IAM permissions allow it, OR resource (bucket) policy allows it

  2. No explicit Deny exists in any policy

IAM principal = any identity that can make an AWS request โ€” a user, role, group, or federated identity. Basically "who is asking."

๐Ÿ’ก Another way to secure s3 is encrypt object using encryption keys


๐Ÿชฃ More on S3 Bucket Policies:

โ“What a Bucket Policy Looks Like

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicRead",
      "Effect": "Allow",
      "Principal": "*",
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::examplebucket/*"]
    }
  ]
}

Breaking it down:

Field

Meaning

Resource

Which bucket/objects it applies to (/* = all objects in the bucket)

Effect

Allow or Deny

Principal

Who it applies to (* = anyone)

Action

The API(s) allowed/denied (e.g., s3:GetObject = read access)

This specific example makes every object in examplebucket publicly readable.

๐Ÿค Common Use Cases

  • Grant public access

  • Force encryption on upload (deny unencrypted uploads)

  • Grant cross-account access

โ€ผ๏ธ Access Scenarios โ€ผ๏ธ

Public Access โ†’ Use Bucket Policy

Anonymous website visitor โ†’ Bucket policy allows public access โ†’ S3 Bucket

User Access to S3 โ†’ Use IAM Permissions

IAM User + IAM Policy (grants S3 access) โ†’ S3 Bucket

No bucket policy needed โ€” IAM policy alone is enough.

EC2 Instance Access โ†’ Use IAM Roles

EC2 Instance + IAM Instance Role (with S3 permissions) โ†’ S3 Bucket

IAM users aren't attached to EC2 โ€” use a Role instead.

Cross-Account Access โ†’ Use Bucket Policy

IAM User (Other AWS Account) โ†’ Bucket Policy allows cross-account access โ†’ S3 Bucket

The other account's own IAM permissions aren't enough โ€” your bucket policy must explicitly allow them.


๐Ÿ”‘ Force Encryption

You can't force S3 to encrypt files directly, but you can deny uploads that aren't encrypted.

{
  "Effect": "Deny",
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::examplebucket/*",
  "Condition": {
    "StringNotEquals": {
      "s3:x-amz-server-side-encryption": "AES256"
    }
  }
}
  • No encryption header on the upload โ†’ request denied

  • Encryption header present โ†’ upload allowed

So it rejects unencrypted uploads instead of encrypting for you.


โŒ Block Public Access (Safety Net)

  • Extra AWS security layer, on by default for new buckets

  • Overrides bucket policy โ€” even a "public" bucket policy won't work if this is enabled

  • Can be set at bucket level or account level (account level = good if no bucket should ever be public)


๐Ÿงฎ Summary Table

Security Type

Use Case

Example

IAM Policy

User/Role based

Allow user to list objects

Bucket Policy

Resource-based

Allow public read, cross-account access

ACL

Fine-grained object control

Grant read/write on specific objects

Encryption

Protect data at rest

SSE-S3, SSE-KMS

Block Public Access

Prevent accidental exposure

Always enabled for sensitive buckets

๐Ÿ‘‰ Data at rest means : data sitting in storage, not being actively used or moved


๐Ÿ’ก Best Practices

  1. Prefer IAM policies + bucket policies over ACLs

  2. Enable encryption by default

  3. Enable Block Public Access unless you intentionally need public objects

  4. Use pre-signed URLs for temporary secure sharing instead of making buckets public