diff --git a/03-DESIGN/00-as-is/06-configuration-and-secrets.md b/03-DESIGN/00-as-is/06-configuration-and-secrets.md index 5de0385..bd6a281 100644 --- a/03-DESIGN/00-as-is/06-configuration-and-secrets.md +++ b/03-DESIGN/00-as-is/06-configuration-and-secrets.md @@ -1,11 +1,12 @@ --- layer: as-is status: implemented -code: [hal] -updated: 2026-08-23 +code: [hal, mesh-controller, mesh-catalog, mesh-host] +updated: 2026-09-21 decisions: - 02-DECISIONS/0011-managed-files-are-generated-never-edited.md - 02-DECISIONS/0009-modules-and-the-graph.md + - 02-DECISIONS/0085-a-secret-is-a-provision.md --- # Configuration and secrets @@ -73,9 +74,31 @@ when the file is created, so regeneration left the previous mode in place. The c worth remembering beyond the instance: a permission set at creation is not a permission maintained. -**Rotation is not a mesh operation.** Secrets can be generated and granted; there is no -mechanism that rotates one and informs everything holding it. Where a rotation has been done, -it has been done by hand, and doing it wrong has taken services down. +**Rotation was not a mesh operation** in the mesh being replaced, and doing it by hand took +services down. On the mesh that exists now it is: `rotate ` discards a pair credential +and delivers both ends in one send, and a module's own secret is such a pair credential when the +module takes it from the vault — which, at the time of writing, one module does (redis). + +## The vault, as it runs + +Since 2026-09-21 the mesh runs `mesh-vault`, a foundation module installed at genesis beside the +adopted store and broker. It provides `secret`: a module that requires one receives a pair +credential the controller minted, and the vault's ledger records the holder and the value's +fingerprint, notices a rotation, and answers over the mesh by fingerprint only. It holds no value. + +Genesis makes the store's superuser and the broker's administrator rather than copying the +template's, keeps them at the paths the store and broker modules declare as their own secrets, and +makes an **operator sealing key** before the first secret is accepted: its private half is a file +beside the produced bundle, which the operator carries off the machine, and its public half is +what the mesh records. Every secret a module holds for itself and every pair credential is sealed +to that key as well as to its node. The export of those copies is written beside the key at the +end of genesis and kept by the vault on its own disk; the operator recovers any secret from it, off +the mesh, with `secret recover`. Secrets made before the key existed, or sealed to a replaced key, +are listed as such rather than passed off as recoverable. The produced bundle and the installer's +transcript carry no credential in the clear. + +Two things this does not yet do: a module with several own secrets cannot take them all from the +vault (issue 069), and an operator cannot hand a value into a pair credential (issue 070). ## Node-level and mesh-level values diff --git a/03-DESIGN/01-to-be/07-the-foundation.md b/03-DESIGN/01-to-be/07-the-foundation.md index 2a1c898..818c523 100644 --- a/03-DESIGN/01-to-be/07-the-foundation.md +++ b/03-DESIGN/01-to-be/07-the-foundation.md @@ -5,6 +5,9 @@ code: - mesh-host examples/foundation-first-node.lock - mesh-host internal/apply - mesh-host internal/bootstrap/phase3.go + - mesh-host internal/bootstrap/rootsecrets.go + - mesh-host internal/bootstrap/operator.go + - mesh-catalog modules/mesh-vault - mesh-catalog modules/postgres - mesh-catalog modules/lavinmq - mesh-lab test/integration/mesh.test.ts (a bare machine becomes a mesh) diff --git a/03-DESIGN/01-to-be/24-the-secrets-vault.md b/03-DESIGN/01-to-be/24-the-secrets-vault.md index badb34a..a865c05 100644 --- a/03-DESIGN/01-to-be/24-the-secrets-vault.md +++ b/03-DESIGN/01-to-be/24-the-secrets-vault.md @@ -1,8 +1,8 @@ --- layer: to-be -status: in-progress -code: [mesh-catalog, mesh-controller] -updated: 2026-09-20 +status: implemented +code: [mesh-catalog, mesh-controller, mesh-host] +updated: 2026-09-21 decisions: - 02-DECISIONS/0085-a-secret-is-a-provision.md - 02-DECISIONS/0031-the-control-plane-authenticates-nobody.md @@ -106,9 +106,9 @@ The vault's second job is to hold these, and it does so without holding a value: answered by it. **Genesis** makes the operator key first and mints real root secrets in place of the fixed ones the -foundation is raised with, so the mesh is handed over with nothing well-known in it. That step is -the installer's and is not yet built; until it is, the fixed credentials are the as-is and are -said so in [21](21-the-installation-in-full.md). +foundation is raised with, so the mesh is handed over with nothing well-known in it. The installer +does this ([21](21-the-installation-in-full.md)); what it runs is described in the as-is +([`00-as-is/06`](../00-as-is/06-configuration-and-secrets.md)). A module's vault-provided secret — the pair credential of [13](13-credentials-and-their-rotation.md) — is sealed to the operator the same way, as is every diff --git a/04-ISSUES/071-the-foundation-is-raised-with-fixed-credentials/00-report.md b/04-ISSUES/071-the-foundation-is-raised-with-fixed-credentials/00-report.md index 0661961..ec026a8 100644 --- a/04-ISSUES/071-the-foundation-is-raised-with-fixed-credentials/00-report.md +++ b/04-ISSUES/071-the-foundation-is-raised-with-fixed-credentials/00-report.md @@ -2,7 +2,7 @@ status: resolved opened: 2026-09-20 located-in: [mesh-host internal/bootstrap, mesh-host examples/foundation-first-node.lock] -fixed-by: mesh-host feat/secrets-vault (ee0c8b8, genesis root credentials + operator key + vault); mesh-controller feat/secrets-vault (e140ed5, 565f144); mesh-catalog feat/secrets-vault; proven by the one-node genesis bed step V5 +fixed-by: mesh-host PR 14 (e30a6b0), mesh-controller PR 34 (6b695c8), mesh-catalog PR 30 (d03520f), mesh-lab PR 39 (7e2e97f); proven by the one-node genesis bed step V5, 22/22 amended-design: 03-DESIGN/01-to-be/24-the-secrets-vault.md ---