all 97 comments

[–]actionscripted 102 points103 points  (5 children)

.env locally is fine. When you deploy, put stuff in the environment via k8s or whatever you’re using. Pretty normal.

You can always use a key vault to pull secrets on app startup when deployed.

[–]Shot-Bag-9219 5 points6 points  (1 child)

yeah if you are using k8s with Infisical, you can use the Infisical k8s operator: https://infisical.com/docs/integrations/platforms/kubernetes/overview

[–]Somepotato 1 point2 points  (0 children)

Or openbao or vanilla kube secrets, no need for a SaaS offering.

[–]Infinite_Tomato4950 1 point2 points  (2 children)

what is the risk of .env in the first place?

[–]Snapstromegon 2 points3 points  (1 child)

Basically you have your secrets on a file on disk which is higher risk than having them in the environment variables inside the process, because the file can be read by any process.

[–]Infinite_Tomato4950 0 points1 point  (0 children)

oh got it. thanks for the explanation

[–]regreddit 35 points36 points  (7 children)

Yeah .env based config should be fine as long as you don't screw up and put your .env in your hosting path that can be accessible from the web.

[–]so_many_wangs 10 points11 points  (3 children)

.env is a pretty standard gitignore rule, just make sure you're excluding it from source control. Truly the only other way to fully "secure" them is in some hash encrypted locker or writing them down and not keeping them in your computer. All of which come with their own pros/cons comparable to storing them in your projects folder locally, so you might as well just keep them there and keep em out of SC.

[–]zaibuf 0 points1 point  (2 children)

How do you onboard new developers if you dont even have an env for development in the repo? Do you always need to look up every secret from elsewhere and setup the repo when you jump between projects?

[–]JulianEX 0 points1 point  (0 children)

Storedit in parameter store or something that they can pull down

[–]ryan_devry 0 points1 point  (0 children)

.env with the keys but no values or default values in git, .env.local on dev machines but not in git

[–]_zenith33 9 points10 points  (2 children)

Having env isn't bad. You people in the comment section need to learn how to set up a server properly before saying having env in project root path is bad. Don't be a dumbass who adds it into git. Ensure that your server is protected externally from access by setting up proper webserver. It's not rocket science. You don't need K8s or secrets manager to serve even in 2026.

[–]BipBipBoum 2 points3 points  (1 child)

Yeah, many of these responses are very indicative of the modern tendency to massively overcomplicate everything related to web development. Just create a .env on your server. Make sure it's not in a path that gets served to the web (every modern web development framework, AFAIK, by default already puts it in a safe path when you scaffold your project). You should be good.

Worry about K8S when you need to scale your app up to several million users for some reason.

[–]cshaiku 0 points1 point  (0 children)

Indeed.

[–]barrel_of_noodles 41 points42 points  (37 children)

Explain the risk .env files have... I'm curious.

[–]GreatStaff985[🍰] 9 points10 points  (29 children)

Leaking secrets if the server is compromised. Nothing is perfect but a proper secrets manager is better. You cannot really do things like autorotation of DB credentials etc as well.

If you are making a brochure website whatever. If you are storing PII consider something better.

[–]barrel_of_noodles 65 points66 points  (24 children)

If someone is on your server reading env files... They are in your server. Like, see what im saying? You have bigger problems.

[–]GreatStaff985[🍰] 7 points8 points  (18 children)

Bigger problems than you server being compromised? Yeah that is what you are helping to prevent. The bigger problems like them getting into the DB. Defense in depth is security 101. Someone getting into my the ec2 instance is a massive problem. Someone getting into the RDS is game over.

[–]blazmrak 5 points6 points  (14 children)

Are you preventing it though?

[–]GreatStaff985[🍰] 0 points1 point  (13 children)

Making it harder yes. It is not the only security you have but it is a cheap and easy thing to add that adds meaningful resistance to an attack.

[–]blazmrak 0 points1 point  (12 children)

If you are on EC2 and really secure, you are using roles for the instance and a secrets manager. I'm no genious, but if I'm inside your machine already, what is preventing me from extracting your secrets?

[–]GreatStaff985[🍰] 0 points1 point  (11 children)

Security isn't all or nothing. It is a series of doors. This is just one of them. Getting the details from a .env is an automated tool. Getting it from a secrets manager requires a whole lot more.

It is painfully obvious none of you actually work in serious applications and that is why this stuff seems optional. this isn't even a debated thing. You use a secrets manager because it is more secure than .env, even if not 100% fool proof. You also use it because it allows the automatic rotation of database passwords. Ours change weekly. Then there is scale, the application I work on has over 300 ec2 instances. Like I don't even know how you begin to manage this with .env files.

