> They sit on disk as plaintext, readable by any process running as your user
The proposed solution:
> Instead of loading secrets from a file, you use a wrapper script that fetches secrets from a secure store and injects them as environment variables into your process
Now they sit "on disk" as plaintext, in /proc/self/environ, still readable by any process running as your user.
That’s why I prefer programs that read all configuration from a file: this file can be dumped with fresh secrete value, read by the program and deleted right away once consumed.
Thanks for mentioning this, a coworker also pointed me to that feature after reading my post. I've since updated the top of the post with two things that stood out to me in the feedback here and on lobste.rs
This matches exactly what we've been building with KeyEnv (keyenv.dev). The core idea: secrets should never live in files on disk at all.
The CLI does `keyenv pull` to fetch encrypted secrets from the server, then `keyenv run` injects them as environment variables into your process. No .env file written, no plaintext ever touches disk, and your app reads process.env exactly like before.
The advantage over 1Password's approach (mentioned in another comment) is that KeyEnv is purpose-built for dev teams: secrets are scoped per project and environment (dev/staging/prod), team members get granular access, and there's a full audit trail. 1Password is great for personal secrets but gets awkward when you need per-project scoping across a team.
For the shell history concern someone raised: `keyenv run` never exposes the actual secret values to the shell — they go straight into the child process environment.
While the 1Password model is not perfect, you can organize your vaults however makes sense for your project. You can do prod/staging/dev, or by projects, etc. Or you can use the new environments feature and create a separate "environment" for each. Service accounts and users can be granted access to specific vaults only.
The huge benefit is that if you are already using it for other stuff, there is no additional "secret zero" to set up - plus you get biometric unlock for your secrets.
Easiest way to use it for dev purposes is varlock (although I'm biased since I created it).
Good points — the "no secret zero" advantage of 1Password is real, especially if the team already uses it. Biometric unlock is a nice UX win too.
Where we saw friction was in CI/CD and multi-service setups. 1Password's op CLI adds ~2-3s per secret fetch, which compounds in pipelines with dozens of env vars. KeyEnv batches the pull so it's one round-trip regardless of how many secrets you need.
The other gap we kept hitting: onboarding a new team member. With 1Password you need to set up vault access, service accounts, and teach them the op run workflow. With KeyEnv it's `keyenv pull` and you're done — access is scoped per project and environment, so you grant access once and they get exactly the secrets they need.
Varlock's approach of bridging 1Password into dotenv workflows is clever though. For teams already deep in the 1Password ecosystem, that's probably the lowest-friction path.
Reading from 1Password definitely does add some overhead, but at least our integration fetches in bulk so should be ~2s total and not scale with number of secrets. For team members, they don't need any service accounts, so its just making sure they are granted vault access, which can be managed through team settings you likely already have set up anyway. Add new team member to "devs" and you're done. Anyway certainly not perfect, but sure beats a lot of the other options.
Should be easy enough to set up a keyenv plugin - varlock adds a lot of additional last mile tooling to get secrets/config integrated into projects, regardless of where they ultimately live.
Nice. One more benefit of this is when using LLM tools like Claude Code or Codex to do something and run tests on a worktree, this solution would work seamlessly.
It’s a whole toolkit for this - with built in validation, type safety, and extra protection for sensitive secrets.