From c82ff767a35653a665fd889fd16eb8ba906bf48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Sun, 2 Aug 2026 16:39:35 +0200 Subject: [PATCH] Say in the runbook what a backup does not carry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every credential-shaped row is left out on purpose — API tokens, trusted devices, step-up elevations, known devices, clinician share links, and the grants behind shared record access. The per-model reasoning already lives in backup-plan.ts with a structural test behind it, but an operator planning a recovery does not read that file. The consequence differs by target and the difference is the part worth knowing. Restoring onto the same instance changes nothing: the restore replaces data tables and does not touch grants, so shared access carries on as it was. Restoring onto a fresh instance brings none of it, so both people invite and accept again before sharing works. That is the fail-safe direction, and it is better planned for than discovered. --- docs/ops/backup-restore.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/docs/ops/backup-restore.md b/docs/ops/backup-restore.md index 1d318164e..33fddad56 100644 --- a/docs/ops/backup-restore.md +++ b/docs/ops/backup-restore.md @@ -92,6 +92,33 @@ The script downloads the object, decrypts it, and writes the JSON dump to disk. Importing the JSON back into a HealthLog instance is left to the operator (use `prisma db seed` or a custom script). +### What a backup deliberately does not carry + +Every credential-shaped row is left out, and this is not an oversight to fix: +API tokens, trusted devices, step-up elevations, known devices, clinician share +links, and the account grants behind shared record access. Restoring data is +rolling a record back to a known state. Restoring an authorization is different +in kind, because a grant the owner revoked on Tuesday would come back alive out +of Monday's file with nobody deciding it and neither person told. + +What this means in practice depends on where you restore to. + +**Onto the same instance.** Nothing changes. The restore replaces the account's +data tables and does not touch grants, tokens or devices, so shared access +carries on exactly as it was. Somebody who had read access before the restore +still has it afterwards, now looking at the restored data. + +**Onto a fresh instance.** None of it comes with the file. Nobody has access to +anybody's record, every API token has to be reissued, every device re-trusted, +and both people have to invite and accept again before sharing works. That is +the fail-safe direction — access lost, never access resumed — and re-consenting +is the right amount of ceremony for handing someone your health record a second +time. Plan for it rather than discovering it. + +The full per-model reasoning lives in `src/lib/export/backup-plan.ts`, where +every excluded model carries a written verdict and a structural test refuses to +let a new model land without one. + ## Monthly restore drill (automatic) Since v1.16.4 a pg-boss job (`data-restore-drill`, cron `11 4 1 * *` —