From fd8ac42301ea9e99d19dc0b168895e75de97f2b2 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 27 Aug 2026 06:10:14 +0200 Subject: [PATCH] docs root-ceremony: the provisional root has no backup, and say what v1.0 changes The topic prescribed paper backup in two locations, split custody over the seed, an access log and an annual read test -- and never said that varve's own provisional rolling key has NONE of them. It was generated straight into CI and its secret half exists in exactly one place: a write-only Actions secret that nobody can read back, by design of the secret store (#110). "Provisional" reads far milder than what that is, so the consequences are now stated flatly: the key cannot be moved to another repository (which is why a realm's contents live in their own repo while the signing step stays where the secret is), it cannot be recovered if the secret or the repository is lost, and it must not be extracted -- printing a secret into a workflow log would expose the root permanently, and with no rotation and no revocation the only remedy would be abandoning the realm. A key with a single write-only copy is not in custody. The topic now says so, and says do not run a realm this way. Also adds a "What changes at v1.0" section, because REQ-CEREMONY-001 was referenced repeatedly and never described in one place. On keyless: recorded as an OPEN question rather than a settled one, with both halves of the evidence. The rejection in DD-026 rested partly on the offline verifier being a stub that failed open -- verified today against wsc 0.11.0 source, that is NO LONGER TRUE: the air-gapped verifier does real certificate-chain, Rekor SET, ECDSA, revocation and identity checks offline, and documents the two things it deliberately skips (the Rekor Merkle inclusion proof, because the verifier computes the wrong shard root for Rekor v2 and failing closed would reject legitimate signatures; and SCT/CT, for want of a provisioned CT key). The structural half of DD-026 still stands, in wsc's own words: "The bundle is signed with a long-lived offline key. Devices verify the signature against a pre-provisioned public key before using." Keyless relocates the long-lived secret rather than abolishing it. But relocation is close to the whole point, and #110 is the argument. Today's long-lived key sits in CI, is used on every deposit, and cannot be backed up or moved. A bundle-signing key is used rarely and can plausibly be held the way this topic prescribes. The question for v1.0 is not "keys or no keys", it is which key has to be online. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019TNtfRjLNhEz82G2ggeeNu --- crates/varve/docs/concept-root-ceremony.md | 67 ++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/crates/varve/docs/concept-root-ceremony.md b/crates/varve/docs/concept-root-ceremony.md index b548392c..93a142b4 100644 --- a/crates/varve/docs/concept-root-ceremony.md +++ b/crates/varve/docs/concept-root-ceremony.md @@ -223,6 +223,73 @@ That is why varve's qualified channel is not open. Do not read the fact that varve ships a root as evidence that the ceremony problem is solved — it is the same problem, deferred to the same requirement. +### And it has no backup at all — read this before copying the pattern + +Everything above prescribes paper backup in two locations, split custody over +the seed, an access log, and an annual read test. **varve's own provisional +rolling key has none of them.** It was generated straight into CI, and its +secret half exists in exactly one place: a write-only GitHub Actions secret in +the varve repository. Nobody can read it back — not the maintainers, not +through the API, by design of the secret store. + +The consequences are worth stating flatly, because "provisional" reads far +milder than what this is: + +* **It cannot be moved.** A second repository cannot be given the key, because + the key cannot be read out of the first. That is why a realm's *contents* + live in their own repository while the *signing step* stays where the secret + is (`varve docs deploy`). +* **It cannot be recovered.** If that secret is deleted, or the repository is + lost, the `pulseengine` rolling line can never be signed again. Every + consumer pinned to it stays frozen on the layer they already installed, with + no in-band way to be told why — because there is no revocation channel to + tell them on. +* **It must not be extracted.** With write access to a repository it is + technically possible to print a secret into a workflow log in pieces. Doing + that here would expose the root permanently, and with no rotation and no + revocation the only remedy would be abandoning the realm. The inability to + read the secret back is a property worth keeping, not an obstacle to route + around. + +A key with a single write-only copy is not in custody. **Do not run a realm +this way.** The ceremony above exists precisely so that your root is not held +the way varve's provisional one currently is, and REQ-CEREMONY-001 is where +varve fixes its own. + +## What changes at v1.0 + +REQ-CEREMONY-001 is not a polish item; it is the requirement that makes a root +holdable. It defines custody, rotation, revocation and expiry, dual-signs one +release so an old root verifies a new one, and adds a transparency mechanism +that makes key compromise detectable rather than merely regrettable. The +qualified channel opens then, and not before. + +**Whether v1.0 keeps a file-based key at all is an open decision, not a settled +one.** Keyless signing — an ephemeral Sigstore identity per release, with no +long-lived secret in CI — was proposed (DD-025), rejected (DD-026), and is +being reconsidered, because the reason it was rejected has partly expired and +the reason to want it has grown: + +* The rejection rested in part on the offline verifier being a stub that failed + open. **That is no longer true**: as of `wsc` 0.11.0 the air-gapped verifier + performs real certificate-chain, Rekor SET, signature, revocation and + identity checks offline, and documents the two things it deliberately does + not verify (the Rekor Merkle inclusion proof, and SCT/CT logs). +* The rejection's structural half **still stands**: the offline trust bundle is + itself signed with a long-lived key that every consumer must pin. Keyless + *relocates* the long-lived secret; it does not abolish it. +* But relocation is close to the whole point. Today's long-lived key sits in + CI, is used on every deposit, and — as above — cannot be backed up or moved. + A bundle-signing key is used rarely, changes rarely, and can plausibly be + held the way this topic actually prescribes: offline, split, on paper, with a + read test. **The question for v1.0 is not "keys or no keys", it is which key + has to be online.** + +Do not plan around either outcome yet. Plan around the fact that the trust root +you pin today is provisional, and that the transition will be announced through +the channel that bootstrapped you, because varve has no in-band way to announce +it. + ## Where to go next * `varve docs signing-keys` — the key format and what varve checks