Skip to main content
emnode
Compliance

Enable Object Lock on S3 general purpose buckets

Security Hub S3.15: Object Lock gives a bucket write-once-read-many (WORM) protection so objects can't be deleted or overwritten before their retention period expires.

12 min·10 sections·AWS

Last reviewed

Remediates AWS Security Hub: S3.15

S3 Object Lock: the basics

Why a regular S3 bucket isn't enough for data you can't afford to lose

By default, anyone with the right S3 permissions can overwrite or delete an object in a bucket, that's the whole point of a mutable object store. S3 Object Lock changes that contract: it lets you store objects using a write-once-read-many (WORM) model, so an object can't be deleted or overwritten for a fixed retention period or indefinitely under a legal hold. It's the cloud equivalent of writing to a disk that physically cannot be erased until a date you set in advance.

The S3.15 control checks whether an S3 general purpose bucket has Object Lock enabled, and fails the bucket if it doesn't. There's an optional mode parameter (GOVERNANCE or COMPLIANCE) and if you set it, the control only passes when the bucket's default retention uses that exact mode. The control is rated Medium severity and falls under the Protect / Data deletion protection category, mapping to NIST.800-53.r5 CP-6(2) and PCI DSS v4.0.1/10.5.1.

It's flagged because deletion protection is something you ideally decide before it matters, not after. Object Lock can be enabled on a new bucket at creation or on an existing bucket in place (it requires versioning, which it turns on automatically), so a failing finding isn't really an infrastructure problem, it's a prompt to ask whether the data in that bucket is the kind that regulators, auditors, or your own incident-response runbook would expect to be tamper-proof. Logs, backups, financial records, and anything subject to a retention mandate are the obvious candidates.

In this lesson you'll learn what S3 Object Lock actually does, the difference between GOVERNANCE and COMPLIANCE retention modes, why versioning is a hard prerequisite, and how to turn Object Lock on, either at bucket creation or in place on an existing bucket (since November 2023, AWS lets you enable it on an existing bucket directly, no new bucket or migration required). You'll see the AWS CLI commands to enable Object Lock and set default retention, how legal holds differ from retention periods, and how to remediate a failing S3.15 finding without breaking applications that expect to overwrite objects.

Fun fact

The backup that saved a hospital from a $9M ransom

In a widely-cited 2021 incident, a healthcare provider hit by ransomware found its primary backups encrypted alongside production, the attackers had quietly compromised the backup account weeks earlier and deleted recovery points. The one dataset they couldn't touch was a tier of backups written to an S3 bucket with Object Lock in COMPLIANCE mode and a 30-day retention. Because no credential (not even root) could delete or overwrite those objects before the retention window expired, the provider restored from them and refused the ransom. The feature that made the difference cost nothing beyond ordinary storage; the decision to turn it on, made months earlier during a routine compliance review, was worth the entire ransom demand.

Enabling Object Lock in action

Diego is the platform engineer who owns the backup tooling at a mid-sized fintech. Security Hub flags S3.15 on the bucket that stores nightly database snapshots, Object Lock isn't enabled. He confirms the classification with the compliance team: these snapshots are subject to a 7-year retention mandate, so they're exactly the kind of data WORM protection exists for.

The good news: he doesn't have to recreate or migrate the bucket. Since November 2023, AWS lets you enable Object Lock on an existing bucket in place, it requires versioning, which Object Lock turns on automatically. So the path is enable Object Lock on the bucket, set a sensible default retention so new snapshots are protected, and use S3 Batch Operations to apply retention to the snapshots already sitting in the bucket.

He runs put-object-lock-configuration against fintech-db-snapshots to enable Object Lock with a default GOVERNANCE-mode retention of 35 days (matching the rolling backup window, with the long-term archival handled separately by Glacier with its own lock), then kicks off an S3 Batch Operations job to set retention on the existing objects. The S3.15 finding clears on the next evaluation, and the snapshots are now genuinely tamper-proof for their retention period, even Diego can't delete them early without explicitly bypassing the lock.

First, check whether the flagged bucket actually has Object Lock configured. A bucket that fails S3.15 returns no lock configuration at all.

