Apply P15: secrets from a systemd credential, the environment or a file

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-23 17:43:08 -07:00
co-authored by Claude Opus 5.5
parent 4a510fde08
commit eab2fbdc55
2 changed files with 7 additions and 5 deletions
+2 -3
View File
@@ -90,9 +90,8 @@ Later changes to the brief:
| 2026-09-17 | The roles table gained a one-sentence Purpose column, and the crates that are not roles got a purpose table under Code constraints. No behaviour changed. | Owner's request: a reader, human or agent, should learn what each piece is for before what it holds. |
| 2026-09-18 | P14, State: the list gained `broker/sessions/<id>.json`, each session's taint and untrusted flag, written only by `brokerd`. | The M3a spec keeps this state in files the list did not name. It can be rebuilt from the audit log's `result` records, so the audit log stays the record of truth. Owner: a plain file also makes debugging easier. |
| 2026-09-22 | P13, Authority contract 4: tool containers run from one image built from source by Nix and named by digest; nothing is pulled at call time. | Approved with the M3 design (2026-09-18); applied when the M3b spec came to rely on it. A pull at call time would be unlisted egress. |
| 2026-09-23 | P15, State, the secrets line: three `SecretStore` backends chosen per secret (a systemd credential by default, an environment variable, an owner-only file), the last two in plaintext and for portability, a file secret warning at startup. | Owner's decision and approval, 2026-09-23 (M4a). The brief's "no plaintext secrets on disk" did not allow the file backend. |
## Proposed changes to the design brief
| # | Change | Reason |
|---|---|---|
| P15 | State, the secrets line, becomes: "Secrets: behind a `SecretStore` trait with three backends, chosen per secret: a systemd credential (encrypted at rest; the key is the host's TPM and host key, not stored beside it), an environment variable, or a file that only the owner can read. The credential backend is the default; the other two put the secret in plaintext, in the process environment or on disk, and are for portability. None in config, none in the repo." | Owner's decision of 2026-09-23. The brief's "No plaintext secrets on disk" does not allow the file backend. |
None pending.
+5 -2
View File
@@ -209,8 +209,11 @@ Files are the source of truth. SQLite is allowed only for rebuildable indexes an
- `audit/*.jsonl` — hash-chained
- `broker/sessions/<id>.json` — each session's taint and untrusted flag, written only by
`brokerd`; it can be rebuilt from the audit log's `result` records
- Secrets: behind a `SecretStore` trait. v0 backend is an encrypted file whose key is not stored
beside it. No plaintext secrets on disk, none in config, none in the repo.
- Secrets: behind a `SecretStore` trait with three backends, chosen per secret: a systemd credential
(encrypted at rest; the key is the host's TPM and host key, not stored beside it), an environment
variable, or a file that only the owner can read. The credential backend is the default; the
other two put the secret in plaintext, in the process environment or on disk, and are for
portability; a file secret prints a warning at startup. None in config, none in the repo.
## Code constraints