Bootstrap stopped when the control plane started — a mesh that runs and cannot be used by anybody not standing at the machine, since the networked surfaces need an identity provider and no module has been assigned yet. It now runs through the provider and the first login. The obstacle was not incidental. The mesh has never held a readable secret: Make generates and seals, keeping no readable copy. An initial administrator's credential is the first value a person must read. Generating it and printing it once was the convenient option and is refused. It would give the control plane a plaintext secret for the first time — briefly, and to one terminal, but the capability would then exist, and an exception made for one case does not stay one. The next awkward credential gets printed too, and "a copy of the database is a copy of nothing" stops being checkable by reading the code. So the operator supplies it, on standard input, not echoed — the path that already exists for a model-access key. What is created is an account in the identity provider, not a user of the mesh; there is still no user model. Unattended bootstrap remains possible and the value still comes from outside: automation supplying it is the operator supplying it. What is refused is the mesh inventing one, so an unattended bootstrap with nothing provided yields a mesh with no administrator — correct rather than broken.
4.9 KiB
topic, status, date, deciders, reconstructed, extends
| topic | status | date | deciders | reconstructed | extends |
|---|---|---|---|---|---|
| the tiers | accepted | 2026-08-31 | jochen | false | 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-substrate.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), 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
-
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.
-
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.
-
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). 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). 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).