--- status: located opened: 2026-09-28 located-in: - mesh-controller internal/catalogue/manifest.go - mesh-controller internal/catalogue/filtering.go - mesh-controller internal/catalogue/declaration.go - mesh-controller examples/route-proxy - mesh-catalog (every routed module manifest) fixed-by: amended-design: 03-DESIGN/01-to-be/08-connectivity.md --- # 140 — An endpoint's reach is not declared, so three mechanisms each decide it separately ## What was observed Preparing to converge the mesh's control-node — the last machine still running the firewall it had before the mesh — the question came up for one module: the forge serves git over ssh, and that port must stay reachable from outside the private network. Where is that said? The manifest declares the port with a source of `mesh`, so the derived filter would close it to everything but the private network. Looking for the place an assignment says otherwise, there are two per-node settings keys: one that gives a module's declared port a machine port, and one that overrides a declared port's source. The second has exactly one caller — the function that builds the node's filter rules. Nothing else in the control plane reads it. A module's routed endpoint is declared somewhere else entirely: a route contribution naming a label and a port. It says nothing about reach. The proxy composes a **public** name and an **internal** name for every route it is given, and obtains a certificate for each from a different authority. Measured on that machine the same day: an identity provider's public name signed by the public authority for 90 days, its internal name signed by the mesh's own intermediate for 24 hours and renewed daily. Both names exist, and both certificates, because the proxy makes every name it can. No assignment asked for either. So the forge's ssh endpoint has a firewall source and nothing else — no name, no certificate, and no way to say it should be public other than a key the filter alone reads. And the forge's web endpoint has two names and two certificates that nobody requested. ## Why it matters beyond this instance **Reach is stated twice, in two vocabularies, in two places that cannot disagree out loud.** A port may be exposed to anywhere while the module contributes no public route; a public route may be served for a module whose own listen is private. Nothing reconciles the pair or refuses it. Each mechanism is separately defensible and the combination is unstated. **The vocabulary belongs to the filter, not to reachability.** *Public, internal, or both* cannot be expressed. A source of `anywhere` is one rule on one chain; it says nothing about which names should exist or which authority should sign them. So "this endpoint must not be public" has no way to be written, and is therefore enforced by nothing — while a public certificate for that very name is obtained automatically. **An endpoint is not a thing in the model.** A module has ports, and separately it has routes. Nothing binds a port to a name to a certificate, which is why three mechanisms each decide reach on their own and none of them is wrong. This is [ADR 0045](../../02-DECISIONS/0045-a-machine-firewall-is-the-sum-of-what-it-listens-on.md)'s fault one level up: that record closed "a declaration that reads as a restriction and restricts nothing" for the packet filter. Here the declaration is absent altogether and the mechanisms guess. **It blocks the certificate work.** The open question recorded for certificates — a name that must not be public needs either DNS-01 or the internal authority only — cannot be answered while no assignment states whether a name should be public. Neither can expiry reporting, revocation, or what happens to a name when a machine leaves: all of them need to know which names were *meant*. ## Open questions - Should an assignment name each of a module's endpoints, bind it to a node-level port, and state whether it is reachable publicly, internally or both — with the filter, the proxy's names and the certificate authority all derived from that one statement? - What is an endpoint that is neither routed nor certified? Git over ssh is public reach with no name and no certificate; the model has to hold that without inventing one. - Are the two existing settings keys the same statement, half-built? If so, is this a new declaration or the completion of theirs? - Does an internal-only endpoint get a certificate at all, and from which authority — and does that settle [issue 129](../129-nothing-makes-a-machine-trust-the-meshs-authority/00-report.md), where nothing installs the mesh's own root? - Does declaring reach per assignment also settle [issue 139](../139-an-internal-route-name-resolves-to-the-consumers-node/00-report.md), where an internal name resolves to the consumer's machine instead of the one serving the endpoint?