
"Immutable" is an easy word to put on a website. It is a much harder thing to prove. So we did — on 23 July 2026 we ran a full independent verification of S3 Object Lock against s3.z1storage.com: 17 out of 17 tests passed, with behaviour matching AWS S3 exactly in both governance and compliance modes. This post walks through what was tested and what the API actually does when you try to break the rules.
The two lock modes, in practice
Governance mode protects objects from ordinary deletion while leaving an administrative escape hatch. A locked version cannot be deleted or have its retention shortened through normal operations:
$ aws s3api delete-object --bucket vault --key backup.tar.gz \
--version-id 3sL4kqtJlcpXrof3vEQ... --endpoint-url https://s3.z1storage.com
An error occurred (AccessDenied) when calling the DeleteObject operation
Privileged operators can override it with the standard bypass header — exactly as on AWS:
$ aws s3api delete-object ... --bypass-governance-retention
# succeeds for credentials with bypass rights
That makes governance mode ideal for operational retention: protection against accidents and malware, with a controlled way out when a genuine need arises.
Compliance mode is true WORM. Once a version is locked, no credential — including the account owner — can delete it, shorten its retention, or downgrade its mode until the retain-until date passes. There is no bypass header, no support override, no way out. Our verification confirmed this end to end, including the final detail that matters: the version becomes deletable again only after its retention expires.
What ransomware sees
An attacker holding stolen keys can issue all the deletes they like. Against a locked bucket, a DELETE without a version-id merely adds a delete marker — the locked data version underneath remains fully intact and recoverable. Deletes aimed at the version itself are refused. Stolen credentials cannot destroy locked backups; that is the whole point.
Per-version control, fully supported
Every PUT to a versioned bucket returns a unique x-amz-version-id, and the version-level API is complete — this is worth noting because earlier documentation listed it as unsupported, and that has been superseded:
# what retention applies to this exact version?
$ aws s3api get-object-retention --bucket vault --key backup.tar.gz \
--version-id 3sL4kqtJlcpXrof3vEQ... --endpoint-url https://s3.z1storage.com
{ "Retention": { "Mode": "COMPLIANCE", "RetainUntilDate": "2026-08-22T09:00:00Z" } }
ListObjectVersions enumerates every version and delete marker; HEAD responses carry the lock mode, retain-until date and version-id as headers. Your backup software — and your auditors — can see exactly what is protected and until when.
Enabling it
Object Lock is a creation-time choice: tick Object lock → Enabled under Advanced Settings when creating a bucket (versioning is enabled automatically), or pass ObjectLockEnabledForBucket=true via the API — both paths verified identical. It cannot be added to an existing bucket, and it cannot be turned off afterwards. You can also set a default retention rule so every new object is locked on arrival — that deserves its own walkthrough: Immutable on arrival.
Why this matters
Plenty of S3-compatible services advertise Object Lock; fewer behave identically to AWS when a hostile client starts probing the edges — retention shortening, mode downgrades, post-expiry semantics, bypass headers. Ours does, and we verified it rather than assumed it. Combined with South African data residency and flat R0.30/GB/month pricing, that makes Z1 Storage a defensible place to put the backups you hope you never need.
Sign up — first 10GB free — and test the refusals yourself.