.env files vs secret managers: when to stop using env files

The .env file is the most widely deployed secret store in software, and the one nobody audits. For years it works: you clone a repo, copy .env.example, fill in the keys, and the app runs. Then the team grows, the pipeline gets automated, and the same file that was convenient becomes the thing that leaks. The useful question is not whether .env files are bad — it is when they stop being good enough, and what to move to instead.

What .env files actually give you

A .env file is a plain-text KEY=VALUE list that a loader pushes into the process environment at startup. Its strengths are real: zero setup, human-readable, easy to gitignore, and it works in every language and every deployment style. For a solo project or a prototype, nothing beats it.

The failure modes are equally real. Copies sprawl: the same file ends up on three laptops, in a sync folder, in a docker-compose.yml, in a CI configuration. Environments drift — staging gets a newer key than production, and nobody can say when. There is no access control, no audit trail, and rotation means editing files on every machine that holds a copy. Secrets leak into shell history, editor swap files, and backups long before they leak anywhere interesting.

Signs you have outgrown the file

A few concrete signals that it is time to stop:

  • More than one person needs the secrets.
  • The same keys exist in more than one environment or machine.
  • You cannot remember the last time a key was rotated, or who has copies.
  • Onboarding involves someone sending a .env file over chat or email.
  • Secrets have appeared in logs, error reports, or pastebins.

Any one of these is manageable. Two or more usually means the file has become the risk it was supposed to avoid.

What a secret manager changes

A secret manager — a password store such as pass or Bitwarden, or a dedicated vault product — gives you one source of truth. Access is controlled per identity, reads can be audited, and rotation is a single operation instead of a file edit in N places. The trade-off is the retrieval step: code and scripts must now fetch secrets at runtime, and that step is where implementations go wrong, by printing secrets to stdout, passing them through command-line arguments, or caching them in files as unprotected as the .env was.

The pragmatic threshold most teams settle on: if a .env contains anything that would hurt when published, and more than a handful of people or machines need it, move it. Keep a local .env as a development bootstrap if you like, but stop treating it as the source of truth.

Making the switch without a migration

The transition does not have to mean building a new vault or converting formats. Stores like pass keep your existing structure, and tooling that reads an existing pass or Bitwarden store lets you keep working without inventing a new secret format. The point of the exercise is centralization, not a migration project.

If your workflows are increasingly automated — CI jobs, cron tasks, AI coding agents — the retrieval problem compounds, because those processes run unattended and their output gets logged. trustless is a credential broker CLI for AI agents that reads an existing pass or Bitwarden store, injects secrets into a subprocess environment, and scrubs them from captured output; the injection design is covered in the documentation.

How many copies of your most sensitive .env file exist on machines and in sync folders right now — and can you name them all?