Live data from Hacker News

Where .env Went Wrong

secretspec.dev

61–70 of 77 posts

Re: Where .env Went Wrong

#61
It's interesting how different roles come up with different solutions based on their own experience.

Developers came up with .env because they would run apps on their own machine and wanted to pass variables to their application without having to set them in a command-line or environment-variable every single time they ran their app. And it works great for that. If you're one developer, running something locally, sure, just read some lines from a file. And if you're a team of developers, and most of you have the same lines you want to use, but maybe just a few of them you want to change per developer machine, fine, either keep .env out of Git, or keep a .env.local for the non-Git stuff. Again, simple, works fine.

Then you want to run your apps in production, with different lines. And then you want to run it on a test/stage/qa machine too - again, different lines. And maybe you hard-code those into separate files (.env.prod, .env.staging, .env.test) and load them depending on which of the 2 or 3 machines you have running your app. Again, simple, works fine.

Until the problems start.

Secrets in the .env? Now those are in the code, which gets cloned everywhere, and can be stolen. "Encrypted" secrets in .env? Now you have to manage a secret key out of the file, in addition to the encrypted secret in the file. Everyone has access to the secret? Now people can use those secrets, or access different machines, potentially creating problems or exceeding their authority, and there is no way to know who did what because it's one shared secret. Somebody leaves the company? Now you need to rotate the secret (which nobody does).

Ephemeral containers/deployments? Now the .env entries don't match the new hostname. Want to support multiple hosts? One hostname in the .env line doesn't work anymore. Want to scale horizontally? Now your "prod/test/dev" files are more of an environment type than a specific host. Your RDS database's hostname, or an old IP address, has changed? App is broken, time to update all the .env lines referring to it and re-deploy the app.

These are all problems that you might or might not run into. But they are problems that do exist in the world; we know they happen, and we know how to avoid them. You decide whether you're going to wait for them to bite you, or avoid them altogether from the very start. If you do the former, you're acting like a Systems Engineer, designing a system to be resistant to known failures. If you do the latter, you're not.

You may not want to do extra work you feel is unnecessary just to avoid a possible problem. But other professions do this anyway, by regulation, because (for example) as a society we we don't want to allow houses to burn down from a preventable problem. Example: If you run wire in a conduit, the conduit must be a minimum size depending on the number and type of wires you run in that conduit. You may think it's annoying that you have plenty of space left in your conduit; why should I have to change my wire size or conduit size? But if the wires take too much current, and don't have enough airflow/space between them, they can heat up and start a fire, or a short, which could cause a larger problem somewhere else (like taking out a hospital's ventilators, as one example). Doing the extra "unnecessary" work prevents fires. That's why Systems Engineers don't use .env files. Their job is to build reliable systems, not just roll out a feature and cross their fingers.

Re: Where .env Went Wrong

#62
post #56
post #47

Hey cool, a relevant place to mention my project: https://dotprot.dev/ Type "dotprot" to copy your .env file into 1Password using the 1P CLI, it verifies it's there, then deletes the local copy of .env. When you're ready to work again, type "dotprot" again to restore the .env file from 1P. There is a .prot file in the directory that you can declare other files to store in 1P as well. Varlock ( https://varlock.dev ) i…

If 1Password hadn't jumped the subscription model shark, I'd be all over that. Any chance you'd entertain supporting bitwarden?

Varlock has bw plugin too - and similarly you can either wire up individual items or pull a whole env style blob from a single item if you prefer.

Re: Where .env Went Wrong

#63
post #54

I'm working with .env and secrets and teamwide configs for the first time, trying to understand solutions from first principles. Are these valid observations so far? - .env is the simplest and oldest / most boring solution. Secrets are passed to teammates by DM? - .env.example seems like a nice home for documentation about secrets - but I'd rather avoid writing sensitive credentials at all -- instead, teams can use a…

Varlock sounds like what you might be looking for. Free, open source, and very flexible toolkit to use however you like.

Re: Where .env Went Wrong

#64
I suppose I'm spoiled by the Symfony framework which has a robust Secrets Component [0].

It allows you to generate a public/private key for each environment: test, dev, and prod (by default). The 'prod' private key can't be committed to the repository. Once the cryptographic keys are generated, you can encrypt any secret you want, and the framework will automatically decrypt it and allow you to access it as an environment variable at runtime.

The encrypted values for all environments are committed to the repository. For example, the file for the `$STRIPE_SECRET_KEY` environment variable for the 'dev' environment is a file that has these contents (shortened for readability):

    
This solves several problems:

1. Keys for the 'dev' and 'test' environments can easily be shared with the team because their public and private keys values are committed to the repository. No more sharing secrets file over Slack or through some other mechanism.

2. The private key for the 'prod' environment can be stored in a 3rd party vault so it can be made available to the production servers. You can also decrypt 'prod' secrets during deployment to reduce the decryption overhead for each request.

3. At worst, agents would have access to the secrets in the 'test' and 'dev' environments only because they couldn't decrypt 'prod' values locally.

4. It forces good practices to ensure you're not using the same secret value for production and non-production environments.

It's made secret management so easy I don't even give it a second thought. Do other web frameworks support a system like this?

[0] https://symfony.com/doc/current/configuration/secrets.html

Re: Where .env Went Wrong

#65
post #52

Earlier quoted context omitted.

Does it matter whether the app reads `.env` directly though?

Maybe. How does the application unify different environment variables? Those inherited by the shell, those read from .profile, those set in the process that start the application (be that ./run.sh, a nodejs script, systemd etc...).

Why would it want to? I'd say what you're asking for is actually a code smell. An app should not have a bazillion interlocking ways to be configured, unless there's a strong reason for this!

Re: Where .env Went Wrong

#66

This article reads like more of an ad than anything else. > Environment variables only deliver values Yes, the problem .env files try to solve is having "environment variables" be injectable from a file so that different applications can have different environment variables by default. > A string is not a schema Yes, input validation is an application concern. The application should know what these values represent /…

First couple sentences sounded like AI so I just stopped.

Re: Where .env Went Wrong

#67
I'm guessing my brain has been permanently warped by working in a hashistack environment for the last 5+ years. All of these KV pairs are always either in a consul (bog-standard config information) or vault (secrets/credentials) in a consul-template associated with the job - and rendered at run time. And, of course - critically - the consul-template updates those credentials and values as they are routinely rotated.

I did a ^F for "update" and "dynamic" - didn't find any hits in that doc. Managing your dynamic environment values is table-stakes in most large deployments - and I didn't see any reference in `secretspec` as to how they plan to do that.

Re: Where .env Went Wrong

#68
Having a crowded and sloppy environment, is not a good way to go. When you log in to your account, you should not source a bunch of environment files by default. It is always a good practice to have a simple environment, just whatever you needed be sourced. If you need extra, just source them before using them. Keep your home clean.

Re: Where .env Went Wrong

#69
post #52

Earlier quoted context omitted.

Maybe. How does the application unify different environment variables? Those inherited by the shell, those read from .profile, those set in the process that start the application (be that ./run.sh, a nodejs script, systemd etc...).

Why would it want to? I'd say what you're asking for is actually a code smell. An app should not have a bazillion interlocking ways to be configured, unless there's a strong reason for this!

It's not the app, it's the environment variables that have many ways to be configured.

Re: Where .env Went Wrong

#70
Hm, the main headache I have with .env files is simply that I lose them (switching between machines etc...), or the trouble of sharing secrets with team mates, etc... The headache of keeping them up to date and synced across environments & machines.

Not affiliated but those troubles are now finally solved with Infisical for me. It's open source so I happily give them a plug.

Post reply on HN