--- topic: the tiers status: accepted date: 2026-08-31 deciders: jochen reconstructed: false extends: 02-DECISIONS/0035-one-implementation-several-surfaces.md --- # 36. Bootstrap ends at a usable mesh, and the first credential comes from a person ## Context Bootstrap currently ends when the control plane starts ([`07-the-foundation.md`](../03-DESIGN/01-to-be/07-the-foundation.md)). That is a mesh that runs and cannot yet be used by anybody who is not standing at the machine: the networked surfaces need an OAuth2 identity provider ([ADR 0035](0035-one-implementation-several-surfaces.md)), the provider is a module, and no module has been assigned. **So bootstrap should go further** — through the identity provider and the first login — and stop at a mesh somebody can actually use. **One thing in the way, and it is not incidental.** The mesh has never held a readable secret. The sealing code says what it does and why: > Make generates a secret and seals it to both ends, **keeping no readable copy.** An initial administrator's credential is the first value a **person must read**. Everything else the mesh generates is something no human ever sees, and everything a human provides is something the mesh immediately stops being able to read. ## Considered Options 1. **The mesh generates it and prints it once**, to the terminal of whoever ran the bootstrap. Convenient, and needs no prompt. **Rejected.** It would give the control plane a plaintext secret for the first time — briefly, and only to one terminal, but the capability would then exist. *An exception made for one case does not stay one*: the next credential that is awkward to supply gets printed too, and the property that a copy of the mesh's database is a copy of nothing stops being checkable by reading the code. 2. **No password: a one-time link that lets the operator set their own.** The nicest to use. **Rejected for now** — it needs a mechanism that does not exist, and the thing it improves is one prompt, once, on a new mesh. 3. **The operator supplies it.** **Adopted.** ## Decision **Bootstrap runs to a usable mesh**: the substrate, the control plane, the identity provider as an ordinary module, its realm and client provisioned, an administrator able to log in, and the networked surfaces available. **The administrator's credential is supplied by the person doing the bootstrap**, on standard input and not echoed — the path that already exists for a model-access key. The mesh seals it and cannot read it afterwards. **What is created is an account in the identity provider, not a user of the mesh.** The mesh still has no user model and gains none here ([ADR 0034](0034-the-local-account-owns-the-mesh.md)). What this produces is the first login for the applications that have one. **The provisioning is ordinary.** A realm, a client and a first account are what an identity module's provisioner makes from what the mesh granted it — the same shape as a database and a bucket, which are built and proven. **The surfaces arrive when their dependency does.** The command API is not started with the control plane and then broken until identity exists; it becomes available once it can authenticate, the way anything else waits for a provider. ## Consequences **The mesh still never holds a readable secret**, and that sentence needs no exception clause. That is the whole reason for the prompt. **An unattended bootstrap is still possible, and the value still comes from outside.** Automation supplying the credential is the operator supplying it. What is refused is the *mesh inventing* one — so an unattended bootstrap with no credential provided produces a mesh with no administrator, which is correct rather than broken. **Bootstrap gains an interactive step**, and it is the only one. Worth stating because a bootstrap that cannot run without a person is a real constraint on how a node is stood up, and this is deliberate rather than an oversight. **The identity provider is still not substrate.** It is assigned by the control plane, so it comes after it, and a thing that comes after cannot be a thing that must exist before ([ADR 0033](0033-the-substrate-is-a-store-and-a-broker.md)). Bootstrap running through it does not move it: bootstrap is a sequence, the substrate is a dependency. **And the recovery path is unchanged.** When the identity provider is broken later — which is the failure that matters, not the one at first start — the command line still works, because it authenticates through nothing (ADR 0035). ## References - [ADR 0035](0035-one-implementation-several-surfaces.md) — the surfaces, and why the command line must keep working - [ADR 0034](0034-the-local-account-owns-the-mesh.md) — the local account owns the mesh; this adds no user model - [ADR 0033](0033-the-substrate-is-a-store-and-a-broker.md) — what must exist before the control plane, which this does not change