From 1f72e82b8453bf07594520a6c099d5e4c42631a2 Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 30 Sep 2026 02:18:21 +0200 Subject: [PATCH] Issue 129 is resolved: a workstation trusts the mesh, and stops when told to MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registered ca-trust from the catalogue — it was merged and had never been registered, which is why "assign it to one machine" had no module to name — assigned it to the workstation, and verified. Verified in the form ADR 0147 prescribes, against the authority's own API so the handshake needs nothing else in the mesh to be right: 200, issuer Mesh Internal CA, Verify return code 0. Four routed internal names verify too, and `git ls-remote https://…` works, which is the consequence the report named. Removal exercised for the first time. Unassign and push removes the anchor, empties the trust store of the mesh's authority, and returns the plain client to the original error; assigning again restores it. That is the half 0147 claimed and nothing had shown. One thing it found that is not in the module: removal works only because the host removes the service before the script. Stopping the unit is what deletes the certificate and refreshes the bundles, and it needs the script to still exist. The symmetry rests on an ordering nothing states. 0147's "written, and not yet run" now carries a progressive insight saying it has run, where, and that it ran on one machine of four. --- ...47-a-module-anchors-the-meshs-authority.md | 28 ++++++ .../00-report.md | 5 +- .../02-resolution.md | 86 +++++++++++++++++++ 3 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md diff --git a/02-DECISIONS/0147-a-module-anchors-the-meshs-authority.md b/02-DECISIONS/0147-a-module-anchors-the-meshs-authority.md index e0e19a0..b480a3e 100644 --- a/02-DECISIONS/0147-a-module-anchors-the-meshs-authority.md +++ b/02-DECISIONS/0147-a-module-anchors-the-meshs-authority.md @@ -113,6 +113,34 @@ the authority it was bound to, checked in the control plane's own test suite — that verified anything. That is a weaker thing than the paragraph above describes, and it stays written this way until the bed runs. +> **Progressive insight — 2026-09-30. It has now been run, on the live mesh rather than in the bed.** +> The paragraph above said nothing had verified anything, and something has. The module was registered +> from the catalogue, assigned to a workstation, and checked in the form this section prescribes — the +> authority's own API, so the handshake needs nothing else in the mesh to be right: +> +> ``` +> $ curl -sS -o /dev/null -w '%{http_code}' https://:9000/health +> 200 +> subject=CN=Step Online CA +> issuer=O=Mesh Internal CA, CN=Mesh Internal CA Intermediate CA +> Verify return code: 0 (ok) +> ``` +> +> **Both halves.** Unassigning and pushing removed the anchor, emptied the trust store of the mesh's +> authority, and returned the plain client to *unable to get local issuer certificate* — then assigning +> again restored it. The negative half is what distinguishes the anchor working from something else +> having trusted it, and it is the half nothing had ever exercised. +> +> **One thing this found that is not in the module.** The removal only works because the *host* removes +> the service before the script: stopping the unit is what deletes the certificate and refreshes the +> bundles, and it needs the script it calls to still exist. Nothing in the module states that ordering; +> the symmetry this record claims rests on it. +> +> Run on the live mesh because that is where a change is verified now +> ([ADR 0149](0149-the-live-mesh-is-the-test-bed.md)), and the bed still cannot raise a foundation. The +> evidence is [issue 129](../04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md). +> It ran on **one** machine; three others still trust nothing of the mesh's. + ## Consequences The predecessor's authority can be retired from a machine once this module is assigned to it, diff --git a/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/00-report.md b/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/00-report.md index abb3825..742c87a 100644 --- a/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/00-report.md +++ b/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/00-report.md @@ -1,7 +1,8 @@ --- -status: diagnosing +status: resolved opened: 2026-09-26 -located-in: [mesh-catalog ca-trust] +located-in: [mesh-catalog modules/ca-trust] +fixed-by: the ca-trust module registered from the catalogue and assigned to a workstation; verified in both directions 2026-09-30 (02-resolution.md) --- # 129 — nothing makes a machine trust the mesh's own certificate authority diff --git a/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md b/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md new file mode 100644 index 0000000..671d196 --- /dev/null +++ b/04-ISSUES/129-nothing-makes-a-machine-trust-the-meshs-authority/02-resolution.md @@ -0,0 +1,86 @@ +# 129 — resolved: the workstation trusts the mesh, and stops when told to + +*Done and measured on the machine, 2026-09-30.* + +## What was done + +Three steps, not the one the plan expected — the module was merged and had never been registered +(see [the diagnosis](01-diagnosis.md)): + +1. **Registered** `ca-trust` from the catalogue. No artifact to build: it declares a directory, a + script, a unit and a service, and no image. +2. **Assigned** it to the workstation the issue was opened on, and pushed. +3. **Verified** with a plain client, then **unassigned and pushed again** to exercise removal, then + assigned and pushed once more. + +The host's own account of arriving: + +``` +created ca-trust.state (/var/lib/ca-trust) +created ca-trust.anchor (/var/lib/ca-trust/anchor) +created ca-trust.unit (/etc/systemd/system/mesh-ca-trust.service) +updated ca-trust.trust (mesh-ca-trust.service): boot disabled to enabled, stopped to running +``` + +## It works, by the check the report asked for + +The report's own reproduction, with no flags and nothing installed by hand: + +``` +$ curl -sS -o /dev/null -w '%{http_code}' https://git.novox.internal/ +200 +$ openssl s_client -connect git.novox.internal:443 -servername git.novox.internal +issuer=O=Mesh Internal CA, CN=Mesh Internal CA Intermediate CA +Verify return code: 0 (ok) +$ trust list | grep -A2 Mesh + label: Mesh Internal CA Root CA + trust: anchor + category: authority +``` + +Four internal names, all verifying: `git` 200, `umami` 200, `keycloak` 302, `drive` 302. Before this, +every one of them was `curl: (60) … unable to get local issuer certificate (20)`. + +**And the consequence the report named specifically**: git over HTTPS to the mesh's forge, which it said +had forced the working clone URL to be ssh-only. + +``` +$ git ls-remote https://git.novox.internal/novox/hq.git HEAD +76fbe323ea3401fcdadbf500c61bd3fa5a0a8603 HEAD +``` + +## Removal is symmetric, which nothing had ever shown + +[ADR 0147](../../02-DECISIONS/0147-a-module-anchors-the-meshs-authority.md) says the module anchors the +authority *and takes it away again*. That half had never run. Unassigning and pushing: + +``` +removed ca-trust.trust (mesh-ca-trust.service) +removed ca-trust.unit (/etc/systemd/system/mesh-ca-trust.service) +removed ca-trust.anchor (/var/lib/ca-trust/anchor) +removed ca-trust.state (/var/lib/ca-trust) +``` + +Then: the anchor file gone, `trust list` naming no authority of the mesh's, and the plain client back to +`unable to get local issuer certificate (20)`. A machine that leaves the mesh stops trusting it, as the +record claims. + +**The order is what makes it work, and is worth saying.** The service is removed *first*, so systemd +runs the unit's `ExecStop` — which is what deletes the certificate and refreshes the bundles — while the +script it calls still exists. Had the script or the state directory gone first, stopping the unit would +have had nothing to run, and the anchor would have been left behind with nothing declaring it. Nothing +in the module says this; it is the host's removal order that makes the module's symmetry real. + +## What this leaves + +- **One machine, not four.** `novox`, `g14` and `ace` still trust nothing of the mesh's. The report's + reasoning — that being on the private network is what makes a machine one that speaks to the mesh's + names — argues for all of them, and ADR 0147 is written for a module assigned per machine rather than + a fact carried to every machine on the network. Whether it should instead arrive the way the roster + and the registry trust do is a real question and is not this record's to answer. +- **`service-manager` reports `degraded` on this machine** and the module ran anyway. Worth knowing that + the capability gate passes on a degraded service manager, since a module whose whole delivery is a + unit is the kind that would be worst served by one. +- **The predecessor's authority is still in the trust store**, beside the mesh's now rather than instead + of it. The report notes that it cannot be retired while anything on the machine speaks TLS to a mesh + name; that is no longer true here, and retiring it is its own piece of work.