ADR 0098; issue 076 opened and resolved; ADR 0097's base refusal live; ADR 0096 proven against the public hub; 074 down to one bed #69

Merged
jschoubben merged 5 commits from multiple-fixes into main 2026-09-21 20:58:27 +00:00
6 changed files with 88 additions and 5 deletions
Showing only changes of commit 252c6042e8 - Show all commits
@@ -0,0 +1,58 @@
---
topic: the tiers
status: accepted
date: 2026-09-21
deciders: jochen
reconstructed: false
extends: 02-DECISIONS/0085-a-secret-is-a-provision.md
---
# 98. A fact a provider makes at first start is fetched from it, not carried in its manifest
## Context
The catalogue's certificate authority declared its root certificate, its root key and that key's
password as its own secrets, and told the container to initialise from them. The mesh mints an
own secret as random bytes, and random bytes are not a certificate: as written the authority
could not start, and no bed had raised it
([issue 076](../04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md)).
The authority can make its own root at first start. What it could not do then was tell the mesh
what that root is: a consumer was given `${bound:acme-ca:root}` from the provider's `serves`,
which is written in the manifest before anything runs.
## Considered Options
1. **A secret the module makes**, with the mesh taking custody once the file exists. Rejected
for now: a node would have to send a value up to the mesh, which no channel does today, and
a root key is the one thing the mesh has no reason to hold.
2. **A served fact the provider contributes at run time.** Rejected for now: the same new
channel, for a fact that is not secret at all.
3. **The consumer fetches it from the provider**, over the mesh network, through a gate before
the thing that needs it starts. Adopted.
## Decision
A provider's `serves` names where a fact made at first start can be fetched — the authority
serves its root at a path beside its ACME directory — and a consumer fetches it in a `run-once`
step declared before the resource that needs it, from the provider's bound address. The mesh
network is where the fetch happens, which is what makes fetching without a prior trust
acceptable: it is the network the mesh itself authenticates. The mesh mints only what it can
make: the authority's password. The root key stays where it was made.
## Consequences
The catalogue's authority starts, and the proxy that requires it trusts what it fetched. What
got harder: a consumer of such a fact carries one more resource, the gate that fetches it, and
a fact that changes after first start is refetched only when the declaration changes.
## How it is checked
The route-forwarding bed installs the authority, the proxy and a consumer from the catalogue and
asserts a routed name is served through the proxy; the proxy cannot start without the root its
gate fetched. The catalogue-wide manifest test parses both manifests.
## References
- [issue 076](../04-ISSUES/076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md)
- [ADR 0053](0053-a-step-that-runs-on-a-schedule.md), [ADR 0085](0085-a-secret-is-a-provision.md)
- [`03-DESIGN/01-to-be/08-connectivity.md`](../03-DESIGN/01-to-be/08-connectivity.md)
+1
View File
@@ -115,6 +115,7 @@ python3 00-META/checks/index.py fail if stale
- **0092** — [An operator delivers a pair credential, and the mesh never replaces it](0092-an-operator-delivers-a-pair-credential.md)
- **0094** — [A module may hold several secrets from one provider, each a pair of its own](0094-a-module-may-hold-several-secrets-from-one-provider.md)
- **0095** — [The control plane is the way to ask a module](0095-the-control-plane-is-the-way-to-ask-a-module.md)
- **0098** — [A fact a provider makes at first start is fetched from it, not carried in its manifest](0098-a-fact-a-provider-makes-at-first-start-is-fetched-from-it.md)
### What runs on them, and how it gets there
+11 -1
View File
@@ -7,8 +7,9 @@ code:
- mesh-controller internal/identity/authority.go
- mesh-host internal/identity/serving.go
- mesh-host internal/apply (the service that reflects a rule set)
updated: 2026-09-09
updated: 2026-09-21
decisions:
- 02-DECISIONS/0098-a-fact-a-provider-makes-at-first-start-is-fetched-from-it.md
- 02-DECISIONS/0005-the-node-host.md
- 02-DECISIONS/0004-a-node-and-how-it-joins.md
- 02-DECISIONS/0007-connectivity.md
@@ -557,6 +558,15 @@ fingerprint in its token ([ADR 0004](../../02-DECISIONS/0004-a-node-and-how-it-j
so nothing needs the CA before membership. It certifies internal names afterwards, and that is
all it does.
**The internal authority makes its own root at first start, and a consumer fetches it**
([ADR 0098](../../02-DECISIONS/0098-a-fact-a-provider-makes-at-first-start-is-fetched-from-it.md)).
The mesh mints the authority's password and nothing else of its: a root certificate and its key
are things only the authority can make, and a served fact written in a manifest cannot carry what
does not exist until the authority has run. So the authority serves its root at a path beside its
ACME directory, and the proxy that requires it fetches that root over the mesh network in a
run-once step before it starts. *How it is checked:* the route-forwarding bed installs the
authority, the proxy and a consumer from the catalogue and asserts the routed name is served.
### What was built
*2026-08-31.*
@@ -30,3 +30,6 @@ route-forwarding, which needs the certificate authority beside the proxy, and th
*Route-forwarding's conversion is blocked:* the catalogue's authority cannot be raised as written
([issue 076](../076-a-served-fact-made-at-first-start-cannot-be-served/00-report.md)).
*Later the same day.* Route-forwarding converted, with the authority beside the proxy
(ADR 0098). One bed remains declared: the large mesh test, with its three fixtures.
@@ -1,9 +1,9 @@
---
status: located
status: resolved
opened: 2026-09-21
located-in: [mesh-catalog modules/step-ca, mesh-controller internal/catalogue (serves)]
fixed-by:
amended-design:
located-in: [mesh-catalog modules/step-ca, mesh-catalog modules/route-proxy]
fixed-by: ADR 0098; mesh-catalog multiple-fixes (the authority makes its own root and serves it; the proxy fetches it through a gate); proven by the route-forwarding bed
amended-design: 03-DESIGN/01-to-be/08-connectivity.md
---
# A served fact made at first start cannot be served, so the catalogue's authority cannot start
@@ -0,0 +1,11 @@
# Diagnosis — 2026-09-21
1. The certificate bed already raised the same authority image with no root supplied, and it made
its own root and issued within a second. The manifest's three minted "secrets" were not needed
by the authority; they were needed by the consumer, which was handed the root as a served fact.
2. Of the three ways to get a fact made at first start to a consumer, two need a channel from a
node up to the mesh that does not exist. The third needs nothing new: the provider serves the
fact at a path, and the consumer fetches it over the mesh network in a gate before it starts.
**Located in:** the two manifests. Decided in
[ADR 0098](../../02-DECISIONS/0098-a-fact-a-provider-makes-at-first-start-is-fetched-from-it.md).