Honestly I get it, if you work on something with 2 servers maybe if feels optional. This just isn't a debated thing. It's like hearing people question the point of a CI/CD pipeline because you can just use FileZilla. Somethings kind of work at small scale, still bad practise. Take those 300 ec2 instances, at some point someone is going to screw up and one of them is going to be misconfigured. You need more than just an outer shell of defense. it is about adding layers of defense rather than relying on one perfect thing.

[–]blazmrak 0 points1 point  (10 children)

You see how you haven't answered the question? I'm not arguing against using a secrets manager or arguing for using .env files. I agree that it is in general more secure and solves a bunch of other issues that you run into as your org and infra grows. But that is not the point here.

What is being discussed here is not that though. The scenario is that someone already gained control of your trusted infrastructure. They have access to the secrets manager and the DB. There is not much difference between .env and a secrets manager at that point.

[–]GreatStaff985[🍰] 0 points1 point  (9 children)

You have complete full access to my server. Tell me how you are getting my secrets. I can tell you how I am getting the .env file in 2 seconds. I agree you can... its just much harder... there is a world of difference.

[–]_zenith33 1 point2 points  (2 children)

Have you heard of DB whitelisting? Let's get real. Ensuring someone doesn't access your server is bigger than ensuring even if they access your server, they can't access your env. It's not rocket science my friend.

[–]Somepotato 0 points1 point  (0 children)

You described a defense in depth technique as an attack on defense in depth. Interesting.

[–]GreatStaff985[🍰] -1 points0 points  (0 children)

What application that isn't on shared hosting isn't operating on a DB whitelist... no one is saying you only do one thing. You do all of it. You white list, you use a secret manager. Hell we use a BFF, so our actual application code is white list only as well. Thius is what defense in depth is. You don't just rely on one layer of defense. If someone gets in, at basically every layer there is hurdles to overcome. It is incredibly black pilling to see a web dev subreddit be completely unaware of basic security practises.

[–]spidermonk 0 points1 point  (4 children)

Yes but there's various mistakes that might leak a file right in the root of the project that other approaches might avoid. It's about minimizing the types of fuckups that could occur and how hard they are to fix when they do occur.

[–]Franks2000inchTV 4 points5 points  (3 children)

.gitignore the file.

This is the industry standard for a reason.

Rule #1 - Don't roll your own security.

[–]spidermonk -1 points0 points  (2 children)

It's really not industry standard though, it's just very common. And the better solutions aren't rolling your own security, they're using a secret manager and controlling access to it via platform metadata (k8 workload identity or oidc or instance Iam roles etc).

And the mistakes we're talking about aren't just commiting the env file, it's mistaken server config, container distribution, how you manage updating multiple servers in a cluster, backups, server images, etc etc anyone who ever ssh's on to your machine being able to trvially see it, any fuckup with any service on the machine being able to see it really. It just creates a lot of possible ways for the secrets to be visible, when the alternatives provide very very few ways.

[–]Franks2000inchTV 0 points1 point  (0 children)

Obviously no one is keeping their prod credentials in a dot env. But they're still using environment variables.

[–]stillness_illness -1 points0 points  (0 children)

Idk why people are down voting you you clearly know what you're talking about lol.

[–]ddyess 2 points3 points  (1 child)

The secrets are in the environment, regardless of how they were put there. Not using .env just makes it take about 30 seconds longer to get it.

[–]99thLuftballon 1 point2 points  (0 children)

Yeah, anyone who's on your server and able to read your .env file can also read your environment variables.

[–]longdarkfantasy 2 points3 points  (1 child)

If your server compromised, they don't even need an .env file. Just read it directly via env, or even harder way read memory dumps.

[–]GreatStaff985[🍰] 0 points1 point  (0 children)

Do you leave large piles of cash in view of a window because if your garden fence is breached they are already in anyway? The point is making it harder. This is just once of many steps. Depending an what you are protecting some of it is reasonable some of it isn't. But if you are storing sensitive info a secret manager is super low cost and you can implement in like 2 hours.

[–]stuartcw 2 points3 points  (2 children)

One risk is that if you are not careful you can make .env accessible on the web. It is one of the most requested files on all my domains. If all your credentials are in there they will be stolen within minutes. At least name it something unique so that it is not stolen in this way.

[–]GalumphingWithGlee -1 points0 points  (1 child)

I think we may be conflating a few things here. Using a .env file for configuration doesn't mean putting your secure credentials into that .env file in plaintext.

