From bd9e777f41a74671d41faa5a3a8b7d925ac91322 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Thu, 9 Jul 2026 22:47:22 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20v0.78.0=20REPORT=20=E2=80=94=20DELETE?= =?UTF-8?q?=20stage-secret=20deployed=20felhom-pve=20(56/56),=20live-valid?= =?UTF-8?q?ated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6 --- REPORT.md | 61 ++++++++++++++++++++----------------------------------- 1 file changed, 22 insertions(+), 39 deletions(-) diff --git a/REPORT.md b/REPORT.md index 505b5b9..e6d83f5 100644 --- a/REPORT.md +++ b/REPORT.md @@ -1,46 +1,29 @@ -# REPORT — agent v0.77.0: fork-4 escrow the offsite restic repo password under R +# REPORT — agent v0.78.0: DELETE /escrow/stage-secret (fork-4 hygiene) — DEPLOYED -**Date:** 2026-07-09 · **Class:** implementation (agent). **Baseline:** `main` @ `7f07393` (v0.76.0) → -`0c22b9b` (v0.77.0). Pairs with controller v0.105.0. Design validated by the custody spike -(`felhom.eu/documentation/audits/SPIKE-restic-password-custody-2026-07-09.md`, `febdc56`). +**Date:** 2026-07-09 · **Class:** implementation (agent, small). **Baseline:** v0.77.0 → **v0.78.0**, live +on felhom-pve (`felhom-agent 0.78.0`, capabilities self-check **56/56, degraded=0**). Part of the offsite +hardening bundle: pairs with controller v0.107.0 (calls this on every `EscrowState` flip to `escrowed`) and +hub v0.39.0 (F4/F2/F5). ## What shipped -Makes the restic-offsite repo password recoverable at DR by riding the existing customer-recovery-code (R) -zero-knowledge escrow (age-under-R, in `IdentityBundle`). Additive; the PBS-K escrow path is untouched. -- `internal/escrow/identity.go`: `IdentityBundle.ResticRepoPassword` (rides `WrapIdentityBundle`/ - `UnwrapIdentityBundle`, self-verified by `escrow.Create`); `AttachResticPassword` (mirrors `AttachWGKey`); - `StagedResticPasswordPath` + `WipeStagedResticPassword`. -- `internal/localapi`: `POST /escrow/stage-secret` (`withGuest` + `scopedFromBody`) stages the - controller-pushed password 0600 (atomic tmp+rename), **never logged** (field name only), overwritten on - re-push. Stage path injectable via `Options.EscrowStagePath` (default `StagedResticPasswordPath`). -- `cmd/felhom-agent/main.go` (`runSelftestEscrowCreate`): auto-injects the staged password into the bundle - (mirrors the WG-key auto-inject) and wipes the staging file after a successful `escrow.Create`. - -## Files changed (commit `0c22b9b`) -`internal/escrow/identity.go`, `internal/escrow/identity_test.go`, `internal/localapi/server.go`, -`internal/localapi/escrow_stage.go` (new), `internal/localapi/escrow_stage_test.go` (new), -`cmd/felhom-agent/main.go`, `CHANGELOG.md`, `CONTEXT.md`. +`internal/localapi`: **`DELETE /escrow/stage-secret`** (withGuest, bearer-authed) — removes the staged +offsite restic repo password (+ any stale `.tmp` partial). **Idempotent:** an absent file is a clean 200 +`{removed:false}`. Closes the fork-4 hygiene gap where a confirm WITHOUT a fresh ceremony (the password +already escrowed — the live e2e's Option-A close) left the transient 0600 staging file behind indefinitely +(only the escrow-create ceremony wiped it before). ## Tests -Green gate `go build ./... && go vet ./... && go test ./...` on the build host (age present) — **all green**. -New tests: -- `TestIdentity_RoundTrip_CarriesResticPassword` — the bundle carries `ResticRepoPassword` byte-exact, the - blob does not leak the plaintext, and a wrong R fails closed (no bundle). -- `TestAttachResticPassword` — missing staged file → clean no-attach; present → trimmed value attached; - empty → error. -- `TestStageEscrowSecret_StagesScopesAndHidesValue` — the pushed secret is staged 0600, the ack is - `{ok,data.staged:true}` (no value echoed), a cross-guest push is 403 and does not overwrite the staged file. -- `TestStageEscrowSecret_NoSecretInLog` — the staged value never appears in a captured log buffer. -Note: `TestGenerateRecoveryCode_EntropyAndFormat` is the documented pre-existing flake (a hyphenated -wordlist word splits to 11) — re-run passes; unrelated to this change. +`TestWipeStagedEscrowSecret`: stage → wipe (EFFECT: file GONE) → idempotent re-wipe (`removed:false`) → +401 unauthenticated. Full suite green (`go build && go vet && go test ./...`). -## Deploy verification -Built `felhom-agent 0.77.0` (`go build -ldflags -X main.version=0.77.0`), installed on felhom-pve (prior -binary backed up to `felhom-agent.bak-0.76.0`), `systemctl restart felhom-agent` → `--version` = 0.77.0, -`systemctl is-active` = active, **capabilities self-check ok=56 total=56 degraded=0**, local-api listening -on 192.168.0.162:8443, no errors/panics. +## Live validation +The endpoint was exercised for the one-off cleanup: the lingering +`/var/lib/felhom-agent/escrow-stage/restic_repo_password` (left by the e2e) was wiped through the +controller container over the pinned local-API channel → `{"removed":true}`, file verified GONE on +felhom-pve; an immediate re-wipe returned `{"removed":false}` (idempotency proven live). No secret value +was ever printed or logged. -## NOT yet live-validated -The supervised escrow ceremony (enable → stage → `--selftest=escrow-create` with a real R → confirm → -gated run) is the **operator-run** follow-up — NOT run here. The stage endpoint is deployed and unit-proven. -No agent publish (`publish-agent.sh`) / Day-0 manifest bump was done — that is a separate operator step. +## Deploy +Standard flow: built on 180 (`-X main.version=0.78.0`), scp'd via local → felhom-pve, `.bak-0.77.0` kept, +`install -m0755` + restart. `configs/` unchanged → no sudoers/wrapper shipping needed. NOT published to +Gitea (no Day-0 vouch change; the Day-0 manifest still vouches 0.76.0).