Skip to content

Lab 10 — Immutable data & discovery

📝 Guide written, not run yet 🧭 Data Protection 💲 a few cents
Services: S3 (Block Public Access, Object Ownership, Object Lock), Amazon Macie

In one sentence

Three S3 data-protection controls the exam loves: Block Public Access + ACLs disabled stop accidental exposure, Object Lock makes object versions immutable (and you see exactly what it does not stop), and Macie finds personal and financial data — including a custom identifier you define.

The idea

 sec10-bpa-…    BPA on + ACLs disabled  → public bucket policy ❌   public-read object ACL ❌
 sec10-lock-…   Object Lock (versioning on)
                  version v1  GOVERNANCE retain 15 min → delete version ❌ · bypass (special permission) ✅
                  version v2  LEGAL HOLD ON           → delete version ❌ even with bypass · hold OFF ✅
                  "delete" without version id         → just adds a delete marker ✅ (data still there)
 sec10-pii-…    customers.csv, hr-notes.txt, readme.txt
                  Macie one-time job (managed identifiers + custom EMP-###### identifier)
                  → findings: SensitiveData:S3Object/Financial, /Personal, /CustomIdentifier …

What to expect when you run it

Part A — Block Public Access and ACLs

Test Expected result
New bucket's BPA settings ✅ all 4 = true (default for new buckets)
Object Ownership ✅ BucketOwnerEnforced = ACLs disabled
Put a bucket policy with Principal: "*" ❌ AccessDenied — blocked by BlockPublicPolicy
Upload an object with public-read ACL ❌ AccessControlListNotSupported

Part B — Object Lock (governance mode, 15-minute retention)

Test Expected result
Bucket created with Object Lock ✅ versioning is enabled automatically (required)
DeleteObject without a version ID ⚠️ succeeds — but only adds a delete marker; v1 is still there
Delete the protected version v1 ❌ AccessDenied (protected by Object Lock)
Shorten the retention date ❌ AccessDenied without bypass
Delete v1 with --bypass-governance-retention (s3:BypassGovernanceRetention) ✅ deleted — would fail for everyone in COMPLIANCE mode
Delete a version under legal hold, even with bypass ❌ AccessDenied — legal hold ignores the governance bypass
Legal hold OFF, then delete ✅

Part C — Macie

File Expected finding
customers.csv ✅ Financial (credit card numbers) + Personal (names, addresses, phones, emails) → SensitiveData:S3Object/Multiple
hr-notes.txt ✅ Personal + CustomIdentifier (sec10-employee-id, 3 matches of EMP-[0-9]{6})
readme.txt — no finding

Automated sensitive data discovery is turned off so Macie doesn't sample every other bucket in the account; the one-time job usually takes 10–20 minutes.

Key lessons

  1. BPA is a guardrail, not a permission. It rejects public policies/ACLs even from an admin, and the most restrictive of account-level and bucket-level settings wins.
  2. Object Lock protects versions, not keys. A plain delete still "works" by adding a delete marker — the object disappears from listings, but the locked version survives.
  3. Governance can be bypassed, compliance can't, legal hold has no end date. Pick by who must be unable to delete and whether the end date is known.
  4. Macie = S3 only. Managed identifiers cover common PII/financial data; custom identifiers (regex + keywords + distance) cover your own formats; allow lists suppress known false positives.

Exam notes

  • 4 BPA settings: BlockPublicAcls (reject new public ACLs), IgnorePublicAcls (ignore existing ones), BlockPublicPolicy (reject new public bucket policies), RestrictPublicBuckets (only AWS services and the bucket owner's account can use an existing public policy).
  • BPA levels: account (enforce org-wide with an SCP denying s3:PutAccountPublicAccessBlock, or the org-level policy) and bucket. Most restrictive applies.
  • Object Ownership = BucketOwnerEnforced disables ACLs: access by policy only, the bucket owner owns every object (default for new buckets since 2023).
  • Need a public website? CloudFront + Origin Access Control, bucket stays private.
  • Find public / cross-account buckets: IAM Access Analyzer for S3, Macie bucket inventory, Config rule s3-bucket-public-read-prohibited, Trusted Advisor.
  • Object Lock needs versioning; can be enabled at creation or later on a versioned bucket. Default retention applies to new objects automatically.
Governance Compliance Legal hold
Ends retain-until date retain-until date only when removed
Override s3:BypassGovernanceRetention + bypass header nobody, not even root (can only extend) anyone with s3:PutObjectLegalHold
Use protect from most users, still testable regulatory WORM (SEC 17a-4, FINRA) litigation, unknown end date
  • S3 Glacier Vault Lock = WORM for Glacier vaults (lock policy immutable after the 24 h confirmation).
  • Ransomware combo: versioning + Object Lock + MFA Delete (root only, CLI only) + AWS Backup Vault Lock + replication to another account.
  • Macie modes: discovery jobs (one-time / scheduled, you pick buckets) vs automated sensitive data discovery (continuous sampling, sensitivity score per bucket). Also policy findings (public, unencrypted, shared buckets).
  • Macie findings → EventBridge (automate) and Security Hub; kept 90 days. Revealing sensitive data samples needs a KMS key and an S3 results location. Org-wide via delegated administrator.
  • Macie can't classify objects encrypted with SSE-C or with a KMS key whose policy doesn't allow its service-linked role → "unclassifiable".

Review questions

Question 1

A developer runs aws s3 rm s3://locked-bucket/report.pdf on a bucket with Object Lock in compliance mode, and the file disappears from the console. Was the data destroyed? Explain.

Show answer

No. s3 rm sends a DELETE without a version ID. On a versioned bucket that just adds a delete marker as the new current version, so the object vanishes from normal listings. The locked version is untouched and can't be deleted until its retain-until date passes — in compliance mode not even by root. Show versions in the console (or ListObjectVersions) and delete the marker to make it reappear.

Question 2

Legal says "keep these 200 objects until the lawsuit ends; we don't know when". Retention or legal hold?

Show answer

Legal hold. Retention needs a retain-until date; a legal hold has no expiry and stays until someone with s3:PutObjectLegalHold removes it. It's independent of retention mode, so it also protects objects whose retention period has already passed, and the governance bypass doesn't override it.

Question 3

Your auditor needs proof that even the root user can't delete trade records for 7 years. Which mode?

Show answer

Compliance mode with a 7-year retention (typically as the bucket's default retention). In compliance mode no user, including root, can delete a protected version or shorten its retention; the period can only be extended. Governance mode isn't enough because anyone with s3:BypassGovernanceRetention can override it.

Question 4

A team needs one S3 bucket to serve a public static website. BPA is on at the account level. What's the recommended design that keeps BPA on?

Show answer

Put CloudFront in front of the bucket with Origin Access Control (OAC). The bucket stays private with BPA on; its bucket policy allows only the CloudFront service principal, scoped with aws:SourceArn to that distribution. That policy isn't public, so BPA doesn't block it. You also get HTTPS (ACM cert in us-east-1), caching and WAF. Turning BPA off for the bucket would work, but it's the wrong answer.

Question 5

Macie reports thousands of findings for an internal test value TEST-0000-0000. How do you stop that without disabling the identifier?

Show answer

Create a Macie allow list — predefined text (the exact value) or a regex — and attach it to the discovery job or to automated discovery. Macie then ignores matches of that value while the managed or custom identifier still flags real data. To hide existing findings, add a suppression rule (archives findings that match the filter), but the allow list is what fixes detection.

Not run yet

Never use COMPLIANCE mode in a lab — nobody can delete those objects until the date passes. The cleanup has to delete every version and delete marker with --bypass-governance-retention before the bucket can go.