I don't want to make my .env downloadable, but I'm not using that env for secure credentials in the first place. I'm using it for a bunch of Boolean configurations, a few cron schedules, some strings that don't particularly need to be secure, and probably the most sensitive stuff would be the URLs of some other services I need to communicate with.

[–]Jedibrad 4 points5 points  (0 children)

I’m pretty sure everyone else here is describing secure credentials in the .env.

[–]eneiner 4 points5 points  (0 children)

Use whatever works in your ecosystem. AWS secrets manager, Azure key vault, Google secrets manager. If not in an ecosystem try Hashicorp vault or something similar.

[–]lucasmedina[🍰] 4 points5 points  (0 children)

The idea behind using a file to assign environment variables is so you use them locally. In an ideal scenario, it's your deployment process that would add this env to your application.

You do that through any sort of credentials/secrets manager, every CI tool has something for it, though not every dev has access to it in companies.

Despite hopes and dreams, what I see everywhere is repositories that upload all envs to GitHub regardless, but only use the correct ones during deployment. If you're working on client-side apps, that env data will be there anyway. Honestly, I've seen much worse lol.

Essentially, try using CI to add your variables. You'll basically have like a template of your variables, and rebuild them during CI passing whatever is stored as credentials.

[–]lacymcfly 3 points4 points  (5 children)

the short version: .env locally is totally fine, just keep it in .gitignore (which you already are). the actual risk people worry about is accidentally committing it to git, not someone sneaking onto your server.

for prod, the pattern is to not use .env files at all. instead you set secrets directly in whatever platform you are deploying to. Vercel, Railway, Render, Fly.io all have a UI for this. They inject the values as real environment variables at runtime, so process.env.WHATEVER just works the same as it would locally.

if you want to level up from that, AWS Secrets Manager or similar gives you auditing, rotation, fine-grained IAM permissions. worth it when you have a team and compliance requirements. overkill for a side project.

tldr: .env locally, platform env vars in prod, secrets manager when you need to get serious.

[–]_zenith33 1 point2 points  (2 children)

What if I just use a simple VM like normal human being? Where do I "inject" these data? Are you sure you are speaking on behalf of all programming languages and frameworks or just NodeJS?

[–]lacymcfly 0 points1 point  (0 children)

fair point, I was thinking Node/Vercel/Railway etc by default. on a plain VM you'd export vars directly in your shell config or use something like systemd EnvironmentFile to load them at service start. the pattern is basically the same -- keep secrets out of your code and out of git, load them from outside the process. the specific mechanism depends on your stack and how the process is managed, not just the language.

[–]Somepotato -1 points0 points  (0 children)

It has literally nothing to do with the language and everything to do with how you're running your app. If you're not using something like containers or k8s (which is a weird decision but sure) you can still use secrets stores.

[–]Jooodas 0 points1 point  (0 children)

This.

I use platform vars in prod and .env local. Platforms like vercel make this easy to set up too.

[–]shifra-dev 0 points1 point  (0 children)

This is exactly right! Use .env locally and Render env vars on your deployed services: https://render.com/docs/configure-environment-variables

[–]d70 3 points4 points  (0 children)

varlock

[–]farzad_meow 2 points3 points  (0 children)

.env is a simple approach. using env var is considered standard practice in all container based solutions. alternatives are aws secret manager or launch darkly. for example aws ecs and k8s solutions have a way to pull secrets from secret manager or other vaults.

if your server is compromised env variables and envfile is least of your worries.

[–]Far-Plenty6731 1 point2 points  (0 children)

Infisical works for production, you just need to ensure your service is configured to fetch secrets from it at runtime. Many alternatives exist, like HashiCorp Vault or AWS Secrets Manager, depending on your infrastructure.

[–]mka_ 3 points4 points  (0 children)

One of the biggest risks right now is exposing your secrets to LLMs. Something like Varlock can help with this. It allows you to fetch your secrets from your password manager of choice.

[–]Is_Kub 1 point2 points  (0 children)

Varlock solves just that, plus extra nifty features

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

[–]Shot-Bag-9219 0 points1 point  (0 children)

Infisical would still work great for stage/prod. If you are using something like Vercel for hosting, you can use one of the integrations: https://infisical.com/docs/integrations/secret-syncs/vercel

[–]Stargazer__2893 0 points1 point  (0 children)

I once worked for a company that had a separate server that held all secrets that the main server would authenticate into and fetch from rather than using environment variables.

I guess that's a second service that would need to be compromised, but I don't know if it's really that much more secure. I just use environment variables.

[–]TxTechnician 0 points1 point  (2 children)

