S3 Object Lock Compliance Mode: Immutable Retention That Even Root Cannot Override
Enable S3 Object Lock in compliance mode at bucket creation so regulated object versions cannot be overwritten or deleted, even by the root user, before the retain-until date.
26 Aug 2026, 08:04 UTC

The problem: privileged users can still delete regulated data
If you store audit logs, financial records, or other write-once-read-many (WORM) data in Amazon S3, a compromised administrator credential or a misconfigured automation can overwrite or delete objects. Standard S3 permissions and bucket policies do not prevent a principal with s3:DeleteObject from removing data. S3 Object Lock in compliance mode addresses this by enforcing retention at the object version level.
Useful takeaway: enable Object Lock in compliance mode when you create the bucket, turn on versioning, and set a default retention period. After that, no principal—including the AWS account root user—can overwrite or delete a protected object version before its RetainUntilDate. Object Lock cannot be disabled after it is enabled, so treat the bucket creation step as permanent.
How compliance mode works
S3 Object Lock works with S3 versioning. Every object version can carry its own retention setting or legal hold. Compliance mode means the retention period is absolute: no user, not even the root user, can delete or overwrite the object version until the retain-until date passes. Governance mode is the alternative; it allows users with the s3:BypassGovernanceRetention permission to override retention, which makes it suitable for testing but weaker for regulatory WORM.
A legal hold is independent of retention. It protects an object version indefinitely until someone explicitly removes it, and it does not expire on its own.
Compliance mode versus governance mode
| Behavior | Compliance mode | Governance mode |
|---|---|---|
| Override by root user | Not allowed | Allowed with s3:BypassGovernanceRetention |
| Override by other principals | Not allowed | Allowed with s3:BypassGovernanceRetention |
| Retention can be shortened | No | No |
| Retention can be extended | Yes | Yes |
| Typical use | Regulatory WORM workloads | Testing and flexible retention |
Worked configuration: create a compliance-locked bucket
Run these commands in a terminal where the AWS CLI is configured with credentials for the target account. Object Lock must be enabled at bucket creation; you cannot add it to an existing bucket that was created without the setting.
Required permissions: s3:CreateBucket, s3:PutObjectLockConfiguration, s3:PutBucketVersioning, s3:PutObject, s3:PutObjectRetention, s3:GetObjectLockConfiguration, and s3:DeleteObject for verification.
Risk: enabling Object Lock is irreversible at the bucket level. You cannot disable it later, and you cannot delete the bucket until all locked object versions are expired or removed.
# Replace example-lock with your bucket name.
aws s3api create-bucket \
--bucket example-lock \
--object-lock-enabled-for-bucket \
--region us-east-1
# Versioning is required for Object Lock.
aws s3api put-bucket-versioning \
--bucket example-lock \
--versioning-configuration Status=Enabled
# Set default retention: 10 days in compliance mode for new object versions.
aws s3api put-object-lock-configuration \
--bucket example-lock \
--object-lock-configuration \
ObjectLockEnabled=Enabled,Rule={DefaultRetention={Mode=COMPLIANCE,Days=10}}
# Upload an object. S3 assigns a version ID.
aws s3api put-object \
--bucket example-lock \
--key audit-log.json \
--body ./audit-log.json
# Apply explicit retention to the uploaded version. Replace
# with the version ID returned by the previous command.
aws s3api put-object-retention \
--bucket example-lock \
--key audit-log.json \
--version-id \
--retention Mode=COMPLIANCE,RetainUntilDate=2026-12-01T00:00:00Z
Default retention applies to new versions automatically; existing versions are not retroactively covered. If you upload a new version of audit-log.json, it receives the default retention unless you specify otherwise.
Verify the lock before you trust it
Confirm bucket-level configuration:
aws s3api get-object-lock-configuration --bucket example-lock
Expected output includes ObjectLockEnabled: Enabled and the default retention rule. Confirm object-level protection:
aws s3api head-object \
--bucket example-lock \
--key audit-log.json \
--version-id
Check the response for the retention mode and RetainUntilDate, or for a legal hold status if one was applied.
To test enforcement, attempt deletion of the protected version:
aws s3api delete-object \
--bucket example-lock \
--key audit-log.json \
--version-id
Before the retain-until date, this request should be rejected with an access-denied response. Do not interpret a successful deletion as confirmation that the lock is working; a successful delete means the object was not protected, the date had passed, or the test was run against an unprotected version.
Syntax and regional behavior can change. Confirm the current CLI and API reference for your target Region before production use.
Limits and common mistakes
- No rollback for Object Lock. Once enabled on a bucket, it cannot be disabled. Plan retention periods and bucket deletion boundaries before creation.
- Retention can be extended, not shortened. You can move a
RetainUntilDateforward, but not backward. Verify dates before applying them. - Existing versions are not retroactively protected. Default retention covers new versions only. Apply retention explicitly to versions that existed before the setting.
- Legal holds do not expire. A legal hold remains until removed with
s3:PutObjectLegalHold. Objects stay protected indefinitely after retention expires if a hold is still active. - Object Lock does not replace bucket policies or MFA delete. A principal with
s3:DeleteBucketcan still attempt to delete the bucket, but only after protected object versions are gone. Use IAM policies and MFA delete as additional layers. - Compliance mode is absolute. Do not use it for data you might need to delete before expiry. Use governance mode if you need a break-glass override path.
Governance or compliance: which to choose
Choose compliance mode when a regulator or auditor requires that no internal principal can delete the data before retention expires. Choose governance mode when you need an override path for operational mistakes, and you can tightly control s3:BypassGovernanceRetention. In either case, enable versioning, test deletion behavior in a non-production bucket first, and document who can remove legal holds.
Practical check: after applying retention, run head-object on a protected version and attempt a delete. If the delete succeeds before the retain-until date, the object version was not covered by compliance retention or the lock configuration was not applied as intended.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.