From 60bcdc09a77230005b98a345f731a7e2c5c2ac1a Mon Sep 17 00:00:00 2001 From: Robert Allan James Date: Wed, 16 Sep 2026 04:01:32 -0400 Subject: [PATCH] =?UTF-8?q?Stage=20E=20amendment:=20resolve=20drive=5Fuuid?= =?UTF-8?q?=20wrinkle=20via=20scratch-device=20mint=20(FABRIC-3.md=20?= =?UTF-8?q?=C2=A7XXXII.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bob's proposal: mint against a "sim thumbdrive" -- a scratch blkio_dev from the existing blk_subsys_add_raw_device() mechanism (same one the kernel ramdrive already uses), then hand-transcribe just drive_uuid + DER cert as FORTH literals into a normal .4th capsule block. This dissolves the wrinkle the first pass of Q2 left open: capsule_mint_identity() runs completely unmodified against the scratch device (same live Zuse-signing op, same rng_get_bytes() draw for drive_uuid), so vm_identity_from_cert() needs zero changes -- no origin-aware variant, no content-hash-derived substitute. "Sim" describes only where the bytes were written, invisible to verify. Also corrects an error in the first pass: cert production cannot be "offline" -- capsule_mint_identity() requires Zuse's live in-kernel signing key, so minting is inescapably a two-boot runtime operation (mint on boot N, package by hand, birth on boot N+1). Punch list updated to match. Still design-only, no code. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K --- FABRIC-3.md | 68 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 25 deletions(-) diff --git a/FABRIC-3.md b/FABRIC-3.md index c8dd3b44..22f6514c 100644 --- a/FABRIC-3.md +++ b/FABRIC-3.md @@ -4311,15 +4311,21 @@ 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. +1. **Packaging -- a new capsule content convention, not a new `mkcapsule` mode.** Correction + to the first pass of this answer: "produced offline" was wrong. + `capsule_mint_identity()` requires `issuer_vm->zuse_cert_seed` -- Zuse's live in-kernel + private key -- so minting can only happen at runtime, on a booted Hera with Zuse + authenticated, exactly like a human identity today. No host-side build tool can produce + this cert. The real shape is two boots: **mint on boot N, package the output as capsule + source by hand, birth it on boot N+1** once that source has gone through a normal build. + Captain Bob confirmed (2026-09-16) the packaging step is a hand-copy: mint against a + scratch device (item 2 below), then transcribe just `drive_uuid` (16 bytes) + the DER + cert bytes as FORTH literals into a normal `.4th` block -- no binary packaging, no new + `mkcapsule` mode, no change to the build tool at all. §XXIV's collision machinery + (`check_block_conflicts()`, `mkcapsule --resolve`, `capsule-reserved.txt`) already covers + this once it exists as a `.4th` block -- 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 @@ -4334,14 +4340,21 @@ This collapses all four questions: `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.** + **The `drive_uuid` wrinkle flagged in the first pass of this answer is resolved, not + deferred -- Bob's proposal (2026-09-16): mint against a "sim thumbdrive," a scratch + `blkio_dev` obtained from the exact same generic RAM-backed mechanism the kernel's own + ramdrive already uses (`blk_subsys_add_raw_device()`, `capsule_loader.c:100`), sized for + just a sig devblock + cert devblock (no seed devblock -- the no-seed decision above means + `capsule_mint_identity()`'s seed-writing step is simply never reached/read back). + `capsule_mint_identity()` runs against this scratch device completely unmodified -- same + live Zuse-signing operation, same `rng_get_bytes()` draw for `drive_uuid` + (`capsule_mint.c:209-213`) as a real thumbdrive gets. This means `drive_uuid` is a genuine + random draw living in a genuine `homeblocks_sig_t`, not a derived or synthetic value -- + "sim" describes only *where* the bytes were written (a throwaway RAM buffer instead of + physical media), a property entirely invisible to the verify path. + **`vm_identity_from_cert()` needs zero changes** -- no origin-aware variant, no + content-hash-derived substitute. This is a strictly better answer than the deferred + "Bob's call" the first pass of this section left open. 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 @@ -4358,14 +4371,19 @@ This collapses all four questions: **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). +- Build the scratch-device mint path: attach a `blk_subsys_add_raw_device()`-backed buffer + sized for sig+cert devblocks only, run `capsule_mint_identity()` against it unmodified + (live, on a booted Hera with Zuse authenticated -- likely a new FORTH word, or a `MINT` + variant that takes a device handle rather than always resolving one from an attach event). +- Hand-transcribe the resulting `drive_uuid` + DER cert bytes out of the scratch buffer as + FORTH literals into a new `.4th` capsule block, following the existing `Block NNNN` + convention -- checked into the repo, picked up by the next `mkcapsule` build like any other + capsule. +- Add the unattended-birth call site: `capsule_birth_baby()` (unmodified) + read the embedded + `drive_uuid`+cert literals back out of the capsule's own arena + `vm_identity_from_cert()` + (unmodified) + post-birth `identity` assignment (`capsule_wirebind.c:272-274`'s pattern), + 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