$ aws s3api get-object-lock-configuration --bucket fintech-db-snapshots
An error occurred (ObjectLockConfigurationNotFoundError) when calling the
GetObjectLockConfiguration operation: Object Lock configuration does not
exist for this bucket
# No lock configuration: this is why S3.15 fails. Object Lock can be
# enabled on this existing bucket in place; no new bucket is required.

A missing Object Lock configuration is exactly what the S3.15 control flags.

Enable Object Lock on the existing bucket and set a default retention rule in one call. Object Lock requires versioning, which it enables automatically when you set the configuration.

$ aws s3api put-object-lock-configuration --bucket fintech-db-snapshots --object-lock-configuration 'ObjectLockEnabled=Enabled,Rule={DefaultRetention={Mode=GOVERNANCE,Days=35}}'
# (no output on success)
# Object Lock + versioning now enabled on the existing bucket.
# Default retention applies GOVERNANCE mode for 35 days to new objects.
# S3.15 will pass on the next evaluation; lock existing objects via Batch Ops.

Object Lock can be enabled in place on the existing bucket and paired with a default retention rule, the path that clears S3.15.

Object Lock under the hooddeep dive

Object Lock works at the object-version level and is built on top of S3 Versioning, that's why versioning is a hard prerequisite, and enabling Object Lock turns versioning on automatically if it isn't already. You can enable Object Lock when a bucket is created or in place on an existing bucket; once enabled it can't be disabled, and versioning can't be suspended afterward. Each object version carries its own retention metadata: a retention mode, a retain-until date, and optionally a legal hold flag. A protected version can't be deleted or overwritten; a delete request against it creates a delete marker rather than removing the underlying immutable version. The data physically remains until the retention window lapses.

There are two retention modes and they behave very differently. In GOVERNANCE mode, the lock blocks ordinary deletes and overwrites, but a user with the s3:BypassGovernanceRetention permission can override it, a useful break-glass path for operational backups. In COMPLIANCE mode, nothing and no one can shorten the retention or delete the version before the retain-until date, not even the root account. COMPLIANCE is the mode regulators expect for true WORM; GOVERNANCE is for protection-with-an-escape-hatch. The S3.15 mode parameter lets the control assert that a bucket uses a specific mode.

Retention is distinct from legal hold. A retention period has a fixed expiry date; a legal hold has no expiry and stays until explicitly removed (with the right permission), independent of any retention setting. Default bucket retention applies automatically to new objects, but you can also set per-object retention that's longer than the default. Crucially, you can extend a retention period but never shorten it in COMPLIANCE mode, the asymmetry is the whole point.

# Inspect the lock configuration on a remediated bucket.
aws s3api get-object-lock-configuration --bucket fintech-db-snapshots-locked

# Verify a specific object version carries retention metadata.
aws s3api get-object-retention \
  --bucket fintech-db-snapshots-locked \
  --key 2026-05-26/snapshot.sql.gz

# Apply a legal hold to a single object (independent of retention period).
aws s3api put-object-legal-hold \
  --bucket fintech-db-snapshots-locked \
  --key 2026-05-26/snapshot.sql.gz \
  --legal-hold Status=ON

What is the impact of missing Object Lock?

The headline impact is data you assumed was safe being deleted or altered when it matters most. Without Object Lock, the only thing standing between a critical dataset and permanent loss is access control, and access control fails. Credentials get phished, IAM policies get misconfigured, an automation script runs against the wrong bucket, or a disgruntled insider with legitimate access decides to clean up. Object Lock removes the human and the credential from the equation entirely for the retention window.

The most acute scenario is ransomware. Modern ransomware actors specifically hunt for and destroy backups before triggering encryption, because backups are what defeat the ransom. A backup bucket without Object Lock is exactly the soft target they're looking for. With COMPLIANCE-mode locks in place, the backups survive the attack regardless of what credentials are compromised, which is often the single deciding factor between a clean recovery and paying a ransom.

The compliance impact is just as concrete. PCI DSS, SEC and FINRA record-keeping rules, HIPAA, and a long list of other regimes require certain records to be retained unaltered for defined periods. "We had IAM policies that should have prevented deletion" is not an answer that satisfies an auditor; "these records were stored under a COMPLIANCE-mode WORM lock that no one could bypass" is. A failing S3.15 finding on an in-scope bucket is a genuine audit gap, not cosmetic.

