docs: SLICE 3 — hub README, REPORT, CONTEXT
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
+12
@@ -3,6 +3,18 @@
|
||||
> Created with the REUSE.md rollout (2026-07-03). Authoritative history: `hub/CHANGELOG.md` (hub),
|
||||
> `website/CHANGELOG.md`, `scripts/CHANGELOG.md`; end-of-task detail in `REPORT.md`.
|
||||
|
||||
- **2026-07-09 — SLICE 3 hub-verified escrow auto-confirm SHIPPED+LIVE (hub v0.40.0 + controller v0.108.0 +
|
||||
agent v0.79.0).** Replaces the operator-trust confirm with a verified fact: ceremony hashes the sealed
|
||||
repo password (agent, `restic_pw_sha256,omitempty` on the escrow upload — contract test moved in lockstep)
|
||||
→ hub stores it (additive `host_escrow` migration, NULL on legacy rows) + serves
|
||||
`escrow:{identity_blob_present,restic_pw_sha256,created_at}` in the report ACK → controller
|
||||
(`report.EscrowAutoConfirmer`) flips pending→escrowed ONLY on hash match with its local repo password.
|
||||
**Red-proofed core: blob-presence alone never confirms** (stale blob = false custody claim); mismatch
|
||||
warns once per hash naming the ceremony; never un-confirms; flip wipes the agent-staged secret. Hashers
|
||||
pinned by the same cross-repo vector. Manual confirm = deprecated fallback (legacy blobs — demo included,
|
||||
hash-NULL verified live; the escrowed demo produced zero confirm activity = Scenario E live). Full happy
|
||||
chain proves out at the next real enable (Peti). NEXT: SLICE 4 soft-quota, Peti runbook.
|
||||
|
||||
- **2026-07-09 — offsite hardening bundle SHIPPED+LIVE (hub v0.39.0 + controller v0.107.0 + agent v0.78.0).**
|
||||
The e2e's sharp edges closed before slices 3–4: **F4** "Re-issue offsite credentials" (explicit operator
|
||||
recovery for consumed-password dead-ends — exactly-1 label scope, fresh one-time secret, ConfigVersion
|
||||
|
||||
@@ -2,32 +2,33 @@
|
||||
|
||||
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
|
||||
|
||||
## TASK — offsite provisioning hardening (F2/F4/F5 + key-auth-first + staged-secret wipe) — 2026-07-09 — DEPLOYED
|
||||
## TASK — offsite SLICE 3: hub-verified escrow auto-confirm — 2026-07-09 — DEPLOYED
|
||||
|
||||
**Shipped (felhom.eu):** hub **v0.39.0** `17cc67f` + bump `17d9af5` — LIVE (Synced/Healthy, provisioner
|
||||
enabled). Bundle pairs: controller **v0.107.0** (key-auth-first bridge + wipe-on-escrowed; live on 9201) +
|
||||
agent **v0.78.0** (`DELETE /escrow/stage-secret`; live on felhom-pve, 56/56). All three green-gated with
|
||||
companion red-proofs.
|
||||
**Shipped (felhom.eu):** hub **v0.40.0** `49d1233` + bump `c24d4af` — LIVE (Synced/Healthy). Chain pairs:
|
||||
agent **v0.79.0** (felhom-pve, 56/56) + controller **v0.108.0** (9201, healthy) — all live. Operator-free
|
||||
task (Viktor ran nothing).
|
||||
|
||||
**Hub changes:**
|
||||
- **F4 (pilot-gating) — "Re-issue offsite credentials":** `Provisioner.ReissueCredentials` + UI button
|
||||
(confirm-gated, shown only when provisioned) + `POST /configs/{id}/offsite-reissue`. Resets the
|
||||
sub-account password (or dedicated-box password via the new `hetznerapi.ResetBoxPassword`), stores a
|
||||
FRESH one-time secret, re-saves the config unchanged → `ConfigVersion` bump → the stuck guest's next
|
||||
refresh re-runs the bridge. **Hard-scoped:** refuses unless the `felhom-customer=<id>` label lookup finds
|
||||
exactly 1 resource (red-proofed). Explicit action only — never implicit rotation. Password never logged.
|
||||
- **F2:** `scanWithRetry` — the host-key scan retries through fresh-subaccount DNS lag (2/4/8/16/30s ≈ 60s,
|
||||
inside the F1 3-min detached ctx; fail-closed past budget; red-proofed).
|
||||
- **F5:** the config form disables its submit buttons + shows an in-flight notice on submit (the re-click
|
||||
bait that caused live F1).
|
||||
**The verification chain:** the ceremony hashes the staged repo password it seals (agent) → the hub stores
|
||||
`restic_pw_sha256` alongside the escrow blob (additive migration; NULL on legacy rows) and serves
|
||||
`escrow:{identity_blob_present, restic_pw_sha256, created_at}` in the **report ACK** → the controller flips
|
||||
offbox `EscrowState` pending→escrowed ONLY on `sha256(local repo_password)` match. **Blob-presence alone
|
||||
never confirms** — a stale blob (re-provision/inject/history) would be a false custody claim re-opening the
|
||||
fork-4 gap; this is the red-proofed core (blob-present-only check → stale-blob test flips → FAIL).
|
||||
Mismatch → pending + loud warn naming the ceremony (deduped per hash); never un-confirms. On flip the
|
||||
agent-staged secret is wiped (v0.107.0 path). The two hashers are pinned by the SAME cross-repo test vector
|
||||
(trimmed-string sha256). Manual confirm-escrow → documented deprecated fallback for legacy hash-less blobs.
|
||||
|
||||
**One-off cleanup (executed):** the staged secret lingering on felhom-pve from the e2e's Option-A confirm
|
||||
was wiped through the NEW agent endpoint (controller container → pinned local API → `{"removed":true}`),
|
||||
verified gone; idempotent re-wipe returned `{"removed":false}`. No secret printed.
|
||||
**Hub specifics:** `host_escrow.restic_pw_sha256` migration; `SaveHostEscrow`/`HostEscrow`/`GetHostEscrow`
|
||||
NULL-safe; `GetEscrowStatusForCustomer` (hosts⋈host_escrow, latest-updated wins); ACK object omitted when
|
||||
no escrow row (fresh customers stay silently pending); `TestEscrowUploadContract` mirrors agent v0.79.0.
|
||||
|
||||
**Deliberately NOT exercised live:** the F4 reset itself (it would rotate the demo's working credential —
|
||||
touching it is forbidden; a live exercise needs a throwaway customer under supervision). Unit red-proofs
|
||||
cover the guards. F5 is template JS — verified on the next operator save.
|
||||
**Live state check (no operator action):** migration applied on the production DB — all 3 legacy rows
|
||||
(demo included) read hash-NULL; the demo's `escrowed` target produced **zero** `escrow-confirm` controller
|
||||
log lines after reports through the new hub (Scenario E — never-revisit — proven live for free); no hub
|
||||
errors.
|
||||
|
||||
**NEXT:** SLICE 3 (escrow auto-confirm — inherits wipe-on-escrowed), SLICE 4 (soft-quota on `quota_gb`),
|
||||
NEW-box restore round-trip → retire the old-box archive, Peti onboarding runbook.
|
||||
**NOT yet live-exercised:** the full happy chain (fresh enable → ceremony records the hash → ACK →
|
||||
auto-flip) — the first real offsite enable (Peti onboarding) proves it; unit red-proofs carry the logic.
|
||||
|
||||
**NEXT:** SLICE 4 (soft-quota on `quota_gb`), Peti onboarding runbook (live-exercises auto-confirm + F4
|
||||
re-issue), NEW-box restore round-trip → retire the old-box archive.
|
||||
|
||||
+6
-1
@@ -89,7 +89,12 @@ host-key scan retries through fresh-subaccount DNS lag (~60s ladder, F2); the sa
|
||||
in-flight notice (F5); and **"Re-issue offsite credentials"** (F4, `POST /configs/{id}/offsite-reissue`) is
|
||||
the explicit recovery for a consumed-password dead-end — resets ONLY the resource labelled for that customer
|
||||
(refuses unless exactly 1), stores a fresh one-time secret, bumps `ConfigVersion`. Never implicit rotation.
|
||||
SLICE 3 (escrow auto-confirm) and SLICE 4 (soft-quota) follow.
|
||||
**SLICE 3 (v0.40.0) — hub-verified escrow auto-confirm:** the agent's ceremony upload carries
|
||||
`restic_pw_sha256` (non-reversible hash of the sealed offsite repo password — safe to store/serve); the hub
|
||||
stores it on `host_escrow` (NULL on legacy rows) and serves
|
||||
`escrow:{identity_blob_present, restic_pw_sha256, created_at}` in the **report ACK**; the controller
|
||||
auto-confirms its pending offbox escrow ONLY on a hash match with its current repo password (blob-presence
|
||||
alone never confirms). SLICE 4 (soft-quota) follows.
|
||||
|
||||
### Infrastructure Backup — RETIRED (Phase-1, 2026-06-16, hub v0.12.0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user