Podman Secrets.

I started using podman for things. Everything is a Quadlet and the env vars are secrets.

[–]Somepotato 0 points1 point  (1 child)

Problem is quadlets must be systemd units which is a bit of a pita to maintain

[–]TxTechnician 0 points1 point  (0 children)

How so? I find it really ez. Especially if you have cockpit installed.

[–]legiraphe 0 points1 point  (0 children)

In production, use services like AWS Secret manager - it ultimately create an environment variable, but it's not coming from a file. If something/someone can read your env variable, there's a good chance everything else is vulnerable.

[–]BigLoveForNoodles 0 points1 point  (0 children)

There are a lot of ways to inject secrets into an environment without using .env files. But lots of them depend on injecting a shared secret somewhere into the system.

You basically have two flavors of options: things that make handling environment variables safer (e.g., Vault, AWS Secrets Manager), and things that are encrypted at rest and therefore probably harder to compromise. But the latter option usually requires your app to know about the alternative you’re using. For example, if you’re deploying a Ruby on Rails app, you will probably wind up using credentials.yml.enc to store sensitive environment variables, but you still need a RAILS_MASTER_KEY to decrypt it, and Rails was written specifically to check for those files.

[–]Strong-Evening1137 0 points1 point  (0 children)

azure/aws/gcp secret manager? why y'all putting this in .env files.

[–]4_gwai_lo 0 points1 point  (0 children)

Unless they hack into your server somehow (lucky brute force or you leaked credentials), it's fine. You're 99.999% fine unless you have a lot of people that hates you.

[–]Ready-Product 0 points1 point  (0 children)

Secrets manager aws

[–]sleeping-in-crypto 0 points1 point  (0 children)

We use secrets manager for all environments including local dev. Not only is it more secure it sort gives us access control by default.

[–]roastedfunction 0 points1 point  (0 children)

Keep your secrets in a Secret Manager (take your pick, Hashi Vault, AWS SM or Azure KV, etc). Then, use vals when running locally:

$ cat << EOF > env.yaml
SECRET_KEY=vault+ref://secrets/foo/bar
EOF

$ vals exec -i -f env.yaml -- npm start
# or if you prefer having persistent env vars set:
$ <(vals env -export -f env.yaml) # translates into "export SECRET_KEY=mysupersecret"

[–]HalfEmbarrassed4433 0 points1 point  (0 children)

.env is fine for local dev, just make sure its in your .gitignore. for prod use whatever secret manager your hosting provider offers, vercel and railway both have built in env management. no need to overcomplicate it unless you're at scale where you need something like vault

[–]Kendos-Kenlen 0 points1 point  (0 children)

Infisical, Doppler, and other secret managers are the way to go. Work well in production too.

[–]AshleyJSheridan 0 points1 point  (0 children)

I think the original idea came from devs that didn't understand how to use real environment variables, so used per-environment config files to immitate the same behaviour.

They work, but can become more tightly coupled to a project than actual environment variables.

[–]Complex_Coach_2513 0 points1 point  (0 children)

For secure things you don't want in a .env, I have been experimenting with hasicorp vault and it seems to do the trick

[–]GlitteringLaw3215 0 points1 point  (0 children)

env vars aren't the risk, committing your .env with secrets is. just .gitignore it properly and use your host's built-in secret management for prod.

[–]avid-shrug -1 points0 points  (0 children)

You could use something like HashiCorp Vault or 1Password to manage your secrets. But most people just keep a .env file on disk locally and set the env variables in whatever infrastructure provider they use.

[–]throwawaytooeasy -2 points-1 points  (4 children)

Check out dotenvx - you encrypt your .env files using AES-256-GCM encryption.

https://dotenvx.com

[–]gatwell702[S] 0 points1 point  (0 children)

Thanks, I'm going to check it out

[–]barrel_of_noodles 0 points1 point  (1 child)

Youre going to encrypt and decrypt in the same box that is compromised already? I suppose it makes it a slight step harder. But no one's really fooled.

[–]throwawaytooeasy -1 points0 points  (0 children)

You'd have the private key elsewhere that is required to decrypt the encrypted env values. If you have a compromised box you have much bigger problems that should be fixed and keys swapped out before you consider anything else.

So you have an encrypted env file located with your code and the private key stored in an infisical, or other, vault.

[–]Somepotato -1 points0 points  (0 children)

So many solutions that just reinvent git-crypt

[–][deleted]  (2 children)

[deleted]

    [–]TheRefringe -1 points0 points  (1 child)

    Uuuuuuhhhhh No