Your backups are only insurance against ransomware if the ransomware can’t reach them. Most can. The credential that writes the nightly backup is almost always the same credential that can delete it, and deleting or encrypting the backups first is now a standard step in a serious intrusion. If the attacker who owns your fileserver also owns the key to your backup bucket, you do not have a recovery plan. You have a copy that dies with the original.
Immutability is what turns a backup into real insurance. S3 Object Lock, in compliance mode, gives you write-once-read-many (WORM) storage where an object cannot be deleted or overwritten before its retention date, by anyone. Not an admin. Not the root account. Not someone holding your keys. This is how you configure it, how to make sure the account writing backups cannot quietly shorten the retention, and how to prove a delete is actually refused.
What Object Lock actually guarantees
Object Lock has two modes, and the difference is the whole point. In governance mode, a user holding the s3:BypassGovernanceRetention permission can still delete a locked object. That is a convenience, and convenience is exactly what an attacker with stolen admin credentials exploits. In compliance mode, there is no bypass. A protected object version cannot be overwritten or deleted by any user, including the root user, until the retain-until date passes. AWS is blunt about the only escape hatch: the sole way to remove a compliance-locked object early is to close the entire AWS account.
Two constraints follow. Object Lock only works on a bucket with S3 Versioning enabled — locking a specific object version is meaningless without versions — and enabling Object Lock at bucket creation turns versioning on automatically. Retention is applied per object, but you set a bucket default retention so that every object written inherits a retain-until date without the client having to ask. That last detail matters more than it looks: immutability is enforced server-side by the bucket, not by the backup tool, so the tool writing the data does not need to be immutability-aware at all.
Configuring the bucket
Create the bucket with Object Lock on, then set a compliance-mode default retention. Thirty days is a sane starting point; size it to how long you need to notice and respond to an intrusion, because everything you write is undeletable for that whole window — including your storage bill.
# Create the bucket with Object Lock enabled (versioning switches on automatically)
aws s3api create-bucket \
--bucket my-immutable-backups \
--region eu-west-1 \
--create-bucket-configuration LocationConstraint=eu-west-1 \
--object-lock-enabled-for-bucket
# Set a bucket-wide default: COMPLIANCE mode, 30-day retain-until on every object
aws s3api put-object-lock-configuration \
--bucket my-immutable-backups \
--object-lock-configuration \
'{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"COMPLIANCE","Days":30}}}'
Backblaze B2 offers the same primitive through its S3-compatible API — governance and compliance modes, plus a legal hold, and it can be enabled on an existing bucket. If you want your immutable tier off AWS for blast-radius reasons, B2 is the pragmatic second home, addressed the same way by any S3 client.
The account that writes backups must not be able to delete them
Compliance mode already stops anyone deleting a locked object. The residual risk is the configuration around it: an attacker holding your backup key could weaken the default retention so that future backups land unprotected, or lifecycle-expire your way out. So the identity restic or rclone authenticates with should be able to do exactly two things — list and put — and nothing that touches lock configuration, versioning, or object retention. Scope it like any other credential you would not want reused against you: minimal verbs, single bucket, no administrative surface. This is the same least-privilege discipline that applies to any API key you issue.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "WriteBackupsOnly",
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-immutable-backups",
"arn:aws:s3:::my-immutable-backups/*"
]
},
{
"Sid": "DenyAnythingThatCouldUndoImmutability",
"Effect": "Deny",
"Action": [
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:PutObjectRetention",
"s3:PutObjectLegalHold",
"s3:BypassGovernanceRetention",
"s3:PutBucketObjectLockConfiguration",
"s3:PutBucketVersioning",
"s3:PutLifecycleConfiguration"
],
"Resource": [
"arn:aws:s3:::my-immutable-backups",
"arn:aws:s3:::my-immutable-backups/*"
]
}
]
}
The explicit Deny is deliberate. In IAM an explicit Deny always wins, so even if a broader policy is attached to this principal by mistake later, the immutability guarantees survive the error. Keep the credential that can change lock configuration — if you ever need one — in a separate identity that no automated job holds.
Pointing restic or rclone at it
Because the bucket applies retention itself, the write path is ordinary. rclone (1.67) needs no special flags — every object it copies inherits the lock:
# Each uploaded object is locked for 30 days by the bucket default
rclone copy /srv/backups immutable:my-immutable-backups/nightly/
restic (0.17) also works, but with one honest caveat you must design around. restic is not lock-free: it writes its own lock files under the repository and expects to delete them, and restic prune reclaims space by deleting and rewriting pack files. Against a bucket where every object is immutable, those deletes are refused, so a repository living directly on a compliance-locked bucket will accumulate and cannot be pruned in place. The clean pattern is to treat the immutable bucket as an archive tier: keep the working restic repository on ordinary storage where prune functions, and rclone copy its snapshots into the locked bucket, or run restic to a rest-server in append-only mode and mirror that. Either way, the copy the attacker can reach is prunable; the copy in the vault is not.
Prove the delete is actually refused
A control you have not tested is a belief, not a control. Write an object, find its version ID, and try to destroy it the way an attacker would:
VID=$(aws s3api list-object-versions --bucket my-immutable-backups \
--prefix nightly/test.txt --query 'Versions[0].VersionId' --output text)
aws s3api delete-object --bucket my-immutable-backups \
--key nightly/test.txt --version-id "$VID"
# An error occurred (AccessDenied): Access Denied because object protected by object lock.
You want that AccessDenied. Run the same check with an admin credential too — in compliance mode it fails identically, which is the assurance you are buying. Make this a scheduled job rather than a one-off, the same way you would wire any control into automation so it actually runs, and pair it with an occasional real restore so recovery time is a measured number and not a hope — the same MTTR discipline you apply to production incidents.
When this is in place, the maths of the attack changes. The intruder can still encrypt your live estate. What they cannot do is reach into the vault and erase the way back, because the storage layer itself refuses — and the account that runs your backups never held the power to help them. That is the difference between a backup and insurance.
Free interactive tool
Website compliance checklist
What your site has to do, based on what it actually does
Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.
Everything that applies
Ordered by what to do first: legal requirements you can close quickly, then larger pieces of work, then what is expected rather than required. Not exhaustive, and not a legal audit.
Dated PDF, yours to keep or circulate.
Free interactive tool
Interactive deadline calculator
Check which regulations apply to you and when
Regulation across the EU, UK, US and Asia-Pacific has moved considerably in the past eighteen months, and several headline dates have shifted more than once. Twelve questions, about three minutes.
Results are shown on screen — no email required. A dated summary is available to download, and can be sent on if that's more useful. What we do with your answers.
Most technology problems are not technology problems. They are control problems.
The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.
Full Governance by Sixteen Pillars
Govern your business. Prove your compliance.
A board assurance cockpit for EU-regulated financial firms — tamper-evident, hash-chained proof of governance across DORA, GDPR, NIS2, ISO 27001, the EU AI Act and MiCA. In development.
See what's coming