Merge pull request 'Issue 092: genesis publishes to a registry the container runtime does not yet trust' (#79) from issue/092-genesis-registry-trust into main
This commit was merged in pull request #79.
This commit is contained in:
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
status: open
|
||||||
|
opened: 2026-09-22
|
||||||
|
located-in: []
|
||||||
|
fixed-by:
|
||||||
|
amended-design:
|
||||||
|
---
|
||||||
|
|
||||||
|
# 092 — Genesis publishes to a registry the container runtime does not yet trust
|
||||||
|
|
||||||
|
## What was observed
|
||||||
|
|
||||||
|
On the first real genesis, on a machine in use, 2026-09-22.
|
||||||
|
|
||||||
|
Genesis raises the mesh's registry, then pushes the control plane's image into it so that the
|
||||||
|
control plane can be reinstalled as an ordinary module pinned to a digest. The push failed:
|
||||||
|
|
||||||
|
```
|
||||||
|
the container runtime would not push <address>/mesh-controller:genesis:
|
||||||
|
Get "https://<address>/v2/": http: server gave HTTP response to HTTPS client
|
||||||
|
```
|
||||||
|
|
||||||
|
The mesh's registry speaks plain HTTP, deliberately: every path to it is inside the private
|
||||||
|
network's encryption ([ADR 0082](../../02-DECISIONS/0082-the-registry-is-reached-by-name-and-trusted-by-the-overlay.md)).
|
||||||
|
The container runtime refuses plain HTTP to a registry it has not been told to trust, and **the
|
||||||
|
thing that tells it is the networking module**, which genesis installs at step 16 — six steps
|
||||||
|
after the push.
|
||||||
|
|
||||||
|
So genesis cannot complete on a machine whose runtime was not already told, out of band, to trust
|
||||||
|
the address the mesh is about to serve its own images from.
|
||||||
|
|
||||||
|
The lab never sees it: its base image writes that trust into the runtime's configuration before
|
||||||
|
any bed starts. That is the same blind spot [issue 084](../084-taking-networking-on-an-adopted-node-restarts-every-container/00-report.md)
|
||||||
|
names from the other side.
|
||||||
|
|
||||||
|
Worked around by hand on the machine: the mesh's registry added to the runtime's trusted list,
|
||||||
|
keeping every key already there, and the runtime **reloaded** rather than restarted, so nothing it
|
||||||
|
was running stopped ([ADR 0102](../../02-DECISIONS/0102-the-mesh-writes-into-a-shared-file-never-over-it.md)).
|
||||||
|
Genesis then continued.
|
||||||
|
|
||||||
|
**Then it happened twice more**, on the same machine, within the hour:
|
||||||
|
|
||||||
|
- **By name, not only by address.** Once the mesh's builder built a module, it pushed the result to
|
||||||
|
the registry by its **mesh name** and port. The runtime trusted the numeric address genesis was
|
||||||
|
given and nothing else, so the push failed the same way. The trust has to cover every name the
|
||||||
|
mesh will use for that registry, not the one the operator typed.
|
||||||
|
- **The mesh's own trust names the wrong port.** The networking module writes the registry's trust
|
||||||
|
into the runtime's configuration — correctly written *into* it, keeping what was there
|
||||||
|
([ADR 0102](../../02-DECISIONS/0102-the-mesh-writes-into-a-shared-file-never-over-it.md)) — and
|
||||||
|
the value it wrote names the registry's **default** port while the node was given another. So the
|
||||||
|
mesh trusts an address its registry does not serve. That is the same fault as
|
||||||
|
[issue 088](../088-the-forges-own-address-names-a-port-it-may-not-have/00-report.md): an address
|
||||||
|
with a port in it that does not follow the node's setting.
|
||||||
|
|
||||||
|
## Why it matters beyond this instance
|
||||||
|
|
||||||
|
Genesis is meant to take a machine from nothing to a mesh without anyone editing files on it. It
|
||||||
|
has one step that cannot work unless somebody already did. Every future first node meets this, not
|
||||||
|
only a node adopted beside a predecessor, and the order is what makes it so: the trust the push
|
||||||
|
needs is installed after the push.
|
||||||
|
|
||||||
|
It also breaks the rule that each step says what it needs before it changes anything. Preflight
|
||||||
|
checks that the bundle's registries are reachable. It does not check that the runtime will speak
|
||||||
|
to the one the mesh is about to raise.
|
||||||
|
|
||||||
|
## Open questions
|
||||||
|
|
||||||
|
- Should genesis write the runtime's trust itself, before the publish step, the way it writes
|
||||||
|
everything else the foundation needs — and hand it to the networking module afterwards?
|
||||||
|
- Or should the push not need it: a registry served over TLS from the start, or an image loaded
|
||||||
|
rather than pushed?
|
||||||
|
- Should preflight refuse a genesis whose runtime does not trust the registry it is being given,
|
||||||
|
rather than letting it fail at step 10?
|
||||||
|
- Whatever writes that trust, which names of the registry must it cover: the address given, the
|
||||||
|
mesh name, loopback? The builder used the mesh name without being told to.
|
||||||
|
- Should the registry's trust be derived from what the registry module *serves* on that node,
|
||||||
|
rather than from its default port?
|
||||||
Reference in New Issue
Block a user