Place the two new records in the reading order, and fix a link the merge moved
Both carried a topic outside the six the index knows, so neither had a place to be read in — 0067 had none at all. Both are 'the tiers', beside 0036 (bootstrap ends at a usable mesh) and 0007 (connectivity), which is what they extend. 0067 cited 0041 for tier 0's property; on this trunk 0041 is events, and the record it meant is 0005. A citation that resolves to the wrong record reads as corroboration, which is worse than a dead link. Claude-Session: https://claude.ai/code/session_01LrgweAeERJYBg88c5cKDzF
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
---
|
||||
status: open
|
||||
opened: 2026-09-10
|
||||
located-in: []
|
||||
fixed-by:
|
||||
amended-design:
|
||||
---
|
||||
|
||||
# 041 — A credential the mesh took care to seal ends up in the process environment
|
||||
|
||||
## Symptom
|
||||
|
||||
The mesh generates a module's own secret, **seals it to the machine and discards the plaintext** —
|
||||
it cannot read the value back even if asked. The host unseals it into a file the module names, at
|
||||
`0600`.
|
||||
|
||||
Then the module hands it to its container as an environment variable, and the runtime puts it
|
||||
where anything on that machine that can talk to the runtime can read it: `docker inspect` prints
|
||||
it, and `/proc/<pid>/environ` holds it for the life of the process.
|
||||
|
||||
Observed while making the control plane an ordinary module. Its **store** connections were moved to
|
||||
files, read by a `…_FILE` variable naming the path. Its **broker** credentials have no such variable,
|
||||
so they are still delivered through an env-file — which the runtime turns into exactly the
|
||||
environment above. Same credential handling, same machine, two different exposures, decided by
|
||||
whether the program that reads it happens to accept a path.
|
||||
|
||||
## Why this matters
|
||||
|
||||
**The care taken elsewhere is what makes this stand out.** Sealing to a machine and discarding the
|
||||
plaintext is expensive and deliberate: it exists so that a credential is readable only where it is
|
||||
used. Handing that same value to the runtime as an environment variable gives it back to anything
|
||||
that can run `inspect` — and `inspect` is a routine operation. It lands in support output, in
|
||||
captured logs, in a screenshot of a terminal, and in any tooling that dumps container state.
|
||||
|
||||
**It is not a module's mistake.** Nothing in the manifest format is being misused: placing a secret
|
||||
into an env-file with `${secret:…}` is a supported shape and other modules use it. So each module is
|
||||
correct on its own, and the property — *a sealed credential is not readable by everything on the
|
||||
machine* — holds or fails per variable, by accident of what each program accepts.
|
||||
|
||||
**And the two halves now disagree inside one module.** The control plane reads its store connection
|
||||
from a file and its broker credential from the environment. A reader cannot tell from the manifest
|
||||
which secrets are protected from `inspect` and which are not, because the manifest looks the same
|
||||
either way.
|
||||
|
||||
## Open questions
|
||||
|
||||
- Should every program the mesh runs accept a path for anything secret — a `…_FILE` twin as a
|
||||
convention rather than a thing each program decides? That is a small change in several programs
|
||||
and a large one in what the manifest can promise.
|
||||
- Should the manifest layer **refuse** `${secret:…}` inside a container's `env`, or inside an
|
||||
`env-file`, once a path-shaped alternative exists? A rule nothing enforces is the shape this
|
||||
repository keeps finding.
|
||||
- Is there a case where the environment is genuinely the only channel — a program that cannot be
|
||||
changed and reads no file? If so, what should the mesh say about that module, out loud, rather
|
||||
than treating it as equivalent?
|
||||
- What is the actual reach of the exposure on a node — which identities can talk to the container
|
||||
runtime, and is that set smaller than "anything running as the operator"? The answer decides
|
||||
whether this is a hardening item or something sharper.
|
||||
Reference in New Issue
Block a user