From 2c322cb2fba7189c3cb90569534356831509c61b Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 11 Sep 2026 11:38:28 +0200 Subject: [PATCH] mesh-control: the control plane could not read its own connections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its image is FROM scratch and runs as 65534. The host writes a sealed own-secret 0600, owned by root, which is right — but the module then bind-mounted those three files into the container and told the process to open them. It cannot: $ docker run --rm -v <0600 root file>:/run/secrets/inventory:ro \ -e MESH_STORE_INVENTORY_FILE=/run/secrets/inventory mesh-control:development status MESH_STORE_INVENTORY_FILE names /run/secrets/inventory ... and it cannot be read: open /run/secrets/inventory: permission denied Measured on a workstation, not reasoned about. Every other module in this catalogue gets away with the same mount because its runtime container runs as root; this one does not, and genesis (novox/hq ADR 0067) would have stopped at step 9 with a control-plane module that starts and cannot open a context. The connections go through the env file this module already has instead. That file is mode 0600 and is read by the container runtime's client, which is root — the same reason the broker's URL has always reached the process this way. It also sidesteps the inode that a file bind mount pins (290be37, step-ca): --env-file is read afresh at create, and restart-on names it. The own-secrets stay exactly as they were, because the installer delivers the substrate's real connection strings into them with `secret accept` before the first push — the mesh did not make those credentials and cannot invent them. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF --- modules/mesh-control/module.json | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/modules/mesh-control/module.json b/modules/mesh-control/module.json index 1e65f17..3345782 100644 --- a/modules/mesh-control/module.json +++ b/modules/mesh-control/module.json @@ -26,11 +26,11 @@ "mode": "0700" }, { - "id": "broker-env", + "id": "control-env", "type": "file", - "path": "/var/lib/mesh/mesh-control/broker.env", + "path": "/var/lib/mesh/mesh-control/control.env", "mode": "0600", - "content": "MESH_BROKER_AMQP=${secret:broker}\nMESH_BROKER_MANAGEMENT=${secret:broker-management}\nMESH_BROKER_ADDRESS=${machine:at}:5671\n" + "content": "MESH_STORE_INVENTORY=${secret:inventory}\nMESH_STORE_IDENTITY=${secret:identity}\nMESH_STORE_LICENCES=${secret:licences}\nMESH_BROKER_AMQP=${secret:broker}\nMESH_BROKER_MANAGEMENT=${secret:broker-management}\nMESH_BROKER_ADDRESS=${machine:at}:5671\n" }, { "id": "server", @@ -42,27 +42,16 @@ "serve" ], "env-file": [ - "/var/lib/mesh/mesh-control/broker.env" + "/var/lib/mesh/mesh-control/control.env" ], "env": { - "MESH_STORE_INVENTORY_FILE": "/run/secrets/inventory", - "MESH_STORE_IDENTITY_FILE": "/run/secrets/identity", - "MESH_STORE_LICENCES_FILE": "/run/secrets/licences", "MESH_BROKER_CERTIFICATE": "/broker-tls/tls.crt" }, "volumes": [ - "mesh-broker-tls:/broker-tls:ro", - "/var/lib/mesh/mesh-control/inventory:/run/secrets/inventory:ro", - "/var/lib/mesh/mesh-control/identity:/run/secrets/identity:ro", - "/var/lib/mesh/mesh-control/licences:/run/secrets/licences:ro" + "mesh-broker-tls:/broker-tls:ro" ], "restart-on": [ - "needs-inventory", - "needs-identity", - "needs-licences", - "needs-broker", - "needs-broker-management", - "broker-env" + "control-env" ] } ]