Amazon S3 Object Lock: governance vs compliance mode, legal holds and retention
What S3 Object Lock actually protects, the difference between governance and compliance mode, legal holds and the newer event-hold retention, the settings you cannot undo, and how to lock files that are already in the bucket.
Object Lock protects object versions, not keys, so a simple delete still hides a file while the locked version stays recoverable. Use governance mode by default and keep the bypass permission with a very small group; switch to compliance mode only for records whose retention period you are sure of, because nobody can shorten it. Use legal holds when the end date is unknown and event holds when retention starts at a business event. Enabling Object Lock is permanent, a default only covers new versions, and existing files need a Batch Operations job.
S3 Object Lock stores objects as write-once-read-many (WORM): for as long as a lock applies, nobody can overwrite or permanently delete that version of the file. It is the S3 answer to "prove this record was not altered", and to "make sure ransomware with our credentials cannot wipe the backups".
It is also one of the few S3 settings with no undo. Pick compliance mode with a seven-year default by mistake and there is no support ticket that removes it. This guide covers what a lock really protects, how the two modes differ, when a legal hold or an event hold fits better than a fixed date, and the order to switch things on.
What a lock protects, and what it does not
Object Lock works only on versioned buckets, and every lock applies to one object version. That detail explains most of the surprises.
A locked version cannot be overwritten, because in a versioned bucket an upload to the same key creates a new version and leaves the locked one alone. A permanent delete, meaning a DELETE that names the version ID, fails with 403 Access Denied. But a simple delete without a version ID still succeeds: S3 adds a delete marker on top, and the file disappears from ordinary listings. Nothing was lost: the locked version is still there, and removing the marker (which is never locked itself) brings the file back. But users will say "it got deleted", and they will be right about what they see.
The other limits are just as literal. A lock does not stop anyone reading the file, so it is not access control. It does not protect versions written before the lock applied. It does not protect the encryption key: if an SSE-KMS key is deleted, locked objects under it can become unreadable. And it does not stop someone from deleting the whole AWS account, which is the one way a compliance-mode object can go early.
Governance mode vs compliance mode
Every retention period has a mode, and the mode decides who, if anyone, can get around it before the date.
- Governance mode: most users cannot delete the version or change its lock, but a principal with s3:BypassGovernanceRetention can, by sending the x-amz-bypass-governance-retention: true header. The S3 console sends that header by default, so an administrator deleting in the console can remove governance-locked objects without noticing the lock was there.
- Compliance mode: nobody can overwrite or delete the version, change its mode or shorten its retention until the date passes. That includes the account root user. The retention can be extended, never reduced.
Which mode to choose
Use compliance mode when a regulation or contract requires records that cannot be altered and you are certain about the retention period. S3 Object Lock has been assessed by Cohasset Associates for SEC 17a-4, CFTC and FINRA requirements, and compliance mode is the setting those assessments rely on.
Use governance mode for everything else: protecting backups against ransomware or a careless script, trialling a retention policy before committing, and any case where "a named administrator can fix a mistake" is an acceptable answer. Then keep s3:BypassGovernanceRetention out of everyday roles. Governance mode is only as strong as the list of principals who hold that permission.
A sensible rollout is governance mode with a short default first, then compliance mode only once the retention period has survived a real audit or legal review. Remember that everything written under compliance mode during a mistaken week stays locked for the full period.
Retention periods, legal holds and event holds
A version can carry a retention period, a legal hold, or both, and they are independent: whichever lasts longer keeps the version protected.
# Legal hold on one version: stays until someone turns it off.
aws s3api put-object-legal-hold \
--bucket amzn-s3-demo-bucket \
--key contracts/acme-msa.pdf \
--legal-hold Status=ON
# Retention that starts when the contract ends, not when it was uploaded.
aws s3api put-object-retention \
--bucket amzn-s3-demo-bucket \
--key contracts/acme-msa.pdf \
--retention '{"Mode":"GOVERNANCE","EventHold":"ON","EventHoldDuration":{"Years":7}}'- Fixed retention: a retain-until date, set on the object or computed from a bucket default of so many days or years after the version was created. Anyone with s3:PutObjectRetention can extend it.
- Legal hold: an on/off flag with no date. It stays until someone with s3:PutObjectLegalHold removes it, whatever the retention says. This is the tool for litigation and audits where the end date is unknown.
- Variable retention with an event hold: the version stays locked while the hold is on, and when you release it S3 sets the retain-until date to the release time plus a duration you chose (1 to 36,500 days, or 1 to 100 years). It fits retention that starts at a business event rather than at upload, such as "seven years after the contract ends" or "three years after the claim closes". You can add a minimum retain-until date as well.
Turning it on without regret
Object Lock can be enabled on a new bucket at creation or on an existing bucket with versioning already enabled. Enabling it is permanent: afterwards you cannot disable Object Lock or suspend versioning on that bucket. Enabling it does not lock anything by itself; nothing is protected until a version gets a retention period, a legal hold, or a bucket default applies to it.
Set the bucket default last, in governance mode, with a period you have checked against your retention schedule. Retention bounds can also be enforced with the s3:object-lock-remaining-retention-days condition in the bucket policy, which stops anyone locking a version for thirty years by typo.
Check your upload path too. Any upload that sets a retention period, including one that picks up the bucket default, must carry a Content-MD5 or x-amz-sdk-checksum-algorithm header. The console and current SDKs add one; older scripts calling PutObject directly can start failing.
# 1. Versioning first. Object Lock requires it and it can never be suspended afterwards.
aws s3api put-bucket-versioning \
--bucket amzn-s3-demo-bucket \
--versioning-configuration Status=Enabled
# 2. Enable Object Lock with a governance-mode default for new versions.
aws s3api put-object-lock-configuration \
--bucket amzn-s3-demo-bucket \
--object-lock-configuration '{
"ObjectLockEnabled": "Enabled",
"Rule": { "DefaultRetention": { "Mode": "GOVERNANCE", "Days": 90 } }
}'Locking files that are already in the bucket
A bucket default applies to versions written after it is set. Existing files stay unlocked until you lock them. For a handful, put-object-retention or put-object-legal-hold per object is enough. For the whole bucket, generate a manifest with S3 Inventory and run an S3 Batch Operations job with the Object Lock retention or legal hold operation, which applies the setting to every listed version in one job.
What it costs, and how it interacts with lifecycle
Object Lock has no charge of its own. The cost is the storage it forces you to keep: every locked version is billed until its retention ends, and in a versioned bucket every overwrite of a locked file adds another full version.
Lifecycle rules still run, but they cannot expire a locked version before its date; expiration applies once the lock ends. Plan the two together: a lifecycle rule that moves locked versions to a colder storage class is allowed and usually worth having, and a noncurrent-version expiration rule is what finally cleans up once the retention period has passed.
Two operational limits: a bucket with Object Lock cannot be a destination for server access logs, and replicating locked objects to another bucket needs Object Lock enabled on the destination too.
What this means for a file workspace on your bucket
A workspace working through a scoped role behaves correctly on a locked bucket without special handling. Users can still upload new versions and delete files in the everyday sense, which adds a delete marker, while the locked versions stay recoverable underneath. The role should not hold s3:BypassGovernanceRetention, s3:PutObjectRetention or s3:PutObjectLegalHold unless someone has decided the workspace is where holds get managed; keep those with the people who own the retention schedule.
Scoping the role a workspace usesThe rest of the security checklist
Starter is free. Deploy a scoped role with CloudFormation, sign in, and browse, without handing anyone an access key.
Primary sources
Discussion
0 comments · open to guests · moderatedLiked this? Get the next article by email. No schedule, no filler, one click to leave.