# [2026-08-23] Every secret-bearing `.env` on ana-docker tightened to 0600 Found while taking uptime ownership of hrafn: its `.env` was mode 0644 with a live bearer token. Not a hrafn lapse — **0644 was the de facto pattern on the host**. Eight stacks carried secret-shaped vars in world-readable `.env` files on a box with four interactive accounts, verified as real exposure by reading one as `nobody`. Swept: **vaultwarden, traefik**, beszel, gitea-runner, miniflux, news-digest, searxng, vor. (hrafn and nevermore were fixed separately the same day.) Six other stacks already used 0600, so this converged on the existing house pattern rather than inventing one. Post-sweep the host has **zero** secret-bearing `.env` readable by `nobody`. Playbook: `playbooks/tighten-env-perms.yaml`, one run per stack, re-runnable. ## The check that matters Every run asserts `docker compose config` still renders **as the deploy user** (`lkraven`), not as root. Checking the mode proves the bits changed; only rendering as the deploy user proves the next deploy can still resolve its variables. ## Two gotchas recorded in the playbook - **vaultwarden looked like it bind-mounted its `.env`** — which would mean the *container's* UID reads it and 0600 could break the password vault. It does not: that `- .env` is under `env_file:`, not `volumes:`. My grep matched the YAML list item without checking its parent key. The playbook now **refuses** any stack that genuinely bind-mounts its `.env`, since that case is read by the container UID. - **elway prompted for a sudo password.** The `ana-docker` ssh alias resolves to `lkraven`, who needs one; **`infra-ops@10.250.50.70` has NOPASSWD**. `corviduo-dev` was repointed to infra-ops at some point and `ana-docker` was not. Run elway against the infra-ops target on this host. Commit `a896c0a`.