A module names who its secret files belong to (secrets-owner)

The control plane runs as 65534 and crash-looped on permission denied the
first time its credentials were mounted as files the host wrote as root at
0600 — the env-file shape hid this because the daemon reads an env-file on
the host side. The composer now gives a module's secret files the owner the
manifest names.
This commit is contained in:
2026-09-21 10:19:00 +02:00
parent 4531f2244f
commit 69bb0fcb67
3 changed files with 55 additions and 4 deletions
+12
View File
@@ -297,6 +297,18 @@ type Manifest struct {
// module, in a file anybody can read, for ever.
OwnSecrets map[string]string `json:"own-secrets,omitempty"`
// SecretsOwner is who the files holding this module's secrets belong to on the machine —
// `uid:gid`, or a name — when its process is not root.
//
// **A secret reaches a process as a file** (novox/hq ADR 0086), and a file the host writes at
// 0600 as root is a file a container running as another account cannot read: the control
// plane, `USER 65534` in a scratch image, crash-looped on `permission denied` the first time
// its credentials were mounted instead of read from an env-file (which the daemon reads, as
// root, on the host side — which is exactly why that shape hid the problem). Absent means
// root, which is what a process that runs as root needs and what a process that does not
// cannot use.
SecretsOwner string `json:"secrets-owner,omitempty"`
// Keeps is where this module wants every operator-sealed secret in the mesh written — the
// vault's field, and so far nobody else's (novox/hq ADR 0085, amended).
//