diff --git a/docs/secret-distribution.md b/docs/secret-distribution.md index b5f9e05..948d46b 100644 --- a/docs/secret-distribution.md +++ b/docs/secret-distribution.md @@ -45,7 +45,15 @@ That redeploy-and-restart sequence isn't just a claim — here's a real one, sta ![A real Vault Agent restart: authenticates, renders triliumnext-mcp's .env.secrets, then its reload_command runs docker compose up -d, recreating and starting the container](../assets/vault-agent-reload.png) -**Shared-secret variant:** not every template is host-scoped — one credential needed by every docker host for its own registry pushes (see [`docs/registry-and-build.md`](registry-and-build.md)) is templated from a single shared path rather than a per-host one. Same mechanics, just a shared source instead of a private one — and it relies on every host's policy already granting read access to that shared path, the same "shared + private" pattern described in [`docs/secrets-and-pki.md`](secrets-and-pki.md)'s access model. +**Shared-secret variant:** not every template is host-scoped — one credential needed by every docker host for its own registry pushes (see [`docs/registry-and-build.md`](registry-and-build.md)) is templated from a single shared path rather than a per-host one. Same mechanics, just a shared source instead of a private one — and it relies on every host's policy already granting read access to that shared path, the same "shared + private" pattern described in [`docs/secrets-and-pki.md`](secrets-and-pki.md)'s access model. This is the real template list entry, repeated per host: + +``` +$ grep -A4 "service: automation" vault_agent/defaults/main.yml +- service: automation + src_path: .../automation-vm/registry-token/registry-token.ctmpl + dest_path: /opt/docker/docker_volumes/registry-token/registry-token + reload_command: "chmod 600 .../registry-token/registry-token" +``` ## 4️⃣ Administrative Secret Flow — a deliberately separate, simpler system @@ -59,7 +67,14 @@ That redeploy-and-restart sequence isn't just a claim — here's a real one, sta > **Why two systems, not one — the actual reasoning, not just the rule**: Vault KV is built for runtime/service/pipeline secrets a running container needs continuously and automatically. `ansible-vault` is built for secrets used by tooling that *operates on* the fleet rather than secrets *consumed by* the fleet's own running services — a Gitea admin token used only during a playbook run, for instance, doesn't need automatic rotation, per-host scoping, or a rendered file sitting on disk permanently. Building that into Vault's model would have meant either weakening Vault's per-host isolation for a use case that doesn't need it, or adding a whole parallel "admin secrets" concept inside Vault itself. Using the tool already built for exactly this case (`ansible-vault`, already part of the Ansible toolchain from [`docs/iac-pipeline.md`](iac-pipeline.md)) was less work and a better fit than extending Vault to do a second, different job. > [!NOTE] -> **One exception to this split, flagged rather than smoothed over**: Technitium's API token moved out of `ansible-vault` into live Vault KV (fetched via a `community.hashi_vault.vault_kv2_get` lookup at playbook-run time) even though it's consumed by an ansible-playbook, not a running service — exactly the case the law above says belongs in `ansible-vault` instead. The admin/runtime split is the general rule here, not an absolute one, and this is the one place it doesn't cleanly apply. +> **One exception to this split, flagged rather than smoothed over**: Technitium's API token moved out of `ansible-vault` into live Vault KV (fetched via a `community.hashi_vault.vault_kv2_get` lookup at playbook-run time) even though it's consumed by an ansible-playbook, not a running service — exactly the case the law above says belongs in `ansible-vault` instead. The admin/runtime split is the general rule here, not an absolute one, and this is the one place it doesn't cleanly apply. This is the actual lookup, not a description of it: +> +> ``` +> $ grep -A2 "technitium_api_token:" app_update/defaults/main.yml +> technitium_api_token: >- +> {{ lookup('community.hashi_vault.vault_kv2_get', 'technitium/secrets', +> engine_mount_point='kv', url=vault_addr, token=technitium_control_vault_token).secret.api_token }} +> ``` --- Related: [`docs/secrets-and-pki.md`](secrets-and-pki.md), [`docs/iac-pipeline.md`](iac-pipeline.md), [`docs/registry-and-build.md`](registry-and-build.md)