hq issue 282 (report on hq's branch issue/282-a-secret-on-a-command-line). No value appears here.
Cause
mosquitto ran docker exec mosquitto mosquitto_ctrl ... -P <admin password> dynsec ... for every administrative call (provisioner every minute, tools). The container runtime records every exec's command line in its event stream (exec_create: <argv>), so docker events, and docker_events with execs: true, returned the broker's admin password.
mosquitto
mosquitto_ctrl runs under a fixed shell (sh -c, no secret in it) that reads the admin name and password from the first two lines of stdin into a 0600 mktemp options file, runs mosquitto_ctrl -o <file> ..., and removes the file on exit. A password a command sets (createClient, setClientPassword) is answered at the tool's own prompt from the rest of stdin. Verified against the pinned image's mosquitto_ctrl 2.1.2 in a local lab with made-up values: -o works, both prompts read stdin, and the recorded exec events carry no value.
dynsec init (bootstrap seed) takes its password on stdin too (docker run -i), so the throwaway container's command line holds none.
Guard: assertNoSecret refuses, before anything runs, an argv carrying the admin password or a password being set (by name, never by value). mqtt_ctrl refuses createClient -p, setClientPassword <user> <password> and init.
Rotation (ADR 0228):own-secrets.admin now says taken: at-start. The bootstrap step names needs-admin under restart-on, keeps the value it last applied in ${dir:state}/admin.applied (0600), and when the mesh's value differs it connects with the applied one and sets the new one online (setClientPassword on stdin), verifies the new one by CONNACK, then records it. The broker keeps running and loses no client. On the first run after this change it verifies the current value by CONNACK and records it. A re-key it cannot do fails the step, by name. Verified live in the lab: first run, unchanged run, rotated run, provisioning (create, reset password, narrow ACLs, holds, delete).
docker
docker_events redacts each exec's command line before it answers: the container's environment secrets (as docker_logs), URI passwords, and by shape (the word after -P/--password/--secret-key/--token..., -a for redis-cli, -p for mosquitto_ctrl unless a number, NAME=value named like a secret, the password a dynsec command sets). The answer lists what was redacted, by name.
New docker_secrets_in_events: reads the exec_create events of a window (60 min default, at most 24 h) and names each secret by container, module, what it was and the program, with counts and first/last time, never the value.
docker_inspect redacts Args, Config.Cmd and Config.Entrypoint the same way.
Other modules found passing a secret on a command line
keycloak repair script: kcadm.sh ... --password "$TMP_PW" and set-password --new-password "$NEW_PW" inside the container (on the JVM's argv while it ran; not a runtime event). Now KC_CLI_PASSWORD per command, verified against Keycloak 26.0.8 in a local lab.
minio: mc alias set mesh <url> <root user> <root password> on the runtime's process argv (and kept in mc's alias file). Now MC_HOST_mesh in mc's environment, with a guard. Still open:mc admin user svcacct add --secret-key <consumer secret> has no other way in; noted in the code and the issue.
Not fixed here, in the issue: gitea's run-once admin-bootstrap passes --password "$(cat /run/secrets/admin)" to the gitea CLI inside its container (expanded in-container; process table only, not a runtime event).
Checked and clean: mssql and nats dumps (stdin), mongodb dump (options file written in-container by a builtin), postgres and supabase dumps (no password), keycloak's own docker exec (stdin), nextcloud, mailu, gitea delivery, nats monitor (no secret).
Checks
merge-check.sh with a locally built controller as MESH_GATE: manifests ok; go test -race for docker and keycloak pass; mosquitto (TypeScript): tsc clean and npm test 11/11 (new: ctrl shape, guard, tool refusal, a fake mosquitto_ctrl checking the options file is 0600 and no password reaches argv); minio tsc clean.
Rollout
Merge, let the pipeline deliver to the home server. On that apply the bootstrap re-runs (its bundle changed) and records the current admin value as applied. Then rotate the admin secret (the issue states the call; it waits for the operator's approval).
hq issue 282 (report on hq's branch `issue/282-a-secret-on-a-command-line`). No value appears here.
## Cause
`mosquitto` ran `docker exec mosquitto mosquitto_ctrl ... -P <admin password> dynsec ...` for every administrative call (provisioner every minute, tools). The container runtime records every exec's command line in its event stream (`exec_create: <argv>`), so `docker events`, and `docker_events` with `execs: true`, returned the broker's admin password.
## mosquitto
- `mosquitto_ctrl` runs under a fixed shell (`sh -c`, no secret in it) that reads the admin name and password from the first two lines of stdin into a 0600 `mktemp` options file, runs `mosquitto_ctrl -o <file> ...`, and removes the file on exit. A password a command sets (`createClient`, `setClientPassword`) is answered at the tool's own prompt from the rest of stdin. Verified against the pinned image's mosquitto_ctrl 2.1.2 in a local lab with made-up values: `-o` works, both prompts read stdin, and the recorded exec events carry no value.
- `dynsec init` (bootstrap seed) takes its password on stdin too (`docker run -i`), so the throwaway container's command line holds none.
- Guard: `assertNoSecret` refuses, before anything runs, an argv carrying the admin password or a password being set (by name, never by value). `mqtt_ctrl` refuses `createClient -p`, `setClientPassword <user> <password>` and `init`.
- **Rotation (ADR 0228):** `own-secrets.admin` now says `taken: at-start`. The bootstrap step names `needs-admin` under `restart-on`, keeps the value it last applied in `${dir:state}/admin.applied` (0600), and when the mesh's value differs it connects with the applied one and sets the new one online (`setClientPassword` on stdin), verifies the new one by CONNACK, then records it. The broker keeps running and loses no client. On the first run after this change it verifies the current value by CONNACK and records it. A re-key it cannot do fails the step, by name. Verified live in the lab: first run, unchanged run, rotated run, provisioning (create, reset password, narrow ACLs, holds, delete).
## docker
- `docker_events` redacts each exec's command line before it answers: the container's environment secrets (as `docker_logs`), URI passwords, and by shape (the word after `-P`/`--password`/`--secret-key`/`--token`..., `-a` for redis-cli, `-p` for mosquitto_ctrl unless a number, `NAME=value` named like a secret, the password a dynsec command sets). The answer lists what was redacted, by name.
- New `docker_secrets_in_events`: reads the `exec_create` events of a window (60 min default, at most 24 h) and names each secret by container, module, what it was and the program, with counts and first/last time, never the value.
- `docker_inspect` redacts `Args`, `Config.Cmd` and `Config.Entrypoint` the same way.
## Other modules found passing a secret on a command line
- `keycloak` repair script: `kcadm.sh ... --password "$TMP_PW"` and `set-password --new-password "$NEW_PW"` inside the container (on the JVM's argv while it ran; not a runtime event). Now `KC_CLI_PASSWORD` per command, verified against Keycloak 26.0.8 in a local lab.
- `minio`: `mc alias set mesh <url> <root user> <root password>` on the runtime's process argv (and kept in mc's alias file). Now `MC_HOST_mesh` in `mc`'s environment, with a guard. **Still open:** `mc admin user svcacct add --secret-key <consumer secret>` has no other way in; noted in the code and the issue.
- Not fixed here, in the issue: `gitea`'s run-once `admin-bootstrap` passes `--password "$(cat /run/secrets/admin)"` to the gitea CLI inside its container (expanded in-container; process table only, not a runtime event).
- Checked and clean: mssql and nats dumps (stdin), mongodb dump (options file written in-container by a builtin), postgres and supabase dumps (no password), keycloak's own `docker exec` (stdin), nextcloud, mailu, gitea delivery, nats monitor (no secret).
## Checks
`merge-check.sh` with a locally built controller as `MESH_GATE`: manifests ok; `go test -race` for docker and keycloak pass; mosquitto (TypeScript): `tsc` clean and `npm test` 11/11 (new: ctrl shape, guard, tool refusal, a fake mosquitto_ctrl checking the options file is 0600 and no password reaches argv); minio `tsc` clean.
## Rollout
Merge, let the pipeline deliver to the home server. On that apply the bootstrap re-runs (its bundle changed) and records the current admin value as applied. Then rotate the admin secret (the issue states the call; it waits for the operator's approval).
mesh/merge-gate pass: builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person; every machine composes with…
mosquitto passed the broker's admin password to mosquitto_ctrl as -P on
every docker exec, and the container runtime keeps every exec's command
line in its event stream, where docker_events returned it. The admin
credentials now reach mosquitto_ctrl as a 0600 options file fed on
stdin, client passwords at its own prompt, and an argv carrying a secret
is refused before it runs. The admin secret says it is taken at start:
the bootstrap re-runs when the mesh replaces it and re-keys the broker
online from the value it last applied, so it can be rotated.
docker_events redacts what an exec's command line carried, and
docker_secrets_in_events names such secrets by name. keycloak's repair
hands kcadm its passwords through KC_CLI_PASSWORD; minio gives mc its
root alias through MC_HOST_mesh.
Deliverynovox/mesh-catalog@13b7562c47b1 — delivered since 2026-10-06T23:44:48Z
Delivery plan — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
tier 0: docker, keycloak, minio, mosquitto
ace: receives docker, mosquitto
g14: receives docker
novox: receives docker; waits for a person: keycloak, minio
shanks: receives docker
keycloak waits for a person: its policy records (module)
keycloak provides oidc-client: its consumers are sent again after it
keycloak keeps data (ADR 0233): what it holds is backed up before it moves
minio waits for a person: its policy records (module)
minio provides s3-bucket: its consumers are sent again after it
minio keeps data (ADR 0233): what it holds is backed up before it moves
mosquitto provides mqtt-topic: its consumers are sent again after it
mosquitto keeps data (ADR 0233): what it holds is backed up before it moves
Machines
docker on ace: passed — healthy 3 times over 2m27s
mosquitto on ace: passed — judged with docker: healthy 3 times over 2m27s
docker on the rest running it: sent
mosquitto on the rest running it: sent
Transitions
2026-10-06 23:38 (new) → proposed (announced): novox/mesh-catalog#100's head announced
2026-10-06 23:40 proposed → checked (checked): the verdict names this commit
2026-10-06 23:40 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-06 23:41 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-06 23:41 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
2026-10-06 23:44 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@13b7562c47b1` — **delivered** since 2026-10-06T23:44:48Z
**Delivery plan** — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
- tier 0: docker, keycloak, minio, mosquitto
- ace: receives docker, mosquitto
- g14: receives docker
- novox: receives docker; waits for a person: keycloak, minio
- shanks: receives docker
- keycloak waits for a person: its policy records (module)
- keycloak provides oidc-client: its consumers are sent again after it
- keycloak keeps data (ADR 0233): what it holds is backed up before it moves
- minio waits for a person: its policy records (module)
- minio provides s3-bucket: its consumers are sent again after it
- minio keeps data (ADR 0233): what it holds is backed up before it moves
- mosquitto provides mqtt-topic: its consumers are sent again after it
- mosquitto keeps data (ADR 0233): what it holds is backed up before it moves
**Machines**
- docker on ace: passed — healthy 3 times over 2m27s
- mosquitto on ace: passed — judged with docker: healthy 3 times over 2m27s
- docker on the rest running it: sent
- mosquitto on the rest running it: sent
**Transitions**
- 2026-10-06 23:38 (new) → proposed (announced): novox/mesh-catalog#100's head announced
- 2026-10-06 23:40 proposed → checked (checked): the verdict names this commit
- 2026-10-06 23:40 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-06 23:41 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-06 23:41 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
- 2026-10-06 23:44 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate: PASS — every machine composes with the change as it did without (0 of 4 compose) (modules: docker, keycloak, minio, mosquitto)
mesh/repo-check: PASS — its merge-check.sh passed
Change plan — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
tier 0: docker, keycloak, minio, mosquitto
ace: receives docker, mosquitto
g14: receives docker
novox: receives docker; waits for a person: keycloak, minio
shanks: receives docker
keycloak waits for a person: its policy records (module)
keycloak provides oidc-client: its consumers are sent again after it
keycloak keeps data (ADR 0233): what it holds is backed up before it moves
minio waits for a person: its policy records (module)
minio provides s3-bucket: its consumers are sent again after it
minio keeps data (ADR 0233): what it holds is backed up before it moves
mosquitto provides mqtt-topic: its consumers are sent again after it
mosquitto keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on g14 as build-1791329888834756367 (builds --log build-1791329888834756367).
--- the gate: docker, keycloak, minio, mosquitto
docker: ok, 20 tool(s)
keycloak: ok
minio: ok, keeps data (valuable)
mosquitto: ok, keeps data (rebuildable)
4 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 3 module(s) changed against 4 machine(s), as the snapshot of 2026-10-06T23:08:02Z says they run
composing every machine as the mesh is
composing every machine with the change
merge gate: PASS — every machine composes with the change as it did without (0 of 4 compose)
judged by controller development build against the facts of 2026-10-06T23:08:02Z
modules the change moves:
- docker (changed)
- minio (changed)
- mosquitto (changed)
machines:
- a machine (f35): does not compose
- holds mesh-dns-resolver (idt): does not compose
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): does not compose
- a machine (yvbpsm): does not compose
a merge would rebuild 4 module(s) in 1 tier(s): docker, keycloak, minio, mosquitto
notes:
- the mesh's settings of nzbget are not kept: refused: nzbget on the mesh cannot compose with the layer "the mesh" — nzbget has a file that says ${setting:username}, and nothing sets "username" for it — an operator's value is the assignment's, never the definition's (novox/hq ADR 0112): `settings set nzbget <file>` with {"username": …}; set today: pgid, puid
- the mesh's settings of qbittorrent are not kept: refused: qbittorrent on the mesh cannot compose with the layer "the mesh" — qbittorrent has a file that says ${setting:username}, and nothing sets "username" for it — an operator's value is the assignment's, never the definition's (novox/hq ADR 0112): `settings set qbittorrent <file>` with {"username": …}; set today: pgid, puid
- a machine (f35)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (f35)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s settings of plex are not kept: refused: plex on idt cannot compose with the layer "idt" — plex places the access "formula-1" at withheld, which is not an absolute path
- holds mesh-dns-resolver (idt)'s given broker for baserow is not kept: baserow does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for bazarr is not kept: bazarr does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for bookshelf is not kept: bookshelf does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for grafana is not kept: grafana does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for home-assistant is not kept: home-assistant does not declare "broker" as an own secret; it declares: token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for icecast is not kept: icecast does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for influxdb is not kept: influxdb does not declare "broker" as an own secret; it declares: admin, admin-token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for jackett is not kept: jackett does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for kometa is not kept: kometa does not declare "broker" as an own secret; it declares: tmdb — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for letta is not kept: letta does not declare "broker" as an own secret; it declares: openai-api-key, server-password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for lidarr is not kept: lidarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for mosquitto is not kept: mosquitto does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for mssql is not kept: mssql does not declare "broker" as an own secret; it declares: reader, sa — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nodered is not kept: nodered does not declare "broker" as an own secret; it declares: admin, api-token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nzbget is not kept: nzbget does not declare "broker" as an own secret; it declares: password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for ombi is not kept: ombi does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for plex is not kept: plex does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for postgres is not kept: postgres does not declare "broker" as an own secret; it declares: reader, superuser — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for qbittorrent is not kept: qbittorrent does not declare "broker" as an own secret; it declares: password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for radarr is not kept: radarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for redis is not kept: redis does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for searxng is not kept: searxng does not declare "broker" as an own secret; it declares: secret — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for sonarr is not kept: sonarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for tautulli is not kept: tautulli does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for unifi is not kept: unifi does not declare "broker" as an own secret; it declares: controller — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for gitea is not kept: gitea does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for keycloak is not kept: keycloak does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mailu is not kept: mailu does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mesh-catalog is not kept: mesh-catalog does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mesh-vault is not kept: mesh-vault does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for minio is not kept: minio does not declare "broker" as an own secret; it declares: root — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mongodb is not kept: mongodb does not declare "broker" as an own secret; it declares: root — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mssql is not kept: mssql does not declare "broker" as an own secret; it declares: reader, sa — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for nextcloud is not kept: nextcloud does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for postgres is not kept: postgres does not declare "broker" as an own secret; it declares: reader, superuser — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for records is not kept: records does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for umami is not kept: umami does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for lab is not kept: lab does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (f35) composes on the mesh and not as the snapshot raised it: build-agent on f35 has no bus credential: nothing was issued for f35.build-agent, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue build-agent --node f35`, then push again — judged by what the change adds
- holds mesh-dns-resolver (idt) composes on the mesh and not as the snapshot raised it: route-proxy on idt has no bus credential: nothing was issued for idt.route-proxy, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue route-proxy --node idt`, then push again — judged by what the change adds
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr) composes on the mesh and not as the snapshot raised it: distribution on ygcyr has no bus credential: nothing was issued for ygcyr.distribution, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue distribution --node ygcyr`, then push again — judged by what the change adds
- a machine (yvbpsm) composes on the mesh and not as the snapshot raised it: build-agent on yvbpsm has no bus credential: nothing was issued for yvbpsm.build-agent, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue build-agent --node yvbpsm`, then push again — judged by what the change adds
--- its merge-check.sh (go toolchain)
testing modules/docker
ok docker/cmd/docker-tools 1.020s
testing modules/keycloak
ok keycloak/cmd/keycloak-provider 1.311s
NOT TESTED HERE: modules/minio is TypeScript; the gate judges its manifest
NOT TESTED HERE: modules/mosquitto is TypeScript; the gate judges its manifest
**Merge check** at `13b7562c`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (0 of 4 compose) (modules: docker, keycloak, minio, mosquitto)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Change plan** — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
- tier 0: docker, keycloak, minio, mosquitto
- ace: receives docker, mosquitto
- g14: receives docker
- novox: receives docker; waits for a person: keycloak, minio
- shanks: receives docker
- keycloak waits for a person: its policy records (module)
- keycloak provides oidc-client: its consumers are sent again after it
- keycloak keeps data (ADR 0233): what it holds is backed up before it moves
- minio waits for a person: its policy records (module)
- minio provides s3-bucket: its consumers are sent again after it
- minio keeps data (ADR 0233): what it holds is backed up before it moves
- mosquitto provides mqtt-topic: its consumers are sent again after it
- mosquitto keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on g14 as `build-1791329888834756367` (`builds --log build-1791329888834756367`).
```
--- the gate: docker, keycloak, minio, mosquitto
docker: ok, 20 tool(s)
keycloak: ok
minio: ok, keeps data (valuable)
mosquitto: ok, keeps data (rebuildable)
4 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 3 module(s) changed against 4 machine(s), as the snapshot of 2026-10-06T23:08:02Z says they run
composing every machine as the mesh is
composing every machine with the change
merge gate: PASS — every machine composes with the change as it did without (0 of 4 compose)
judged by controller development build against the facts of 2026-10-06T23:08:02Z
modules the change moves:
- docker (changed)
- minio (changed)
- mosquitto (changed)
machines:
- a machine (f35): does not compose
- holds mesh-dns-resolver (idt): does not compose
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): does not compose
- a machine (yvbpsm): does not compose
a merge would rebuild 4 module(s) in 1 tier(s): docker, keycloak, minio, mosquitto
notes:
- the mesh's settings of nzbget are not kept: refused: nzbget on the mesh cannot compose with the layer "the mesh" — nzbget has a file that says ${setting:username}, and nothing sets "username" for it — an operator's value is the assignment's, never the definition's (novox/hq ADR 0112): `settings set nzbget <file>` with {"username": …}; set today: pgid, puid
- the mesh's settings of qbittorrent are not kept: refused: qbittorrent on the mesh cannot compose with the layer "the mesh" — qbittorrent has a file that says ${setting:username}, and nothing sets "username" for it — an operator's value is the assignment's, never the definition's (novox/hq ADR 0112): `settings set qbittorrent <file>` with {"username": …}; set today: pgid, puid
- a machine (f35)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (f35)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s settings of plex are not kept: refused: plex on idt cannot compose with the layer "idt" — plex places the access "formula-1" at withheld, which is not an absolute path
- holds mesh-dns-resolver (idt)'s given broker for baserow is not kept: baserow does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for bazarr is not kept: bazarr does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for bookshelf is not kept: bookshelf does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for grafana is not kept: grafana does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for home-assistant is not kept: home-assistant does not declare "broker" as an own secret; it declares: token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for icecast is not kept: icecast does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for influxdb is not kept: influxdb does not declare "broker" as an own secret; it declares: admin, admin-token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for jackett is not kept: jackett does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for kometa is not kept: kometa does not declare "broker" as an own secret; it declares: tmdb — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for letta is not kept: letta does not declare "broker" as an own secret; it declares: openai-api-key, server-password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for lidarr is not kept: lidarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for mosquitto is not kept: mosquitto does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for mssql is not kept: mssql does not declare "broker" as an own secret; it declares: reader, sa — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nodered is not kept: nodered does not declare "broker" as an own secret; it declares: admin, api-token — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for nzbget is not kept: nzbget does not declare "broker" as an own secret; it declares: password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for ombi is not kept: ombi does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for plex is not kept: plex does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for postgres is not kept: postgres does not declare "broker" as an own secret; it declares: reader, superuser — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for qbittorrent is not kept: qbittorrent does not declare "broker" as an own secret; it declares: password — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for radarr is not kept: radarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for redis is not kept: redis does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for searxng is not kept: searxng does not declare "broker" as an own secret; it declares: secret — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for sonarr is not kept: sonarr does not declare "broker" as an own secret; it declares: api-key — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for tautulli is not kept: tautulli does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds mesh-dns-resolver (idt)'s given broker for unifi is not kept: unifi does not declare "broker" as an own secret; it declares: controller — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for gitea is not kept: gitea does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for keycloak is not kept: keycloak does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mailu is not kept: mailu does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mesh-catalog is not kept: mesh-catalog does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mesh-vault is not kept: mesh-vault does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for minio is not kept: minio does not declare "broker" as an own secret; it declares: root — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mongodb is not kept: mongodb does not declare "broker" as an own secret; it declares: root — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for mssql is not kept: mssql does not declare "broker" as an own secret; it declares: reader, sa — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for nextcloud is not kept: nextcloud does not declare "broker" as an own secret; it declares: admin — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for postgres is not kept: postgres does not declare "broker" as an own secret; it declares: reader, superuser — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for records is not kept: records does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr)'s given broker for umami is not kept: umami does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for fail2ban is not kept: fail2ban does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for lab is not kept: lab does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (yvbpsm)'s given broker for nftables is not kept: nftables does not declare "broker" as an own secret; it declares no own secrets — a secret it requires from a provider is accepted with `--provider <node> [--local <name>]`, the value the running service already uses (novox/hq ADR 0163)
- a machine (f35) composes on the mesh and not as the snapshot raised it: build-agent on f35 has no bus credential: nothing was issued for f35.build-agent, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue build-agent --node f35`, then push again — judged by what the change adds
- holds mesh-dns-resolver (idt) composes on the mesh and not as the snapshot raised it: route-proxy on idt has no bus credential: nothing was issued for idt.route-proxy, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue route-proxy --node idt`, then push again — judged by what the change adds
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr) composes on the mesh and not as the snapshot raised it: distribution on ygcyr has no bus credential: nothing was issued for ygcyr.distribution, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue distribution --node ygcyr`, then push again — judged by what the change adds
- a machine (yvbpsm) composes on the mesh and not as the snapshot raised it: build-agent on yvbpsm has no bus credential: nothing was issued for yvbpsm.build-agent, and a push would seal a placeholder its process cannot read (novox/hq issue 203). `module issue build-agent --node yvbpsm`, then push again — judged by what the change adds
--- its merge-check.sh (go toolchain)
testing modules/docker
ok docker/cmd/docker-tools 1.020s
testing modules/keycloak
ok keycloak/cmd/keycloak-provider 1.311s
NOT TESTED HERE: modules/minio is TypeScript; the gate judges its manifest
NOT TESTED HERE: modules/mosquitto is TypeScript; the gate judges its manifest
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
hq issue 282 (report on hq's branch
issue/282-a-secret-on-a-command-line). No value appears here.Cause
mosquittorandocker exec mosquitto mosquitto_ctrl ... -P <admin password> dynsec ...for every administrative call (provisioner every minute, tools). The container runtime records every exec's command line in its event stream (exec_create: <argv>), sodocker events, anddocker_eventswithexecs: true, returned the broker's admin password.mosquitto
mosquitto_ctrlruns under a fixed shell (sh -c, no secret in it) that reads the admin name and password from the first two lines of stdin into a 0600mktempoptions file, runsmosquitto_ctrl -o <file> ..., and removes the file on exit. A password a command sets (createClient,setClientPassword) is answered at the tool's own prompt from the rest of stdin. Verified against the pinned image's mosquitto_ctrl 2.1.2 in a local lab with made-up values:-oworks, both prompts read stdin, and the recorded exec events carry no value.dynsec init(bootstrap seed) takes its password on stdin too (docker run -i), so the throwaway container's command line holds none.assertNoSecretrefuses, before anything runs, an argv carrying the admin password or a password being set (by name, never by value).mqtt_ctrlrefusescreateClient -p,setClientPassword <user> <password>andinit.own-secrets.adminnow saystaken: at-start. The bootstrap step namesneeds-adminunderrestart-on, keeps the value it last applied in${dir:state}/admin.applied(0600), and when the mesh's value differs it connects with the applied one and sets the new one online (setClientPasswordon stdin), verifies the new one by CONNACK, then records it. The broker keeps running and loses no client. On the first run after this change it verifies the current value by CONNACK and records it. A re-key it cannot do fails the step, by name. Verified live in the lab: first run, unchanged run, rotated run, provisioning (create, reset password, narrow ACLs, holds, delete).docker
docker_eventsredacts each exec's command line before it answers: the container's environment secrets (asdocker_logs), URI passwords, and by shape (the word after-P/--password/--secret-key/--token...,-afor redis-cli,-pfor mosquitto_ctrl unless a number,NAME=valuenamed like a secret, the password a dynsec command sets). The answer lists what was redacted, by name.docker_secrets_in_events: reads theexec_createevents of a window (60 min default, at most 24 h) and names each secret by container, module, what it was and the program, with counts and first/last time, never the value.docker_inspectredactsArgs,Config.CmdandConfig.Entrypointthe same way.Other modules found passing a secret on a command line
keycloakrepair script:kcadm.sh ... --password "$TMP_PW"andset-password --new-password "$NEW_PW"inside the container (on the JVM's argv while it ran; not a runtime event). NowKC_CLI_PASSWORDper command, verified against Keycloak 26.0.8 in a local lab.minio:mc alias set mesh <url> <root user> <root password>on the runtime's process argv (and kept in mc's alias file). NowMC_HOST_meshinmc's environment, with a guard. Still open:mc admin user svcacct add --secret-key <consumer secret>has no other way in; noted in the code and the issue.gitea's run-onceadmin-bootstrappasses--password "$(cat /run/secrets/admin)"to the gitea CLI inside its container (expanded in-container; process table only, not a runtime event).docker exec(stdin), nextcloud, mailu, gitea delivery, nats monitor (no secret).Checks
merge-check.shwith a locally built controller asMESH_GATE: manifests ok;go test -racefor docker and keycloak pass; mosquitto (TypeScript):tscclean andnpm test11/11 (new: ctrl shape, guard, tool refusal, a fake mosquitto_ctrl checking the options file is 0600 and no password reaches argv); miniotscclean.Rollout
Merge, let the pipeline deliver to the home server. On that apply the bootstrap re-runs (its bundle changed) and records the current admin value as applied. Then rotate the admin secret (the issue states the call; it waits for the operator's approval).
Delivery
novox/mesh-catalog@13b7562c47b1— delivered since 2026-10-06T23:44:48ZDelivery plan — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
13b7562cmesh/merge-gate: PASS — every machine composes with the change as it did without (0 of 4 compose) (modules: docker, keycloak, minio, mosquitto)mesh/repo-check: PASS — its merge-check.sh passedChange plan — builds docker, keycloak, minio, mosquitto → ace, g14, novox, shanks; no bus step; 2 wait(s) for a person
Run by the build seat on g14 as
build-1791329888834756367(builds --log build-1791329888834756367).