refactor(secrets): store lives at /secrets, not /srv/secrets

/srv is the projects tree — agents grep, find and `ls -R` it constantly, so a store
under it turns up in ordinary searches and risks being read (or pasted) by accident.
/secrets sits outside that blast radius: nothing routinely walks it, and it is still
0700 loops, still not a repo, still ciphertext at rest.

Override with AO_SECRETS_STORE if a host puts it elsewhere.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-01 16:54:03 +00:00
co-authored by Claude
parent 7605efe624
commit 6c56c1953e
2 changed files with 8 additions and 8 deletions
+3 -3
View File
@@ -363,11 +363,11 @@ Run it by hand with `engine/agents.py up --config agents.toml`.
secret anywhere else** — not in a git remote URL, not in a project `.env`, not in a prompt.
```
/srv/secrets/store.yaml the store: sops+age ciphertext, mode 0600
/secrets/store.yaml the store: sops+age ciphertext, mode 0600
~/.config/sops/age/keys.txt the age private key — the ONE plaintext secret, mode 0600
```
`/srv/secrets/` is deliberately **not a git repo and has no remote**, so there is no path by
`/secrets/` is deliberately **not a git repo and has no remote**, so there is no path by
which a `git add`/`git push` can leak it; the store is ciphertext at rest anyway.
Read it with `engine/secrets.py` (stdlib + the `sops` binary, no Python deps):
@@ -382,7 +382,7 @@ env = get_group("cc_ci_testenv") # a whole group as a dict
python3 engine/secrets.py list # group/key NAMES only — never prints values
python3 engine/secrets.py get tangled.cookie # one value on stdout
python3 engine/secrets.py materialize tangled-session # write a runtime file from the store
sops /srv/secrets/store.yaml # add/edit: decrypts to $EDITOR, re-encrypts on save
sops /secrets/store.yaml # add/edit: decrypts to $EDITOR, re-encrypts on save
```
**Materialized files.** Some consumers read a fixed path and can't be taught otherwise (a systemd