Claude Code secret management: moving from .env to a password store

Claude Code is a capable agent, and to call services it needs credentials. The path of least resistance is a .env file: drop the keys in, load them, move on. But that means every key is readable by the agent — and anything the agent invokes inherits the environment. Prompt injection, verbose tool output, a subprocess that echoes its env: any of them can put a key into context and then into a third-party model API.

The fix isn’t “trust Claude not to leak”. It’s moving the keys somewhere the agent can reference but never read.

Why .env is the wrong default for agents

Plaintext-on-disk was already a liability — accidental commits, backup leaks, any process that can read the working directory. Agents add a new dimension: the file’s contents are consumed by software whose entire job is to read, summarize, and transmit. A .env file is not a secret store anymore; it’s a secret delivery mechanism into the context window.

The migration: four mechanical steps

Moving to a password store sounds like a project. It doesn’t have to be. The practical path is:

  1. Set up GPG and pass. One key, one store initialization. If you already use pass, skip ahead.

  2. Import your .env files. Instead of hand-copying every key, scan the project directories, parse the KEY=VALUE lines, and import each entry into the store as a named secret — with the originals backed up before anything is touched. The secrets move into the store; the files get neutralized safely.

  3. Teach the agent to reference by name. The agent config points at the broker: CLAUDE_CODE commands and tools get secrets injected at process time. The agent says “use GITHUB_TOKEN”; the broker resolves it.

  4. Verify with a health check. A doctor command validates the whole chain — GPG key, pass store, gpg-agent, any remaining .env files, and the agent integration — and reports structured JSON so you can confirm the migration actually took.

What the agent can’t do anymore

After the migration, the agent can still use every credential — it just can’t see them. Subprocesses get the values injected into their environment, and stdout/stderr are scrubbed so key values (raw, base64, URL-encoded) never surface in agent-visible output. If the agent runs a command that echoes DATABASE_URL, what comes back is the sanitized form.

This is what trustless does: a zero-dependency credential broker CLI for AI agents that reads your existing pass or Bitwarden store — no migration to a new vault format, no daemon required. The setup wizard and doctor handle the steps above, and the full command reference is in the documentation.

The practical test

After migrating, ask your agent to run something that would normally leak an environment variable — env, a failing connection string, a debug dump. What you want to see is a redacted value, not a key. That’s the moment the threat model changes from “hope the agent behaves” to “the agent can’t misbehave in this direction even if it wants to”.

What’s in your .env files right now, and how many of those values has your agent already seen?