WORM buckets
WORM (write once, read many) means objects can’t be deleted or overwritten until their retention date, not even by you, not even by an attacker holding your keys. It’s the property that makes a backup survive the bad day it exists for.
How gitdr treats it
Section titled “How gitdr treats it”Before writing anything, gitdr probes the destination’s lock configuration. Then:
- Lock confirmed. It proceeds and records the observed immutability in the signed manifest, so “was this backup on WORM storage” has a tamper-evident answer later.
- No lock. It warns loudly and proceeds. Configuring WORM is your job, but you’ll never be quietly unprotected.
--require-worm(orworm.require: true). No confirmed lock means the run fails closed. Use this once your bucket is set up.
Independent of all that, gitdr’s storage layer has no delete or overwrite method, uploads are create-only. WORM protects you from stolen credentials; create-only protects you from gitdr itself.
Set one up
Section titled “Set one up”AWS S3, Object Lock. Only settable at bucket creation:
aws s3api create-bucket --bucket my-worm-bucket --region us-east-1 \ --object-lock-enabled-for-bucketaws s3api put-object-lock-configuration --bucket my-worm-bucket \ --object-lock-configuration \ '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}}'COMPLIANCE mode is real WORM, nobody can shorten it. GOVERNANCE can be lifted with a special permission, which an attacker with admin can also hold. Pick COMPLIANCE.
Google Cloud Storage, locked retention policy. The lock is irreversible:
gcloud storage buckets create gs://my-worm-bucket --location=US \ --uniform-bucket-level-access --public-access-prevention --retention-period=30dgcloud storage buckets update gs://my-worm-bucket --lock-retention-periodAzure Blob. Storage account with version-level immutability plus blob versioning, then a container with a time-based immutability policy (Azure docs).
S3-compatible providers
Section titled “S3-compatible providers”“S3-compatible” is a spectrum, and Object Lock is one of the least universally
implemented parts. Set destination.s3.endpoint and usually usePathStyle: true.
| Provider | Object Lock | Notes |
|---|---|---|
| Wasabi | yes | 90-day minimum retention |
| Backblaze B2 | yes | enable at bucket creation, versioning required |
| MinIO / IDrive e2 | yes | create the bucket with object lock |
| Cloudflare R2 | no | works as a destination, gitdr warns, no WORM |
A provider that doesn’t implement the Object Lock API can’t be confirmed immutable, so
gitdr warns and proceeds, or fails closed under --require-worm.
Credential scoping
Section titled “Credential scoping”The destination credential needs create/put and read. It never needs delete, so don’t grant it. A compromised runner then can’t purge history even on a non-WORM bucket.