Object Lock (WORM immutability)
Lock objects as immutable with a per-object WORM model: define retention, choose between Governance and Compliance mode, and protect your data against accidental deletions or ransomware.
Object Lock applies WORM immutability (Write Once, Read Many) at the object level. When a version of an object has an active retention, OtterStorage prevents it from being deleted or overwritten until the retention date expires, even for the bucket owner. It's the technical foundation for anti-ransomware backups and for regulatory compliance. The entire API is S3-compatible and works with aws s3api or other clients.
How it works
Object Lock relies on versioning: retention is set on each object version, not on the key. That's why versioning is required and is enabled automatically when you turn on Object Lock. While a version is under retention:
- That version cannot be deleted (
DeleteObjectVersionis denied). - Its content cannot be modified: a new write creates another version, but the protected one stays intact.
- The retention date cannot be shortened or removed (except in Governance mode with the proper permission, see below).
Reads work normally. Because OtterStorage doesn't charge for requests or deletions, keeping many immutable versions adds no per-operation cost: you only pay for the storage they take up.
Step 1: create the bucket with Object Lock (from the console)
Object Lock can only be enabled when the bucket is created, and buckets are created from the OtterStorage console (your keys are scoped to a single bucket and cannot create buckets). When creating the bucket, enable the Immutability (Object Lock) option, choose the mode (Governance or Compliance) and the retention days; this also enables versioning automatically.
Once created, you can verify from the CLI that it's active:
aws s3api get-object-lock-configuration \
--bucket mi-bucket-worm \
--endpoint-url https://es-mad-1.s3.otterstorage.io
If you need to refresh the aws s3api syntax and profile configuration, see the AWS CLI guide.
Retention modes: Governance and Compliance
Each retention is applied in one of two modes. The difference is in who can lift or shorten the protection before it expires.
GOVERNANCE
Protects the object against accidental deletions or changes, but a user with the s3:BypassGovernanceRetention permission can lift or shorten the retention. It's the recommended mode to protect yourself from mistakes and most attacks while keeping a controlled escape hatch for administrators. To bypass the retention you must send the x-amz-bypass-governance-retention header, which in the CLI is expressed with --bypass-governance-retention.
COMPLIANCE
Strict immutability: no one can delete the version or shorten the retention date before it expires—not even the account owner or the administrator. The date can only be extended, never reduced. It's the mode for demanding regulatory requirements (for example, legal retention of financial records). Use it carefully: a COMPLIANCE retention cannot be undone.
Step 2: apply retention to an object
You can set the retention when uploading the object with put-object, specifying the mode and the date until which the object must remain immutable. The date is in ISO 8601 format (UTC):
aws s3api put-object \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--body 2026-06-11.tar.gz \
--object-lock-mode GOVERNANCE \
--object-lock-retain-until-date 2027-06-11T00:00:00Z \
--endpoint-url https://es-mad-1.s3.otterstorage.io
If the object already exists, apply or change the retention on a specific version with put-object-retention:
aws s3api put-object-retention \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--retention '{"Mode":"COMPLIANCE","RetainUntilDate":"2027-06-11T00:00:00Z"}' \
--endpoint-url https://es-mad-1.s3.otterstorage.io
To query the current retention of an object:
aws s3api get-object-retention \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--endpoint-url https://es-mad-1.s3.otterstorage.io
Shortening a GOVERNANCE-mode retention requires the explicit bypass:
aws s3api put-object-retention \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--retention '{"Mode":"GOVERNANCE","RetainUntilDate":"2026-07-01T00:00:00Z"}' \
--bypass-governance-retention \
--endpoint-url https://es-mad-1.s3.otterstorage.io
In COMPLIANCE mode this bypass does not exist: the command above would fail if the new date is earlier than the current one.
Step 3: bucket default retention
Instead of setting retention object by object, you can define a default retention that applies automatically to every new object in the bucket. It's configured with put-object-lock-configuration, specifying Days or Years (one of the two, not both):
aws s3api put-object-lock-configuration \
--bucket mi-bucket-worm \
--object-lock-configuration '{
"ObjectLockEnabled": "Enabled",
"Rule": {
"DefaultRetention": {
"Mode": "GOVERNANCE",
"Days": 30
}
}
}' \
--endpoint-url https://es-mad-1.s3.otterstorage.io
For a multi-year default retention in Compliance mode:
aws s3api put-object-lock-configuration \
--bucket mi-bucket-worm \
--object-lock-configuration '{
"ObjectLockEnabled": "Enabled",
"Rule": {
"DefaultRetention": {
"Mode": "COMPLIANCE",
"Years": 7
}
}
}' \
--endpoint-url https://es-mad-1.s3.otterstorage.io
The default retention is calculated from the moment each object is uploaded. A retention set explicitly in the put-object takes precedence over the bucket's. Changing the default rule only affects objects uploaded afterward: it does not rewrite the retention of objects that already exist.
Object legal hold vs. OtterStorage Legal Hold
There are two similarly named concepts that you should not confuse:
- Object legal hold (S3): a per-object flag of Object Lock itself, independent of the retention date. While it's
ON, the version is immutable even if it has no retention or even if the retention has expired; it's removed by setting it toOFF. It's granular and has no expiration date. - OtterStorage Legal Hold (per bucket): a reversible switch at the level of the entire bucket, governed from the console, that freezes all of the bucket's content and configuration at once. It's designed for audits and litigation. We describe it in detail on the Legal Hold page.
The object legal hold is also managed via the API. To enable it on a version:
aws s3api put-object-legal-hold \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--legal-hold '{"Status":"ON"}' \
--endpoint-url https://es-mad-1.s3.otterstorage.io
And to remove it:
aws s3api put-object-legal-hold \
--bucket mi-bucket-worm \
--key backups/2026-06-11.tar.gz \
--legal-hold '{"Status":"OFF"}' \
--endpoint-url https://es-mad-1.s3.otterstorage.io
In short: use the object legal hold when you need to freeze specific versions without a defined date; use the per-bucket OtterStorage Legal Hold when you want to freeze the entire bucket reversibly from the console.
Use cases
Anti-ransomware backups
Configure a default retention in GOVERNANCE mode on the backup bucket. Even if an attacker compromises your credentials, they won't be able to delete or overwrite the immutable backups within their retention period: at most they could upload new versions, but the protected ones would still be available to restore. If you want an even stronger guarantee and accept that the protection is irreversible, use COMPLIANCE. Because we don't charge for requests or deletions, keeping a deep history of immutable versions doesn't penalize your per-operation bill.
Regulatory compliance
For records that the law requires you to keep for a fixed period (for example, tax or financial documentation), apply a default retention in COMPLIANCE mode with the required Years. No user, not even the administrator, will be able to delete those objects before the period expires, which gives you solid proof of immutability for auditors.
Best practices
- Plan before creating: Object Lock can only be enabled when the bucket is created. Decide on it in advance for data that requires immutability.
- Start with GOVERNANCE: protect against mistakes and attacks while keeping an administration path. Reserve COMPLIANCE for strict legal requirements, since it cannot be reverted.
- Limit the bypass: grant
s3:BypassGovernanceRetentiononly to the essential identities. - Combine it with lifecycle: after the retention expires you can automate the deletion or transition of old versions. See the lifecycle guide.
- Use UTC for dates: specify
RetainUntilDatein ISO 8601 format withZto avoid time zone ambiguities.
For more details on buckets, access keys, and the rest of the features, see the documentation.
Ready to try it out?
Create your account and get your keys in minutes.