Why I stopped using .env files for secrets (mostly)
I did not stop because .env is evil. I stopped because I am human — and .env files are too easy to duplicate, too easy to commit under stress, and too easy to open in the wrong screen share.
This is a workflow article: the engineering justification is in why .env leaks and is .env safe?.
1. The near-miss that stuck
The pattern: Friday deploy, someone runs git add ., and .env was newly created in a subdirectory not covered by the root ignore rule. CI did not catch it; GitHub push protection did — once. The other time, it was git log archaeology and rotation at 22:00.
After that, “gitignored” stopped feeling like a guarantee.
2. Backup sprawl is silent
Time Machine does not care about your security policy. Neither does zip -r handoff.zip ./project. A plaintext .env in the tree means every backup of that folder is a secret backup.
3. Wrong terminal, wrong DATABASE_URL
With one mega env file, tab three might still export staging while you think you are on local. The failure mode is subtle data corruption, not a dramatic hack.
Structured workspace grouping fixed the cognitive bug for me — organize across projects.
4. What I do instead (hybrid)
- Canonical secrets live in PassStore on my Mac — per-repo workspaces, Keychain options (Security).
- When a tool requires a file, I generate a gitignored
.envfor the session orexportin one terminal tab I close after work. - Runtime still uses environment variables — I did not abandon 12-factor; I changed storage.
5. When I still use .env files
- Ephemeral local-only sandboxes I can delete.
- CI-generated files that never touch my disk on laptop.
- Docker compose dev flows where compose expects
env_file— file is short-lived and scoped.
6. Soft CTA
If your story rhymes with mine, try PassStore — download and read stop storing secrets in .env files for a more prescriptive take.