Issue 042 — nothing gives a node an account for a registry
Found by deleting the lab's registry and giving the machines a real path out: public images fetched, the operator's own could not be fetched at all. There is no provision for a registry credential, no manifest field, and no step in enrolment that establishes one. It applies to the mesh's own store too, which today asks for nothing — a decision that has never been written down as one, and so reads as an absence. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -0,0 +1,64 @@
|
|||||||
|
---
|
||||||
|
status: open
|
||||||
|
opened: 2026-09-11
|
||||||
|
located-in: []
|
||||||
|
fixed-by:
|
||||||
|
amended-design:
|
||||||
|
---
|
||||||
|
|
||||||
|
# 042 — Nothing gives a node an account for a registry
|
||||||
|
|
||||||
|
## Symptom
|
||||||
|
|
||||||
|
A module names an image in a registry that requires authentication. The machine cannot fetch it:
|
||||||
|
|
||||||
|
```
|
||||||
|
pull access denied … authorization failed: no basic auth credentials
|
||||||
|
```
|
||||||
|
|
||||||
|
Nothing in the mesh delivers a registry credential to a node. There is no provision for it, no
|
||||||
|
field in a manifest for it, and no step in enrolment that establishes one.
|
||||||
|
|
||||||
|
Observed when the lab's own image registry was deleted and machines were given a real path to the
|
||||||
|
internet for the first time. Public images fetched normally; the operator's own — in their own
|
||||||
|
registry — could not be fetched at all.
|
||||||
|
|
||||||
|
## Why this matters
|
||||||
|
|
||||||
|
**Delivery ends at a node pulling an image, and this is the last step of it.** The whole design
|
||||||
|
from source to artifact to machine assumes the final fetch succeeds. It succeeded until now for
|
||||||
|
one reason: everything was either public, or came from a registry the harness ran with no
|
||||||
|
authentication at all.
|
||||||
|
|
||||||
|
**And it applies to the mesh's own store, not only to somebody else's.** The registry the mesh runs
|
||||||
|
is reached over the private network and today asks for nothing. That is a decision — *anything that
|
||||||
|
can reach it can read every artifact the mesh holds, and push to it if pushing is open* — but it
|
||||||
|
has never been written down as one. It reads as an absence, which is the kind of thing that stays
|
||||||
|
true by accident until it is exploited.
|
||||||
|
|
||||||
|
**The mesh already knows how to do this.** A provision grants a consumer a credential, minted by
|
||||||
|
the mesh, sealed to the machine, with the plaintext discarded. An account on a registry is exactly
|
||||||
|
that shape: the artifact store is already a provision, and a node that must pull from it is already
|
||||||
|
a consumer of it. What is missing is not a mechanism but the recognition that pulling is a use of
|
||||||
|
the store, not a thing that happens beneath it.
|
||||||
|
|
||||||
|
**It is also a bootstrap question**, which is where it will bite first: the machine that installs a
|
||||||
|
mesh pulls the control plane's image before the mesh exists to grant anything
|
||||||
|
([ADR 0067](../../02-DECISIONS/0067-genesis-is-a-pivot.md)). Whatever the answer is, it has to
|
||||||
|
survive a moment when there is nobody to ask.
|
||||||
|
|
||||||
|
## Open questions
|
||||||
|
|
||||||
|
- **Should the ability to pull be granted like anything else** — the store mints a per-node account,
|
||||||
|
seals it to the machine, and the host writes whatever the runtime reads? That would make a node's
|
||||||
|
reach into the artifact store follow the same rules as its reach into a database.
|
||||||
|
- **What should the mesh's own registry require?** If the answer is "nothing, inside the private
|
||||||
|
network", that is defensible and must be *recorded* as the decision it is, with what it assumes
|
||||||
|
about who is on that network.
|
||||||
|
- **What authenticates a push?** Reading and writing are not the same grant, and a builder that may
|
||||||
|
publish is a much stronger thing than a node that may fetch.
|
||||||
|
- **What does an operator's own external registry do here?** It is not the mesh's to grant accounts
|
||||||
|
on. Is the credential operator-supplied, like any other secret the mesh cannot invent — and if so,
|
||||||
|
which module owns it, given that every module pulling from there needs it?
|
||||||
|
- **How does any of this work before the mesh exists?** The bootstrap fetches images with no mesh to
|
||||||
|
grant a credential, so the first pull is either public, anonymous, or carried.
|
||||||
Reference in New Issue
Block a user