53 lines
3.8 KiB
Markdown
53 lines
3.8 KiB
Markdown
# TASK — agent: identity-only escrow ceremony (K-optional) — unblocks no-PBS customers
|
|
|
|
<!--
|
|
CLASS: Implementation (agent only, small). BLOCKER it removes: escrow.Create hard-requires the PBS key K
|
|
(escrow.go:64 "KeyPath ... is required") and runSelftestEscrowCreate dies without a PBS storage id + key
|
|
file — so a customer WITHOUT the PBS tier (Peti: BYO, PBS deliberately skipped) cannot run the ceremony
|
|
at all, which blocks fork-4 custody + auto-confirm for exactly the customer class most likely to skip
|
|
PBS. Fix: an identity-only mode — wrap the IdentityBundle (restic password, tunnel/pbs tokens, WG key)
|
|
under a fresh R with age, self-verify, upload; skip every K step. WRITTEN BY: project-Claude. BY: CC.
|
|
-->
|
|
|
|
## 0. Scope & baseline
|
|
felhom-agent v0.79.0 (re-confirm live head) → **v0.80.0**. No controller/hub change: the upload wire
|
|
shape already carries `restic_pw_sha256` + the blob; auto-confirm matches the hash — K is irrelevant to it.
|
|
|
|
## 1. Design
|
|
- `escrow.CreateOptions.KeyPath == ""` becomes VALID **iff** `IdentityBundle != nil` → identity-only mode:
|
|
skip `KeyFingerprint`, skip the K `Wrap`, skip paperkey; generate R exactly as today; `WrapIdentityBundle`
|
|
under R; **self-verify by unwrapping the identity blob** (the "an escrow you haven't recovered isn't an
|
|
escrow" rule applies to the identity path too — today only K is self-verified; identity-only mode MUST
|
|
self-verify the identity blob); upload with `KeyFingerprint` empty/omitted.
|
|
- `runSelftestEscrowCreate`: when no `-storage` AND `escrow.pbs_storage_id` empty → do NOT die; log
|
|
"no PBS storage — identity-only escrow" and proceed iff there is anything to escrow (staged restic
|
|
password and/or bundle file and/or WG key); if truly nothing to wrap → clear error ("nothing to escrow").
|
|
- K present (demo & PBS customers) → behavior byte-identical to today (K + identity, both self-verified).
|
|
- Hub: verify `SaveHostEscrow`/upload handler tolerate an empty key fingerprint (read the handler; if it
|
|
rejects empty, a one-line relaxation on the hub side joins this task — re-confirm at source, do not assume).
|
|
|
|
## 2. R semantics (unchanged, restate in the doc)
|
|
Fresh R per ceremony, displayed once, never retained; supersedes the customer's previous R; the old blob
|
|
stays valid for old history only.
|
|
|
|
## 3. Tests (non-hollow + red-proofs)
|
|
- Identity-only: no KeyPath + bundle with `restic_repo_password` → blob created, **self-verify unwrap
|
|
byte-exact**, upload payload has the blob + `restic_pw_sha256`, no K ops attempted (fake records).
|
|
**Red-proof:** restore the KeyPath-required guard → identity-only test fails.
|
|
- Self-verify red-proof: corrupt the blob before verify → ceremony FAILS, nothing uploaded.
|
|
- Nothing-to-escrow: no K, no staged pw, no bundle, no WG key → clear refuse.
|
|
- K path regression: with KeyPath → identical call sequence to v0.79.0 (golden assertions).
|
|
|
|
## 4. Deploy / live
|
|
Build v0.80.0 → felhom-pve (demo agent) → healthy, 56/56 caps. Publish 0.80.0 to Gitea + bump the hub
|
|
Day-0 agent manifest (the publish-train pattern; the operator-sign step is Viktor's 🛑 as per GL-1).
|
|
**Peti's agent update path:** the agent self-update is operator-signed + pinned — confirm from the go-live
|
|
record how a BYO agent updates (self-update channel armed at his install? operator pubkey file was NOT
|
|
passed on his install form) — if his box cannot self-update the agent, REPORT must say so and the ceremony
|
|
waits for the next Peti-touch window (he runs one update command). Do not improvise a new update path.
|
|
|
|
## NOT to do
|
|
Do not weaken the K path or its self-verify; do not skip the identity self-verify; do not change the R
|
|
generation/display; do not touch controller/hub auto-confirm logic; do not run a ceremony on any real box
|
|
from this task (unit + demo-agent deploy only).
|