220. A hosted server is a rendezvous only over TLS, with its key held as a secret and the mesh read only by those it trusts
Kontext
On 2026-10-21 the owner asked that the Gigalixir deployment of ADR 0219 be "truly live: a rendezvous, optional but the default server, alive, showing the whole mesh", and to study the repository before building it. The study found that the code nearly allows it already and the records do not:
- Every Majordomus server is a rendezvous (
mesh.register, ADR 0050), the endpoint is plain HTTP and reachable on the hosted application, and a node that dials a hub links both ways, so the hub would fold and relay the whole journal. - The mesh client speaks plain HTTP over a bare socket; there is no TLS in the executable
(ADR 0067). The intent
an-authorised-node-connects-from-anywhereholds the invariant "no mesh frame crosses a public network in cleartext". - ADR 0126 lets any caller beyond loopback read every read capability, the mesh's included: sessions, claims, handovers and reviews of every trusted node. ADR 0204 rejected "an anonymous public Cockpit".
- A node's signing key lives in
node.jsonunder the machine's state directory and "never leaves the machine it was created on" (ADR 0050). A hosted dyno's filesystem is ephemeral, so it would mint a new key at every boot, never intrust.allow, and its mesh stays closed. - A hosted node advertises the addresses of the interface it binds, which on a platform are internal pod addresses nobody outside can dial.
The owner decided three questions put to him on 2026-10-21 (recorded with majordomus decision): the hub's key may be held as a secret configuration variable of the hosting
platform, with its public key listed in trust.allow; TLS comes first and the hub after; an
anonymous caller reads the repository and liveness, and the mesh only an authenticated user or
a trusted node.
Rozhodnutí
- TLS before anything is opened. The mesh client gains TLS: an
https://rendezvous endpoint or seed is reached over TLS with the platform's certificate verified against the system roots, and anhttp://endpoint outside the private and overlay ranges is refused, with the correction. Until this lands, no public endpoint is declared. - The key is the deployment's secret. A declared hosted hub reads its node seed from one secret environment variable of its platform at start, writes nothing of it to the tracked tree, a log line or an answer, and refuses to start its mesh when the variable is absent or malformed rather than minting a key nobody trusts. This amends ADR 0050's custody statement for a deployment object that names a provider, and only for it.
- The hub says where it is. A hosted server advertises the public URL its deployment object
names (ADR 0219,
provider.url), not its interface addresses. - The mesh is read only by those the mesh trusts. On a server bound beyond loopback, the
mesh's read capabilities (
mesh.state,mesh.peers,mesh.events,mesh.nodes,mesh.cooperation,/ui/mesh,/cockpit/mesh,/cockpit/monitor) answer a remote caller only when it presents a request signed by a key intrust.allow; anyone else gets the liveness of the server and a refusal that says how to be trusted. The repository's other reads stay as ADR 0126 left them. A browser user signs in through I1205 when it lands; until then a person reads the hub's mesh through their own trusted node. - Registration does not tell a stranger who is trusted.
mesh.registeranswers an untrusted caller with the hub's own envelope only, never the candidates of trusted nodes. - Default, and optional. The hub's URL is added to
rendezvous.endpointsof this repository's mesh declaration once 1–5 hold and the owner'strust.allowentry for its key is committed; a machine that wants no public rendezvous narrows it out in its working tree, as any declaration can be narrowed.
Důsledky
- Case 491's refusal of a public hub becomes a refusal of a public hub that is not
https://. - ADR 0204's tailnet hub stays the private path; the hosted hub is the path from anywhere.
- The intent
an-authorised-node-connects-from-anywheregains a relay through a trusted hub every node can reach, without NAT traversal of its own. - A leaked hub seed is a key compromise: rotation is the succession path of I2705.
Zamítnuté alternativy
- Open the hub over
http://now and add TLS later. The owner chose TLS first; signed frames cannot be forged, but cleartext can be read on the path. - Leave the mesh readable to anyone. It would publish every node's session intents, claim paths and handover bodies; ADR 0204 already rejected an anonymous public Cockpit.
- Mint a key per boot and enrol it each time. Every restart would need a commit to the trunk.