hub v0.159.0 (R-1154, after security review): the enroll reuse path re-issues nothing, it warns the operator
The first draft (5121536f, unpushed) re-issued the claim code and the off-site login on a
reuse whose old box was stale or switched off. A security review flagged it: the caller
holds only the household's retrieval passphrase, and both re-issues are operator
session-only actions (05 section 17.5, 09 decision 252, R-1055/R-1059). Now the reuse
path classifies the old box and re-issues nothing: gone -> host_reinstall_over_old_host
(warning, mailed to the operator: delete the old host and re-run, or re-issue by hand);
live -> host_reenroll_while_live (info). The mint path after the operator's delete is
unchanged and still re-issues. The once-per-silence record and the claim engine comment
edit are reverted. 05 section 8, README and CHANGELOG updated; tests red-proved.
This commit is contained in:
@@ -222,24 +222,23 @@ Today: `GET /config/{id}` with an `X-Retrieval-Password` (Hungarian passphrase)
|
||||
The existing `configgen` deep-merge + Hungarian-passphrase machinery is the base; it grows the
|
||||
agent-first + key-pinning + restore-mode steps.
|
||||
|
||||
**A reinstall over an existing host record re-issues when the old box is gone [DESIGN, 2026-10-19 — R-1154, brief
|
||||
**A reinstall over an existing host record is made loud, never acted on [DESIGN, 2026-10-19 — R-1154, brief
|
||||
2026-10-19; hub v0.159.0].** `POST /host-enroll` is the installer's step 4, run on every pass (a `--resume` too), with
|
||||
the customer's passphrase; an existing host record is REUSED (same id and key — the reinstalled box takes it over).
|
||||
The clean-slate re-issues (the claim code, the off-site login — both live in the CONTROLLER) used to run only when a
|
||||
record was minted, so a reinstall that kept the old record skipped both in silence. The reuse path now runs them
|
||||
when, and only when, the old box is gone: **no controller wait connection open now**, and either the household
|
||||
switched the box off on purpose (`deliberate_off_at` inside its hold) or **both** the agent's host report and the
|
||||
controller's report are older than `alerting.stale_threshold` (or absent) — the threshold and comparison
|
||||
`hostStatus` uses, no second definition. **Once per silence:** not again when it already ran since the host's last
|
||||
report (an installer `--resume` before the new agent's first report). **Why this rule and not "re-issue on every
|
||||
reuse":** a live box re-enrolls legitimately (a `--resume` after its agent started, a repair re-run), and re-issuing
|
||||
there rotates the household's claim code and resets its off-site login under a running box; not re-issuing costs a
|
||||
reinstall two operator presses, which the skip record now names. The controller report counts because the codes
|
||||
live there: a box whose agent is broken but whose controller reports is live. **Known residual:** a reinstall done
|
||||
less than the threshold after the old box's last report is still treated as live — it is recorded
|
||||
(`host_reenroll_not_reissued`, operator-only, info) instead of silent, and the operator presses the two buttons or
|
||||
deletes the old host first. The re-issue writes `host_reenroll_reissued` (also the once-per-silence record); both
|
||||
types are hub-origin only. `hub/internal/api/reenroll.go`, pinned by `hub/internal/api/r1154_reenroll_test.go`.
|
||||
the customer's retrieval passphrase; an existing host record is REUSED (same id and key — the reinstalled box takes
|
||||
it over). The clean-slate re-issues (a new claim code mailed to the household, the off-site provider password reset)
|
||||
run only on the MINT path, i.e. after the operator deleted the old host — **the operator's delete is their gate,
|
||||
and stays so.** A reinstall that kept the old record used to skip them in silence. Now the reuse path classifies the
|
||||
old box and re-issues NOTHING: **gone** (no controller wait connection open now, and either `deliberate_off_at`
|
||||
inside its hold or BOTH the host report and the controller report older than `alerting.stale_threshold` or absent —
|
||||
the `hostStatus` threshold and comparison) → the operator-only WARNING `host_reinstall_over_old_host`, mailed to the
|
||||
operator: delete the old host (Hosts page) and run the installer again, or re-issue the claim code and the off-site
|
||||
login from the customer page; **live** → the operator-only INFO `host_reenroll_while_live`, recorded, never mailed.
|
||||
**Why not re-issue automatically** (a security review of the first draft, the same day): the passphrase is a
|
||||
household-held secret typed into the installer, and both re-issues are operator SESSION-ONLY actions — not even an
|
||||
operator token may run them (§17.5; `09` §3 decision 252, R-1055/R-1059: an off-site re-issue „stops its backup for a
|
||||
while"). Re-issuing on the reuse path would give those powers to anyone holding the passphrase whenever the box is
|
||||
switched off or silent. The cost of the loud shape is two operator acts per reinstall that kept its old record. Both
|
||||
event types are hub-origin only. `hub/internal/api/reenroll.go`, pinned by `hub/internal/api/r1154_reenroll_test.go`.
|
||||
|
||||
## 9. DR model
|
||||
|
||||
|
||||
Reference in New Issue
Block a user