ADR 0086: a secret reaches a process as a file, and an exception is declared

Closes issue 041 by decision and by code on the same branch: the catalogue
engine refuses a secret in a container's env, and a secret-carrying env-file
unless the container declares its reason; the controller reads all six of
its credentials from files; design 13 states the rule and how it is checked.
This commit is contained in:
2026-09-21 10:10:33 +02:00
parent 7015bf58ac
commit ec7b6e0748
3 changed files with 102 additions and 5 deletions
@@ -5,11 +5,12 @@ code:
- mesh-controller internal/inventory/secrets.go
- mesh-controller cmd/mesh-controller/rotate.go
- mesh-controller examples/postgres-provisioner
updated: 2026-09-20
updated: 2026-09-21
decisions:
- 02-DECISIONS/0001-mesh-brokers-nodes-host-agents-think.md
- 02-DECISIONS/0009-modules-and-the-graph.md
- 02-DECISIONS/0085-a-secret-is-a-provision.md
- 02-DECISIONS/0086-a-secret-reaches-a-process-as-a-file.md
---
# 13 — Credentials, and moving them
@@ -88,6 +89,19 @@ reads exactly like a credential that was never delivered. That has now happened
environment needs a person in the middle of the one path that exists so there is not one, and puts
a superuser password where `docker inspect` prints it.
## A secret reaches a process as a file
The care above ends at the container's door if the module then hands the value to the runtime as
an environment variable: `docker inspect` prints it, and the process's `/proc` entry holds it for
anything on the machine that can talk to the runtime. So a secret reaches a process **as a file**
([ADR 0086](../../02-DECISIONS/0086-a-secret-reaches-a-process-as-a-file.md)): the module mounts
the file the host wrote and points the program at it, and the mesh's own programs take a `_FILE`
twin for every variable that carries a credential. Software that reads only its environment is
not forbidden; it is **declared**, on the container, with a reason, so the manifest says which
secrets are exposed that way. **Checked** at composition: the catalogue engine refuses a
`${secret:…}` in a container's `env` outright, and a secret-carrying file named in `env-file`
unless the container carries the declaration.
## How it is checked
Not by comparing two files. **Two ends holding a matching string proves they agree, not that either