There's a quieter operational impact too. Mutable backups and logs erode trust in your own recovery story, every restore raises the question of whether the source was tampered with. Immutable storage makes the integrity question disappear, which speeds up incident response and forensics when you can least afford ambiguity about whether the evidence is clean.

How do you remediate a failing S3.15 finding?

Since November 2023 you can enable Object Lock in place on an existing bucket, so remediation is a deliberate four-step process: classify the data, enable Object Lock on the bucket with the right default retention mode, lock the objects already in the bucket with S3 Batch Operations, then enforce the standard so new buckets are born protected.

1. Classify the data before you change anything

Confirm whether the flagged bucket actually holds data that warrants WORM protection: backups, audit logs, financial or regulated records. Not every bucket needs Object Lock, and the control may be reasonably suppressed for buckets holding ephemeral or non-critical data. The classification decision drives everything that follows, including which retention mode to use, so settle it with the data owner and compliance before touching infrastructure.

2. Enable Object Lock on the bucket and set a default retention

Enable Object Lock in place on the existing bucket, no new bucket or migration is required, and it requires versioning, which it turns on automatically. The single put-object-lock-configuration call both enables Object Lock and sets a default retention rule with the chosen mode and period. Use GOVERNANCE mode where a sanctioned break-glass restore must remain possible, and COMPLIANCE mode where records must be immutable to everyone including root for the full retention window. A default retention applies only to objects written after it's set.

3. Lock the objects already in the bucket

The default retention protects new objects only, so use S3 Batch Operations to apply retention (or a legal hold) to the objects already in the bucket. Watch for applications that overwrite objects in place, under Object Lock those overwrites are blocked during the retention period, so workloads that mutate the same key repeatedly need a versioned or new-key pattern instead. Verify with get-object-retention on a sample of objects before you consider the finding closed.

4. Enforce the standard so new buckets are born protected

One remediated bucket doesn't close the gap. Bake Object Lock into the provisioning templates (CloudFormation, Terraform, or your platform's bucket factory) for any tier classified as critical, and use a Service Control Policy or AWS Config rule to flag or block creation of in-scope buckets without it. The goal is that no critical dataset can ever exist in a mutable bucket again, so S3.15 stops recurring at the source.

# 1. Enable Object Lock in place and set a default retention rule in one call.
#    Versioning is turned on automatically. Use COMPLIANCE for true regulatory WORM.
aws s3api put-object-lock-configuration \
  --bucket fintech-db-snapshots \
  --object-lock-configuration \
    'ObjectLockEnabled=Enabled,Rule={DefaultRetention={Mode=COMPLIANCE,Days=2555}}'

# 2. The default retention only covers new objects. Lock the objects already in
#    the bucket with an S3 Batch Operations job (put-object-retention operation),
#    driven by an inventory or CSV manifest of the existing keys.
aws s3control create-job \
  --account-id 111122223333 \
  --operation '{"S3PutObjectRetention":{"Retention":{"Mode":"COMPLIANCE","RetainUntilDate":"2033-01-01T00:00:00Z"}}}' \
  --manifest file://manifest.json \
  --report file://report.json \
  --priority 1 \
  --role-arn arn:aws:iam::111122223333:role/S3BatchOpsRole \
  --region us-east-1

# 3. Confirm the lock configuration is in place on the bucket.
aws s3api get-object-lock-configuration --bucket fintech-db-snapshots

Quick quiz

Question 1 of 5

Security Hub flags S3.15 on an existing bucket holding regulatory backups. What is the correct remediation path?

You've completed Enable Object Lock on S3 general purpose buckets. You now know what the S3.15 control checks, why Object Lock gives a bucket write-once-read-many protection, the difference between GOVERNANCE and COMPLIANCE retention modes, and how to remediate a failing finding: enable Object Lock in place on the existing bucket, set a default retention, and lock the objects already there with S3 Batch Operations. No new bucket or migration required. Next time S3.15 lights up, you'll know to classify the data first and remediate at the source.

Back to the library