diff --git a/docs/decisions.md b/docs/decisions.md index 9a35ff4..10a464e 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -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/.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. diff --git a/docs/design.md b/docs/design.md index 4ef487e..02487d4 100644 --- a/docs/design.md +++ b/docs/design.md @@ -209,8 +209,11 @@ Files are the source of truth. SQLite is allowed only for rebuildable indexes an - `audit/*.jsonl` — hash-chained - `broker/sessions/.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