docs(secrets): state that every secret must be decryptable by the desktops

The desktops hold the trusted admin keys and are where secrets are edited and
rekeyed from; narrowing a set to the servers alone breaks agenix -r and drops
the offline recovery key.
This commit is contained in:
Ryan Yin committed 2026-09-21 20:50:11 +08:00
1 parent a43aa02a69
commit 89e57b5b39
2 files changed
+11 -12

No files matched your search

+4 -3
View File
@@ -47,6 +47,10 @@ Consequences worth remembering:
is the only way to restore its data.
- restic's own password is never stored inside a backed-up tree: `etc/agenix` and all key material
are excluded (see below).
- Recipients follow the secrets repository's rule: every secret is decryptable by the desktops
(`desktop_keys`, which also carries the offline `recovery_key`), so a desktop can edit or rekey
anything and no secret becomes unrecoverable when a host is lost. The desktop repository password
is the one secret the servers do not get.
## Schedule
@@ -139,9 +143,6 @@ Restoring a btrbk snapshot (offline; stop writers first):
is the layer which survives a compromised host.
- **`restic check` timer**: periodic integrity verification, on the host that holds the password.
- **Metrics**: run rest-server with `--prometheus` and chart repository growth in Grafana.
- **Recovery key for the homelab password**: `restic-password-homelab.age` is encrypted only to the
storage hosts' keys, so losing youko's host key makes it unrecoverable. Adding the offline
`recovery_key` to that group fixes it without weakening the desktop/homelab split.
## Components
+7 -9
View File
@@ -22,17 +22,15 @@ decrypt all my secrets via `agenix`. Then, I can use them in this flake.
## Which Keys Go on a Secret
Changing a secret's recipients is **two** questions, and both have to be answered:
**Every secret must be decryptable by the desktops.** The desktops hold the trusted admin keys, and
they are where secrets are added, edited and rekeyed — including `agenix -r`, which has to decrypt
every secret in this repository first. Narrowing a secret to the servers alone breaks that.
- **Who must be able to read it?** Only the hosts that actually need it. Splitting by trust domain
(desktops, servers, one application) keeps a compromised host from reading secrets it has no
business reading.
- **How is it recovered when those hosts are gone?** Every set must keep `recovery_key`. It is held
offline and on no machine, so it does not widen who can read a secret — but without it, the secret
is unrecoverable once the machines that could decrypt it are lost.
So every recipient set is `desktop_keys ++ <the hosts that need it>`, and `desktop_keys` carries the
offline `recovery_key`; a lost host therefore never makes a secret unrecoverable.
Narrowing a secret's recipients is where this bites: it is easy to drop the offline key along with
the hosts being removed. Re-check both questions after any recipient change.
The one exception is the desktop's own restic repository password (`restic-password-desktop.age`):
`desktop_keys` alone, because the backup servers must not be able to read desktop data.
## Adding or Updating Secrets