Settles the design repository now that the self-upgrade build is on main: - Records the two decisions that shipped without a record — ADR 0077 (the controller/foundation/node vocabulary) and ADR 0078 (the store and broker are ordinary modules); accepts ADR 0075 and 0076, which shipped work rests on. - Fills issue 051's amended-design and wires ADR 0078 into 07-the-foundation. - Sweeps the repo rename (mesh-control -> mesh-controller) into the mutable docs now that the forge repo is renamed; updates the glossary note and repos.md. - Fixes the six broken links from the design-doc renames, indexes the glossary, regenerates the decisions reading order. Both checks (records.py, index.py) are green. Statuses stay honest: the build is on main and lab-proven but not deployed as the production mesh, so the to-be docs remain in-progress and the as-is layer (the hal mesh) is unchanged — graduation to implemented + as-is belongs to deployment, not merge. https://claude.ai/code/session_01D6qtiYU3P9jk3pnAXyAFyx
100 lines
4.9 KiB
Markdown
100 lines
4.9 KiB
Markdown
---
|
|
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
|