Stage E ratified: unattended identity is cert+personality only, no seed (FABRIC-3.md §XXXII.2)
Settles all 4 open questions on paper, no code: - No seed baked into capsules for this pass (Bob's call); runtime-minted seed documented as a future, separately-scoped possibility - Birth via capsule_birth_baby() (unmodified, already generic), not capsule_runcap_birth() -- that path requires a real blkio_dev*+ homeblocks_sig_t* an unattended identity can't provide, and its own header says build-time-baked content is exactly the wrong case for it - Identity population is the same post-birth struct-assignment pattern capsule_wirebind.c already uses live (vm->identity = identity) - §XXIV's block-collision machinery already covers a cert-carrying capsule -- no new risk, no change needed there - ACL gate lives on the attaching human's credentials, since an unattended instance holds no secret to prove anything about itself - xHCI/live-table machinery confirmed irrelevant, independent of the seed question One real wrinkle flagged, not resolved: vm_identity_from_cert()'s serial-number check binds to a physical drive_uuid an unattended identity doesn't have -- needs Bob's call before implementation. Punch list recorded; implementation not started per standing "plan approval is not a start signal" rule. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
42d4bf3dad
commit
06e2507ce4
+75
@@ -4297,6 +4297,81 @@ whatever code implements unattended birth.
|
||||
unattended identity's own lifecycle (no `blkio_dev`, no device to attach/detach) before
|
||||
assuming the two paths share no state.
|
||||
|
||||
**Ratified, 2026-09-16 -- all four questions settled on paper, no code written.** Traced,
|
||||
not assumed: `vm_identity.h`'s own header comment says outright "no seed/private material
|
||||
belongs here at all" (line 29), and `user_identity_seed.h:25` states the running system's own
|
||||
verify path checks "these two alone" -- cert + pubkey, never the seed. Confirmed live:
|
||||
`capsule_wirebind_verify_cert()` only ever reads and verifies (§XXVIII's BINDSTEP re-check is
|
||||
the same function, same direction); nothing in the attach/verify path signs as the identity
|
||||
being checked. **Decision (Captain Bob, 2026-09-16): unattended identities carry cert +
|
||||
personality only, never a seed, for this pass.** A future runtime-minted-seed path (an
|
||||
instance that signs as itself) is a documented possibility, explicitly out of scope here --
|
||||
if it's ever built, it must mint at runtime into a non-persisted/fenced location, never bake a
|
||||
seed into a git-committed capsule.
|
||||
|
||||
This collapses all four questions:
|
||||
|
||||
1. **Packaging -- a new capsule content convention, not a new `mkcapsule` mode or MINT
|
||||
variant.** No seed means no secret-handling in the build tool at all: the DER cert
|
||||
(produced offline by the existing `MINT`/`capsule_mint_identity()` path, Zuse-signed, same
|
||||
as today) becomes part of a normal `(p)` PRODUCTION capsule's own payload, following the
|
||||
same `Block NNNN` convention every capsule already uses for its personality source.
|
||||
§XXIV's collision machinery (`check_block_conflicts()`, `mkcapsule --resolve`,
|
||||
`capsule-reserved.txt`) already covers this -- it's blind to *content*, only to block
|
||||
numbers, so a cert-carrying capsule is just another capsule to it. No new collision risk,
|
||||
no change needed to §XXIV's machinery.
|
||||
2. **Birth -- `capsule_birth_baby()`, unmodified, not `capsule_runcap_birth()`.**
|
||||
`capsule_runcap_birth()` was the wrong tool: its own header says a user's identity source
|
||||
"never exists at build time" (`capsule_runcap.h:19-20`) -- exactly backwards for a
|
||||
build-time-baked unattended capsule, and it hard-requires a real `blkio_dev*` +
|
||||
`homeblocks_sig_t*` it would have no way to obtain. `capsule_birth_baby()` is already the
|
||||
generic, capsule-directory-sourced birth path every `(p)` capsule uses (confirmed at 4
|
||||
existing call sites across `mama_forth_words.c`/`capsule_console.c`); an unattended
|
||||
identity is just another named capsule going through it, `skip_pki_sig = 0` like any normal
|
||||
build-time capsule. Identity population is a proven, already-live pattern, not new
|
||||
invention: `capsule_wirebind.c:272-274` does exactly this today --
|
||||
`((VM *)user_ctx)->identity = identity;`, a plain post-birth struct assignment once
|
||||
`vm_identity_from_cert()` has verified the cert. The unattended path calls
|
||||
`vm_identity_from_cert()` on the capsule's own embedded DER cert immediately after
|
||||
`capsule_birth_baby()` returns, then assigns the result the same way.
|
||||
**One real wrinkle, not silently resolved:** `vm_identity_from_cert()`'s serial-number
|
||||
check binds the cert to a physical `drive_uuid` (`homeblocks_sig_t`, 16 bytes) -- a
|
||||
capsule-embedded identity has no physical drive and thus no `drive_uuid` to bind against.
|
||||
Either the cert-issuing step needs a different binding value for this identity origin (e.g.
|
||||
the capsule's own content hash, already the system's universal identity primitive) or
|
||||
`vm_identity_from_cert()` needs a origin-aware variant. **Not designed here -- flagged for
|
||||
the punch list, needs Bob's call on what an unattended identity's cert should bind to
|
||||
before implementation.**
|
||||
3. **ACL-gated console attachment -- checks the attaching human's own credentials, not the
|
||||
instance's.** Falls directly out of the no-seed decision: an unattended instance can never
|
||||
prove anything about itself at attach time (it holds no secret to challenge), so the gate
|
||||
necessarily lives on the human side -- almost certainly a capability bit
|
||||
(`VMIdentity.acl_caps`, still unassigned per this header's own "real bits get names only
|
||||
once the operation gets built" precedent) checked on the attaching human's own verified
|
||||
identity before the console-birth + `VM-NAME-REG` pairing (§XXXII.2 above) is allowed to
|
||||
run. Concrete bit value: punch-list item, not decided here.
|
||||
4. **§VII's xHCI/live-table machinery -- confirmed irrelevant, independently of the seed
|
||||
question.** An unattended identity is born from a capsule directory entry, never from a
|
||||
`blkio_dev*`; it has no physical device to attach/detach and never enters the xHCI
|
||||
per-device registry at all. This holds regardless of how Q1/Q2 were answered, so it was
|
||||
never actually contingent on the seed decision above.
|
||||
|
||||
**Punch list for implementation (not started, needs explicit authorization per this project's
|
||||
standing "plan approval is not a start signal" rule):**
|
||||
- Decide what an unattended identity's cert binds to instead of `drive_uuid` (item 2's
|
||||
wrinkle) -- Bob's call.
|
||||
- Define the new capsule content convention for an embedded cert (which block(s), what
|
||||
format) and add build-time production of it (offline `MINT`-equivalent step, not new
|
||||
runtime code).
|
||||
- Add the unattended-birth call site: `capsule_birth_baby()` + `vm_identity_from_cert()` +
|
||||
post-birth `identity` assignment, gated by the explicit invariant already stated above
|
||||
(never touch `g_wirebind_attached_username`/console-pairing).
|
||||
- Assign a real `acl_caps` bit for "may attach a console to an unattended instance" and wire
|
||||
the check into the console-birth + `VM-NAME-REG` path.
|
||||
- Acceptance: 3-arch clean boot with at least one unattended instance born at boot, no console
|
||||
attached, verified un-promptable (§VIII.1 gate holds), then a human console attached to it
|
||||
after the fact via the existing `VM-NAME-REG` pairing mechanism.
|
||||
|
||||
### XXXII.3 -- Primitive error-handling audit: kernel-only scope, real surface counted
|
||||
|
||||
**Scope, decided explicitly:** this audit covers kernel-side primitives only --
|
||||
|
||||
Reference in New Issue
Block a user