docs(wiki): settle on-site encrypted backup + disaster-recovery design

New concept page backup-recovery.md resolving the design half of open-question #5.
Driving scenario: a stolen/destroyed PC whose LUKS+TPM disk is unrecoverable by
design — recovery stands up a NEW PC, restores a backup, and keeps signing the
SAME chain.

Settled: admin-driven encrypted full-DB backup (SQLite online-backup/VACUUM INTO,
snapshots included) to local/USB, SMB/NFS, or SFTP targets; manual button + an
in-process daily timer; keep-last-N + dailies retention; restore is admin-only /
out-of-band (operator-adversary surface). A restored copy must still verifyChain.

Key custody (the load-bearing decision, bears on #6): three independent keys —
EVENT_SIGNING_KEY kept an extractable, escrowed software key DECOUPLED from the
TPM so the ledger survives total hardware loss (the conscious trade: a TPM-sealed
signing key would be unforgeable but permanently unverifiable after the machine
dies); a NEW dedicated park_buzi_backup_key in Komodo for backup encryption,
separate from the signing key; the LUKS/TPM disk key, appliance-only and
deliberately non-recoverable. Keys are never inside the backup they unlock.

Updated open-questions #5 (design SETTLED) + #10 note; disk-os-hardening deploy
runbook (why the signing key is not sealed + park_buzi_backup_key); index catalog
+ concept count. Design only — not yet built.

Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
2026-06-29 11:43:23 +02:00
parent 11567a417f
commit 9e442586af
5 changed files with 174 additions and 11 deletions
+16 -8
View File
@@ -2,7 +2,7 @@
type: decision
tags: [parking, decisions, open]
sources: [parking-system-architecture]
updated: 2026-06-21
updated: 2026-06-29
status: open
---
@@ -23,13 +23,18 @@ procurement. (See [[parking-system-architecture]] §10.)
4. **Reconciliation channel.** Even if "offline," establish *some* periodic path (USB, hotspot,
manager visit) to reconcile the signed log against an external authority — the real anti-fraud
control. See [[reconciliation]].
5. **Durability / backup.** Backup strategy for the [[sqlite]] database + recovery plan; "sync
later" currently leaves a disk failure as **total revenue-history loss**. _(Confirmed in-scope
to design, 2026-06-15.)_ Because the DB is the signed [[append-only-event-chain]], a backup must
preserve the chain intact (a restored copy must still `verifyChain`); options include SQLite
WAL/online-backup snapshots to a second disk/USB + the periodic external export that doubles as
the [[reconciliation]] channel (#4). Encryption at rest already applies ([[disk-os-hardening]]).
Design TBD.
5. **Durability / backup.** _(Design SETTLED 2026-06-29 — see [[backup-recovery]]; implementation
pending.)_ A disk failure / stolen-or-destroyed PC currently leaves **total revenue-history loss**.
Settled design: an **admin-driven encrypted full-DB backup** (online-backup/`VACUUM INTO`, snapshots
included) to a **local/USB · SMB/NFS · SFTP** target, **manual button + in-process daily timer**,
**keep-last-N + dailies** retention, encrypted with a **dedicated `park_buzi_backup_key`** (separate
Komodo secret, *not* the signing key). Recovery = backup file **+** the two escrowed keys held
out-of-band; a restored copy must still `verifyChain`. **Key-custody stance:** `EVENT_SIGNING_KEY`
stays **decoupled from the TPM** (an extractable, escrowed software key) precisely so it survives
total hardware loss — the conscious trade against #6 (a TPM-sealed signing key would be unforgeable
but **unverifiable after the machine dies**). **Restore is admin-only/out-of-band** (operator-adversary
surface — [[threat-model]]). See [[backup-recovery]], [[fleet-deployment-komodo]], [[disk-os-hardening]],
[[reconciliation]] (#4).
6. **Secure-element integration.** Confirm [[atecc608]] wiring/usage on the host (event
signing). The [[esp32-custom-controller]] command-authentication use is **deferred — not
being implemented for now** (access control is the [[dingtian-relay]] behind
@@ -62,6 +67,9 @@ procurement. (See [[parking-system-architecture]] §10.)
reclaim deleted-blob pages without `VACUUM`. **Undecided:** pruning policy (age-based vs.
total-size cap), VACUUM cadence, and how this interacts with the #5 backup strategy (blobs
bloat every backup). Until decided, snapshots accumulate unbounded. See [[entry-exit-points]].
_(Update 2026-06-29: pruning is now disk-pressure based — see [[entry-exit-points]]; and the
settled #5 backup includes snapshot BLOBs by default, with a noted future "exclude snapshots"
toggle since they dominate backup size — see [[backup-recovery]].)_
11. **Appliance OS image → WebKitGTK version (Tauri dependency).** _(Raised by
[[desktop-shell-tauri]], 2026-06-21; narrowed same day.)_ The chosen
[[desktop-shell-tauri|Tauri v2 desktop shell]] renders through the **host's WebKitGTK**, not a