Settings

Theme

Stop Putting Secrets in .env Files

jonmagic.com

34 points by veverkap 2 months ago · 20 comments

Reader

theozero 2 months ago

You will probably really like https://varlock.dev

It’s a whole toolkit for this - with built in validation, type safety, and extra protection for sensitive secrets.

sudahtigabulan 2 months ago

> 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.

  • jiehong 2 months ago

    Exactly.

    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.

    Environment variables tend to be messy IMO

prognostikos 2 months ago

It may be marked as Beta, but I've been using https://developer.1password.com/docs/environments/ since October-ish with no issues.

  • hollow-moe 2 months ago

    I'm pretty sure this uses FIFO under the hood, that's a smart idea !

  • jonmagic 2 months ago

    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

ivannovazzi 2 months ago

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.

  • theozero 2 months ago

    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).

    https://github.com/dmno-dev/varlock

    • ivannovazzi 2 months ago

      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.

      • theozero 2 months ago

        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.

mahaekoh 2 months ago

Mfw typing the command stores the password in plaintext in my shell history

  • embedding-shape 2 months ago

    Prefix your entire command with a space, usually prevents saving it to the history file.

    Usually I do ^ while setting it as a variable, then I can still save the regular command to the history without the secret.

theden 2 months ago

So the solution is to use a proprietary password manager instead? No thanks

hebetude 2 months ago

People still code on their local boxes? op is not biometric secured over an ssh tunnel

zaik 2 months ago

Another solution integrated with most Linux systems: https://systemd.io/CREDENTIALS/

bibstha 2 months ago

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.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection