Skip to content
Quest 10Advanced16 min

Lock the Vault

The archive holds unreleased research on Giratina. It must never become public, every request must use TLS, and data must be encrypted at rest. S3's defaults do most of this already — as long as nobody undoes them.

What you'll learn

  • Access is allowed only if a policy allows it and nothing denies it; an explicit Deny always wins.
  • New buckets have Block Public Access on and ACLs disabled; keep it that way and grant access with IAM and bucket policies.
  • Every new object is encrypted (SSE-S3 by default); use SSE-KMS when you need key-level control and audit.

Section 01

Who can do what

MechanismAttached toUse it for
IAM policyA role or userWhat your own functions and people can do — the default choice
Bucket policyThe bucketRules for everyone: deny non-TLS, require encryption, allow another account or a CloudFront distribution
Access pointsA named endpoint on the bucketSeparate policies per application or team on a shared bucket
ACLsBuckets and objectsLegacy. Disabled by default (Object Ownership: BucketOwnerEnforced) — leave them off

Within one account, either an IAM policy or the bucket policy can allow access. Across accounts, both sides must allow it.

Section 02

Block Public Access

Four settings stop buckets from becoming public through ACLs or policies. Since April 2023 they're all on for new buckets, and you can enforce them for the whole account. With BlockPublicPolicy on, S3 rejects any bucket policy that grants public access — the intern's “public read” statement fails with AccessDenied.

Need public images for a website? Serve them through CloudFront with origin access control, and keep the bucket private.

Section 03

Encryption

  • SSE-S3 — the default since January 2023. S3 manages the keys; nothing to configure.
  • SSE-KMS — keys in AWS KMS: separate permission to decrypt, CloudTrail records of key use. Turn on S3 Bucket Keys to cut KMS request costs.
  • DSSE-KMS — two layers of encryption for workloads that require it.
  • SSE-C — you send your own key with every request. Since April 2026 it's disabled by default for new buckets.

In transit, deny plain HTTP with a bucket-policy statement on aws:SecureTransport — the practice below.

Practice

Your turn

An intern wrote a bucket policy to "make sprites load faster" by making every object public. Block Public Access rejects it. Replace that statement with one that keeps the archive private and denies any request that doesn't use TLS.

Remove the public Allow; add a Deny for s3:* when aws:SecureTransport is "false", on the bucket and its objects.
Tab inserts two spaces. Press Escape, then Tab, to leave the editor. Control or Command plus Enter runs the code.
Simulated — no AWS calls

Check

Check your understanding

Quick Quiz · one question, as many tries as you need.

A role's IAM policy allows s3:GetObject on the bucket. The bucket policy denies s3:* when aws:SecureTransport is false. The role calls GetObject over HTTP. Result?

Choose one answer.