SpipCP
Backups

Append-only & immutability

The security story behind backups — two separate credentials (an add-only backup lane and a delete-capable prune lane), how rest-server enforces append-only, where provider object-lock fits, and the one gap self-hosted object stores still have.

The whole reason to take backups is the bad day. The worst bad day is when the thing that compromised a site also deletes its backups. SpipCP is built so that can't happen by accident or by an attacker holding a site's credentials — because the credential a backup uses cannot delete anything.

Two keys, two lanes

Every storage target has two separate credentials, and they reach the repository through two separate lanes:

LaneCredentialWhat it can do
Backup lanethe backup keyAdd new backup data. Never delete. Every site backup, the panel self-backup, and every restore (which only reads) ride this lane.
Prune lanethe prune keyDelete old snapshots. Used only by the retention pruner and the manual "delete backup" action.

A backup process literally never holds the delete-capable key. So a compromised site — which can at most reach the credential a backup runs with — can write a new backup, but cannot wipe the history.

The panel holds the repo keys, not the nodes

The restic repository password (which encrypts the backup contents) and the storage credentials are held by the panel, encrypted at rest. They're handed to a backup as a process/environment secret for one operation — never written into a command line (so they can't leak into ps or a log) and never stored on a node.

The rest-server append-only lane

On a storage node you run, rest-server runs with --append-only. That makes the two lanes server-enforced, not just client-promised:

  • The backup user can PUT new data, but the server refuses every delete it asks for — even if the client tried to delete, the box says no.
  • The prune user reaches a separate, loopback-only lane on the box that can delete. It's only used by the panel's pruner, and it's not exposed to the network.

So even a backup client that has been fully taken over can't destroy a snapshot: the refusal happens on the server, under your control, on a box the compromised site has no other access to.

Provider object-lock

If you bring your own S3 bucket on AWS S3 or Cloudflare R2, you can additionally enable object-lock — the provider makes objects immutable for a retention window, so nothing, not even a delete-capable key, can remove them until the lock expires. That's the strongest immutability available: it survives even a compromised prune key.

The honest gap: self-hosted object stores

Why a self-hosted storage node runs rest-server, not Garage

Self-hosted S3 stand-ins — Garage, SeaweedFS, RustFScannot enforce append-only or object-lock today. With one of those, a client holding the bucket key can delete objects, and there's no server-side refusal to stop it. SpipCP doesn't paper over that: a self-hosted storage node runs rest-server (which can enforce append-only), and provider object-lock is only offered on AWS S3 / R2 (which can enforce it). Where immutability can't be guaranteed, the panel says so rather than implying a protection you don't have.

The safety floor on top of all this

Even with all the above, the panel adds one more guard you can't fat-finger past: it will never delete the last verified-restorable backup. A retention rule (or a manual delete) that would leave a site with no good backup is refused unless you explicitly confirm "leave with no backup." Immutability stops an attacker; the safety floor stops you. See Backups → deletion.

On this page