spike(pin-mismatch): follow-up — aside-var-lib holds matching token store; R1 = one-copy fix for pin+token
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EPZ4GJ8L5Jqf8UiPwbn1kt
This commit is contained in:
@@ -179,7 +179,37 @@ the old token store), or the symptom merely changes from `TLS pin mismatch` to `
|
|||||||
|
|
||||||
**Token store (applies to R1/R2):** also re-seed guest 9201's bearer token into
|
**Token store (applies to R1/R2):** also re-seed guest 9201's bearer token into
|
||||||
`/var/lib/felhom-agent/local-tokens.log` (re-provision token mint, or restore the old token store
|
`/var/lib/felhom-agent/local-tokens.log` (re-provision token mint, or restore the old token store
|
||||||
from the same `aside-var-lib` set-aside if present), else expect a `401` after the pin is fixed.
|
from the same `aside-var-lib` set-aside), else expect a `401` after the pin is fixed.
|
||||||
|
|
||||||
|
### Follow-up CONFIRMED (2026-06-29) — `aside-var-lib` holds the matching token store → R1 is one copy
|
||||||
|
|
||||||
|
The set-aside **does** contain the pre-migration token store, and it matches guest 9201's
|
||||||
|
*current* controller token, so **R1 fixes the pin and the token blocker in a single restore**:
|
||||||
|
|
||||||
|
```
|
||||||
|
/root/agent-backup-bundle-test/aside-var-lib/local-tokens.log
|
||||||
|
656 bytes, 8 records, mtime 2026-06-26 19:56 (pre-migration)
|
||||||
|
effective (last-write-wins) vmids: 9200, 9201
|
||||||
|
vs live /var/lib/felhom-agent/local-tokens.log : 0 bytes, mtime 2026-06-28 08:56 (reset at migration)
|
||||||
|
```
|
||||||
|
|
||||||
|
Verified on-host (token plaintext/hashes never left the host; only the verdict was emitted): the
|
||||||
|
agent stores `{"v":<vmid>,"h":hex(sha256(token))}` JSONL (`internal/localapi/tokenstore.go`,
|
||||||
|
last-write-wins per vmid). The SHA-256 of the controller's **current** `controller.yaml`
|
||||||
|
`local_api.token` (the line under `local_api:`, **not** the unrelated `git:`/`hub:` tokens in the
|
||||||
|
same file) is **present in the old store under vmid 9201**. So:
|
||||||
|
|
||||||
|
- old leaf fp `60b5974d…` **==** `PIN_FP` (and `SEED_FP`) ✓
|
||||||
|
- old store's effective 9201 token hash **==** controller's current `local_api.token` hash ✓
|
||||||
|
|
||||||
|
**Therefore the cleanest remedy is R1 extended to three files:** restore
|
||||||
|
`local-api.crt`, `local-api.key`, **and** `local-tokens.log` from `…/aside-var-lib/` →
|
||||||
|
`/var/lib/felhom-agent/`, `chown felhom-agent:felhom-agent` (crt `0644`, key/tokens `0600`),
|
||||||
|
restart the agent. The agent then *loads* (not regenerates) the old leaf and re-indexes the old
|
||||||
|
token store; the controller's existing pin **and** token both validate, **with zero in-guest
|
||||||
|
change**. (Caveat: this reinstates the pre-migration leaf `60b5974d…` rather than adopting the
|
||||||
|
new `ced34036…` — fine for restoring service; if the operator wants the new leaf to be canonical,
|
||||||
|
that's R2/R3 instead, both of which still need the token re-seed handled separately.)
|
||||||
|
|
||||||
**Forward-looking:** the root→non-root migration runbook should **carry the existing
|
**Forward-looking:** the root→non-root migration runbook should **carry the existing
|
||||||
`local-api.{crt,key}` and `local-tokens.log` into the new data dir** (or treat their loss as a
|
`local-api.{crt,key}` and `local-tokens.log` into the new data dir** (or treat their loss as a
|
||||||
@@ -196,8 +226,10 @@ incident.
|
|||||||
migration mtime is strong evidence; not *proven* live because the TLS pin fails before any token is
|
migration mtime is strong evidence; not *proven* live because the TLS pin fails before any token is
|
||||||
evaluated, and probing it would require an authenticated call (out of scope for read-only). Operator
|
evaluated, and probing it would require an authenticated call (out of scope for read-only). Operator
|
||||||
should expect it and plan the token re-seed alongside whichever pin remedy is chosen.
|
should expect it and plan the token re-seed alongside whichever pin remedy is chosen.
|
||||||
- **Not assessed:** whether `…/aside-var-lib/` also holds the matching pre-migration
|
- **Resolved (was "not assessed"):** `…/aside-var-lib/` **does** hold the matching pre-migration
|
||||||
`local-tokens.log` (would make R1 + token restore a single copy). Cheap to check before choosing.
|
`local-tokens.log`, and its effective 9201 token hash equals the controller's current
|
||||||
|
`local_api.token` hash — so R1 restored as three files (crt+key+tokens) fixes pin **and** token in
|
||||||
|
one copy, zero in-guest change. See §7 follow-up.
|
||||||
|
|
||||||
*No secrets recorded: the per-guest bearer token is referenced as "stored out-of-band"; the leaf
|
*No secrets recorded: the per-guest bearer token is referenced as "stored out-of-band"; the leaf
|
||||||
fingerprint is not a secret.*
|
fingerprint is not a secret.*
|
||||||
|
|||||||
Reference in New Issue
Block a user