v0.105.0: fork-4 offsite password custody — hand-off + atomicity gate + DR inject + coord
Pairs with agent v0.77.0. StageEscrowSecret pushes the repo password to the agent (POST /escrow/stage-secret) at offsite-enable → EscrowState="pending". Atomicity gate: RunOffboxBackup (scheduler + handler) refuses until EscrowState="escrowed" (operator POST /backup/offbox/confirm-escrow after the escrow ceremony) — no un-recoverable offsite ciphertext can exist. DR: POST /backup/offbox/inject-password pre-places a recovered 64-hex password 0600 (honored by WriteOffboxSecrets' IsNotExist guard; refuses clobber without force). DR recipe gains non-secret offsite_restic coords (DRResticCoord); SFTP key regenerated at DR, not escrowed. New settings.OffboxTarget.EscrowState. Tests + atomicity & inject companion red-proofs green; UI gates pass. NOT yet live-validated (supervised ceremony). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
+16
-2
@@ -716,8 +716,22 @@ not just those with HDD data. Non-HDD apps can configure destination, method, an
|
||||
> anywhere) is a **hard error** → `LastStatus="error"` + operator alert (was a misleading `ok`/0 snapshots).
|
||||
> A *partial* run (some units missing) stays `ok` but sets a Hungarian **`LastWarning`** naming the skipped
|
||||
> apps, shown on `/backups`.
|
||||
> - **Secrets** (SSH key + auto-gen repo password) are **0600 files in the data dir** — never logged/committed;
|
||||
> they ride DR via the PBS whole-CT snapshot of the rootfs (the recovery-unit/dr-recipe stay secret-free).
|
||||
> - **Secrets** (SSH key + auto-gen repo password) are **0600 files in the data dir** — never logged/committed.
|
||||
> - **Password custody + atomicity (v0.105.0, fork-4; pairs with agent v0.77.0).** The repo password is the
|
||||
> irreplaceable DATA key for the offsite tier, so it rides the **customer-recovery-code (R) escrow**
|
||||
> (age-under-R, in the agent's `IdentityBundle` — custody spike validated a recovered password opens the
|
||||
> real repo). **Atomicity gate:** enabling offsite pushes the password to the agent (`StageEscrowSecret` →
|
||||
> `POST /escrow/stage-secret`) and marks `EscrowState="pending"`; **no offsite backup runs until the escrow
|
||||
> is confirmed** (`OffboxRunnable()`), so an un-recoverable offsite copy can never exist.
|
||||
> **Operator ceremony (pilot, supervised):** enable offsite (→ pending) → run
|
||||
> `felhom-agent --selftest=escrow-create --identity-bundle <assembled> --upload` (the bundle now carries
|
||||
> the staged restic password, auto-injected, then wiped) → hand the customer the fresh **R** (once;
|
||||
> supersedes any prior code) → `POST /backup/offbox/confirm-escrow` (or the "Letét megerősítése" button).
|
||||
> **DR:** recover R → the escrow yields the password → `POST /backup/offbox/inject-password {password}`
|
||||
> pre-places it 0600 → configure offbox → restore. The SFTP access key is **regenerated** at DR (a fresh
|
||||
> sub-account key), NOT escrowed; the DR recipe carries only the non-secret `offsite_restic`
|
||||
> coordinates (`DRResticCoord`). *(A hub-verified auto-confirm + customer-self-serve enable + fresh-R UX
|
||||
> are the provisioning task, deferred.)*
|
||||
> - **Injection guard** (`ValidateOffboxTarget`): host/user/repo must not start with `-` (ssh
|
||||
> option-injection) or carry metacharacters/traversal; `OffboxConfigured` fails closed on an invalid
|
||||
> target. Image: `restic` + `openssh-client` (re-added; restic's sftp backend shells out to `ssh`).
|
||||
|
||||
Reference in New Issue
Block a user