Say plainly that env-file never points at a sealed secret
The playbook offered `env-file` and `${secret:name}` as alternatives,
and that reading is what produced the bug every example module shipped
with: own-secrets pointing at a path named `.env`, mounted as env-file,
holding a bare password. The container starts with no password set —
which is a service running on the wrong credential, not a failure.
They are not alternatives. A sealed file holds a password and nothing
else, so env-file points at a file the module declares whose content
leaves a hole, and the host fills it on the machine. A provisioner is
the exception, because it reads a password file.
Written out as the three lines a module needs, with the failure it
prevents named, since the abstract version was already there and was
read the other way.
This commit is contained in:
@@ -38,10 +38,35 @@ Three questions, answered from the machine:
|
||||
it and removed after them.
|
||||
|
||||
4. **Put every secret in a file, never in `env`.** A declaration travels over the broker in plain
|
||||
text: a password in `env` is a password the broker sees. Use `env-file` for containers, or
|
||||
`${secret:name}` inside a config file the module supplies. **The mesh delivers parts; a module
|
||||
text: a password in `env` is a password the broker sees. **The mesh delivers parts; a module
|
||||
that needs them combined combines them.**
|
||||
|
||||
**A sealed file holds the password and nothing else** — no key, no `=`, no newline that means
|
||||
anything. So `env-file` must never point at one. It points at a file the module *declares*,
|
||||
whose content leaves a hole:
|
||||
|
||||
```
|
||||
own-secrets superuser → /var/lib/postgres/superuser.secret the password, alone
|
||||
a file /var/lib/postgres/superuser.env, mode 0600,
|
||||
content: POSTGRES_PASSWORD=${secret:superuser}
|
||||
the container env-file: [/var/lib/postgres/superuser.env]
|
||||
```
|
||||
|
||||
The host fills the hole on the machine, which is the only place both halves exist — the mesh
|
||||
discarded the value
|
||||
([credentials and their rotation](../../03-DESIGN/01-to-be/13-credentials-and-their-rotation.md)).
|
||||
A **provisioner** is the exception: it reads a password file, so it mounts the `.secret`
|
||||
directly.
|
||||
|
||||
Every example module in `mesh-control` had this wrong and shipped: `own-secrets` pointing at a
|
||||
path *named* `.env`, mounted as `env-file`, holding a bare password. Docker reads that as a
|
||||
malformed line and the container starts **with no password set at all** — not a failure to
|
||||
start, a service running on the wrong credential. They parsed and they resolved. Two tests in
|
||||
`examples/modules` now refuse both halves of it.
|
||||
|
||||
Add `restart-on` naming the env file, or the container keeps the credential it started with
|
||||
through every rotation.
|
||||
|
||||
5. **Pin every image by digest.** A tag moves. The manifest in a repository names artifacts; the
|
||||
manifest the mesh holds names digests, and they are not the same document.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user