# secrets/ SOPS-encrypted YAML files. The plaintext lives only in transit and in the operator's head — committed files are always ciphertext. ## Conventions - One file per logical grouping (e.g. `gitea-tokens.yaml`, `webhook-hmacs.yaml`, `api-keys.yaml`). - Recipients are declared in `../.sops.yaml` by path-regex, not per-file. - The plaintext schema inside each file is free-form YAML; the consumer code decides what it expects (e.g. `gitea-tokens.yaml` contains `{"": "ghp_xxx"}`). ## How to add a secret ```bash # 1. Decide which clients should be able to decrypt it; edit ../.sops.yaml to # list their age public keys for the new path_regex. # 2. Create the plaintext, encrypt in place: sops -e --in-place secrets/my-thing.yaml # 3. Commit + push. The 5-min sync propagates to every recipient. ``` ## How to consume a secret ```bash # On any client that's a recipient: homelab secret my-thing # prints plaintext # Or programmatically: sops -d /opt/homelab-context/secrets/my-thing.yaml ``` The `mcp` tool `list_my_secrets(caller_pubkey)` returns the names of secrets the caller can decrypt. The MCP server never reads plaintext — decryption stays client-side. ## Granting / revoking access To grant a new recipient: edit `../.sops.yaml` to add their age pubkey, then re-key every affected file: ```bash sops updatekeys -y secrets/my-thing.yaml ``` To revoke: remove the recipient from `../.sops.yaml` and `sops updatekeys` — but remember this only protects future ciphertext. Past plaintext the client already decrypted is gone from your control. Rotate the underlying credential if compromise is suspected. `homelab client remove ` does the recipient removal + `updatekeys` for you, and prints the rotation checklist as a follow-up. ## hello.yaml — bootstrap decrypt test `secrets/hello.yaml` is encrypted to every enrolled client. Used by Phase 3a verification to confirm the end-to-end decrypt path works on a freshly- bootstrapped machine. Content is intentionally trivial: ```yaml greeting: hello from the homelab ```