Eight stacks on ana-docker kept secret-bearing compose .env files at mode
0644 -- readable by every local account on a box with four interactive
users. Verified as a real exposure, not a theoretical one, by reading one
as `nobody`. Six other stacks already used 0600, so this converges on the
existing house pattern rather than inventing one.
Swept (all verified mode 600, unreadable by nobody, compose config still
rendering as the deploy user, container untouched):
vaultwarden traefik beszel gitea-runner
miniflux news-digest searxng vor
Post-sweep the host has zero secret-bearing .env readable by nobody.
Checked before writing the playbook, and re-checked by the playbook itself
so a bad case cannot be swept in by accident:
- every target is owned by lkraven, the deploy user, so 0600 preserves the
deploy path (asserted by rendering compose config AS lkraven, not root --
checking the mode proves the bits changed, only rendering as the deploy
user proves the next deploy still resolves its variables)
- none is bind-mounted into a container. vaultwarden looked like it was;
that `- .env` is under `env_file:`, not `volumes:`. A genuinely
bind-mounted .env is read by the container UID and 0600 could break it,
so the playbook refuses that case.
Two gotchas recorded in the file:
- elway's variable regex eats any bare identifier in braces, so a docker
--format Go template containing {{end}} or {{println}} fails as an
undefined variable. Grep the raw inspect JSON instead.
- the `ana-docker` ssh alias resolves to lkraven, who needs a sudo
password; run elway against infra-ops@10.250.50.70 for NOPASSWD.