diff --git a/README.md b/README.md index ba7ce81..ee35ee7 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/secrets.py b/secrets.py index 25d8c93..805ec14 100755 --- a/secrets.py +++ b/secrets.py @@ -6,9 +6,9 @@ remote URLs (`https://user:pass@host/...`, which `git remote -v` happily prints) in .env files, a private key at mode 0644. Anything in a repo is one `git add -A` away from a push. So: ONE encrypted file, OUTSIDE every git tree, and a helper every project uses. - store: /srv/secrets/store.yaml sops+age ciphertext, mode 0600 + store: /secrets/store.yaml sops+age ciphertext, mode 0600 age key: ~/.config/sops/age/keys.txt the ONLY plaintext secret on disk, 0600 - outside git by construction — /srv/secrets is not a repo and has no remote. + outside git by construction — /secrets is not a repo and has no remote. USAGE (library): from secrets import get, get_group @@ -23,14 +23,14 @@ USAGE (CLI): MATERIALIZED FILES: some consumers read a fixed path and cannot be taught otherwise (a systemd EnvironmentFile, an ssh IdentityFile, `nix`'s authKeyFile). Those files still exist on disk at 0600, but the STORE IS THE SOURCE OF TRUTH — `materialize` rewrites them from it. -Never edit a materialized file by hand; edit the store (`sops /srv/secrets/store.yaml`) and +Never edit a materialized file by hand; edit the store (`sops /secrets/store.yaml`) and re-materialize, or the two silently drift. -ADDING A SECRET: sops /srv/secrets/store.yaml (opens decrypted in $EDITOR, re-encrypts on save) +ADDING A SECRET: sops /secrets/store.yaml (opens decrypted in $EDITOR, re-encrypts on save) """ import json, os, subprocess, sys, pathlib -STORE = os.environ.get("AO_SECRETS_STORE", "/srv/secrets/store.yaml") +STORE = os.environ.get("AO_SECRETS_STORE", "/secrets/store.yaml") AGE_KEY = os.environ.get("SOPS_AGE_KEY_FILE", os.path.expanduser("~/.config/sops/age/keys.txt")) # name -> (path, mode). Files a consumer reads from a fixed location; see MATERIALIZED FILES.