Killing your .env files: a zero-friction migration path
Every developer knows the .env file is a security liability. It sits on
disk in plaintext, gets committed by accident, and — since AI coding agents
arrived — gets read by software that sends summaries of what it read to a
third-party API.
And yet almost nobody migrates to a password store. Not because they don’t
care, but because the onboarding is a wall: install GPG, generate a key,
initialize pass, move your secrets over by hand, then teach every tool to
use it. That’s an afternoon of fiddling for a problem that hasn’t bitten you
yet.
I wrote a credential broker for AI agents and found that the adoption barrier wasn’t security philosophy — it was friction. So the migration path got designed around that.
Why .env is uniquely bad for agents
Plaintext secrets on disk were already bad. Agents make it worse in two ways:
The agent reads them. Claude Code, OpenCode, Codex — they all load
.envto call services. Whatever they read enters the context window, and anything in the context window can leak: prompt injection, an over-verbose debug log, a tool call that echoes an environment variable.Everything the agent invokes inherits them. Spawn a subprocess and it gets the whole environment, including keys that subprocess has no business seeing. The blast radius is every command your agent ever runs.
The fix isn’t “trust the agent not to leak.” It’s removing the plaintext from the equation structurally.
The migration path: four boring steps
The barrier to entry is real, so the wizard was built to make each step mechanical:
GPG key — generate if missing, with sane defaults. No menu of 400 options.
Pass store — initialize
~/.password-store, which is what the broker reads from. No migration, no new vault format: if you already usepass, this step is a no-op..envimport — this is the step that makes people actually do it. Point it at your project directories; it scans for.envfiles, parsesKEY=VALUE, imports each entry into the store as a named secret, and backs up the originals before touching anything. The secrets move to the store; the files get neutralized safely.Agent configuration — wire the broker into your agent (the tool wrapper / skill setup), so the agent references secrets by name and gets values injected at process time. The agent stops needing
.envat all.
The doctor: make migration verifiable
A migration nobody can verify is a migration nobody trusts. The companion
tool is a health check that validates the whole chain: GPG key validity, pass
store health, gpg-agent status, a security scan of any remaining .env
files, agent integration status, and the local MITM CA certificate
installation.
It outputs human-readable text by default, structured JSON with
--json for cron/SIEM integration, and an auto-fix path for the issues that
are safe to resolve mechanically. “Is my setup healthy?” becomes a command,
not an investigation.
Friction is the enemy of security
The security tooling that gets adopted is the tooling that makes the secure
path the easy path. If migrating from .env to a password store is one
command and a few prompts — with backups and a verifiable result — then
“good security hygiene” stops being a resolution and becomes just what
happens when you set up a machine.
This is part of trustless, a
zero-dependency Go credential broker CLI for AI agents. The setup wizard,
doctor, and .env importer are all built in — one binary, no runtime
dependencies, 321 tests with -race, cosign-signed releases with SBOM.
What’s your .env → password manager migration horror story? Or the one
thing that would actually make you switch?