Zero-knowledge backup encryption seals every future backup of your server to recovery keys that only you hold. You turn it on, verify it, and manage your keys from one place: the Encryption panel on your server's Backups tab. This article is about that panel. For the recovery keys themselves — how each type works and how to get your data back — see Zero-knowledge backups: your recovery keys.
SHC never sees a private key, a passphrase, or an open backup key. That is the whole point, and it has one consequence you must plan for: if you lose every key you sealed to, those backups are gone — we cannot reset them and neither can anyone who compromises us. Register more than one key.
Open your server, go to the Backups tab, and find the Encryption panel. Its header tells you the current state:
Just below, a status line names what you can do next, based on whether this service already has an SSH key we can use:
If you provisioned with an ed25519 SSH key, you already have a recovery key and there is nothing new to install.
age can only seal to ssh-ed25519.To recover later you use your ordinary SSH private key — plain age, no SHC tooling at all:
age -d -i ~/.ssh/id_ed25519 backup.dek.age > dek.bin
No SSH key on the service? Add an ssh-ed25519 key on the SSH keys tab, then come back here.
These recovery-key types are derived on your own machine so that your secret never reaches us. You derive the public age1... recipient with our small recovery-key helper (shc-age.py), then paste that public value into the panel. The exact per-type derive commands are in your recovery keys.
Both the Turn on encrypted backups box and the Re-key box carry an Add a recovery recipient (optional) control. To add one of these keys:
age1... recipient offline with shc-age.py — SHC never sees your secret.age1... field and choose its type from the dropdown: bitcoin, nostr, PGP, passphrase, recovery card, or custom (age).Your recovery-key set always keeps one primary that you control — an SSH key, or a passphrase. A pasted passphrase recipient counts as your primary, so a server with no SSH key can still turn encryption on this way; the bitcoin, nostr, PGP, and recovery-card rungs ride alongside that primary.
Prefer to script it? You can register the same recipients through the zero-knowledge routes in the customer API — the panel and the API write to the same place. The API also accepts one type the dropdown does not list yet: a post-quantum hybrid recipient (kind pq-hybrid) that pairs an age key with an ML-KEM-1024 key so your sealed backups resist a future quantum adversary — see your recovery keys.
Plan ahead for one thing: your recovery-key set is write-once. You choose it when you turn encryption on. Adding a key afterwards means re-keying to a new set, which is destructive (below) — so paste every key you want at turn-on time, or when you deliberately re-key.
When encryption is on, the panel lists your active recovery keys with their kind, their age1... recipient, and a short fingerprint. To confirm a key is really yours and really the one being sealed to, re-derive it offline with shc-age.py and compare the recipient string against the row. They must match exactly. Verifying costs nothing and never exposes your secret.
Revoking a key removes it from future backups. It does not change or damage existing backups — anything already sealed to that key can still be opened with it. Revoke is one click with a confirmation, and it cannot be undone. The panel will not let you revoke your last primary key — your only remaining way in — and shows "only key" there instead. To change your only key, re-key.
Re-keying replaces your entire recovery-key set with a brand-new generation and retires the old one: every recipient from the previous set is revoked, so the old keys are decisively replaced rather than left enrolled beside the new ones. Every backup made under the previous set becomes permanently unrecoverable — to you, to SHC, to anyone. It is deliberately hard to do by accident: expand Re-key, choose the SSH key(s) and/or paste the recovery recipient(s) for the new generation, and type DESTROY-MY-BACKUPS to confirm. Through the API the same action requires destroy_ack: DESTROY-MY-BACKUPS plus the confirmation challenge. Use it only when you intend to abandon the old backups — for example after a key is exposed, or to change which keys your backups are sealed to.
Restoring an encrypted backup is operator-assisted, and your key stays with you the whole time. You decrypt the backup's sealed key on your own machine with the key you hold:
age -d -i <your-identity-file> backup.dek.age > dek.bin
Then our team completes the in-place restore of your server. SHC never sees your recovery key at any step. The full per-type recovery procedure is in your recovery keys.
As long as you still hold any one registered key, you can recover. If you think a key was exposed, re-key to a fresh set while you still hold another. If you lose all registered keys, the backups are unrecoverable — by design, and not something we can waive. Keep at least two keys, in two different places; the 24-word recovery card is the simplest durable fallback.
Your first backup slot is free, and additional metered slots are coming. For the recovery keys and their commands, see Zero-knowledge backups: your recovery keys; for the exact constructions and test vectors, the key derivation reference.