DEV Community 👩‍💻👨‍💻

Cover image for Stop Using .env Files Now!
Gregory Gaines
Gregory Gaines

Posted on • Updated on

Stop Using .env Files Now!

Table Of Contents


Hello Reader 👋🏽

I've worked on huge enterprise systems and I'm disappointed to see 99% of all JavaScript tutorials tell you to use a .env for production config and secrets which is dumb.

It's time to correct this behavior plaguing the community. Let's explore the problem with .env files and the ultimate solution.

The problem with .env files 🚫

1. Storing the .env file

The problem is well... It's a file. You are not supposed to store your "production" file in your repo; where do you put it? Directly in the VM root? What about Docker containers, do you bake your secrets directly in the image? If the image leaks, everyone has access to your secrets.

2. Updating a secret config

What happens if you need to update a database password? Whoever updates the .env will have access to every secret in the file. I don't even have to explain why this is bad. Every time a config has to be updated whoever is updating it can see EVERY secret.


The updater has access to all your secrets


3. Versioning

Let's say you are deploying a new feature that requires updating your config / secret variables, something goes wrong and the application gets rolled back.

Uh-oh does anyone remember the last values we had in the .env? We have no history and the application requires the values we just deleted/overwrote.

Config servers to the rescue 🦸‍♂️

The perfect solution to all these issues is using a config server. A config server is an externalized application for storing configs and secrets. It's considered the central hub for managing secrets across environments.

Multiple cloud services can function as a config server like AWS Parameter Store, Google Secrets Manager, or HashiCorp Vault for my open-source enthusiasts.

Once you create a secret or config, most of the time you are given a URL like https://app.com/config/DB_PASSWORD/v1.

Let's see how a config server solves all the issues with .env files.

Solving: 1. Storing the .env file

With a config server, all the secrets are centralized in one place, encrypted, and can only be accessed by applications and users you approve.


No plain files in sight!


Solving: 2. Updating a secret

With a config server, instead of updating a secret, you create a new version. After creating a new version, you update your secret URL like .../config/DB_PASSWORD/v2 or .../config/DB_PASSWORD/v3.


Adding a new secret version


Solving: 3. Versioning

Like with solution 2, most config servers have automatic versioning. If you need to update a secret, create a new version and update the config URL in the application. If the application gets rolled back, it will automatically use the last config URL you had in place.

This way secrets are protected and your applications can get rolled back with no issues with the previous secrets.


Look at all those secret versions


More Pros of a Config Server ✅

Automatic Secret Rotation

Secrets can become stale which can lead to your systems becoming compromised! A centralized config like AWS provides automatic Secret Rotation.

If you team or org all pull the same config, they will automatically get updated with the latest values. No need to send it over slack, no need to get a "trusted" dev, or having the possibility of forgetting to update one of your .env files. Easy and painless!

VPC Endpoints

A config server is usually hosted on a VPC which provides a localhost like connection for your services. This allows the ability to pull secrets without them ever having to touch the internet (virtually no latency), nor allowing outsiders to query the server.

Audit Logs

Did a secret get leaked? Config servers usually carry audit logs so you can check when or where a secret was accessed.

Does an updated config cause an error? Check when it was last updated and if needed, preform a global update for all your services. No plain text file editing needed.

Final Thoughts 💭

I hope now developers will start using centralized configs for their production services. .env files are unreliable and have no access management, versioning, or safe updates.

I'm not saying .env file don't have a purpose. They can be used for local or development-oriented environments.

What I'm trying to say is don't store valuable secrets in simple files, especially if my data is in your service.

About the Author 👨🏾‍💻

I'm Gregory Gaines, a simple software engineer @Google who's trying to write good articles. If you want more content, follow me on Twitter at @GregoryAGaines.

Now go create something great! If you have any questions, hit me up on Twitter (@GregoryAGaines); we can talk about it.

Thanks for reading!

Top comments (307)

Collapse
 
ravavyr profile image
Ravavyr

I get it...you're like overly cautious.
After years and years of dealing with hundres of sites/apps/applications I can tell you one thing.

NO ONE gets hacked via their .env file. Ever.
First of all, it's really easy to lock it down so no one can access it except for the devs who need access. At some point there's at least one human being [preferably 2 in case one gets hit by a bus] who should know where and how to access and change all your passwords. Therefore having them in one place is just as safe as having them in 20 different places where you will absolutely 100% guaranteed forget some the next time you need to update things or something is on fire.

Overly cautious security leads to a mountain of steps to get to sensitive info that just hurts development and recovery times more than it helps to actually protect anything.

In other words...it's a pain in the buttocks. Don't do it.

Use .env files and learn the few steps it takes to protect them. There is NOTHING wrong with that.

Collapse
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Sounds like more work in my opinion. With a config server, there is no need to trust the "2 devs" since the server has permissions and access restrictions so only permitted devs can add secrets without viewing existing ones.

I don’t think it’s overly cautious, it’s being modern. There is no mountain of steps. Whitelist your application and use the config url like the examples in the article, easy and no pain in the buttocks.

Please re-read the article, I explained how easy recovery (roll backs) and development time is simplified using a config server. I COULD use a .env file and take steps to secure it, or I could live in 2022 and use a config server with permissions, auth, versioning, real-time updates, and an audit trail for extra security.

Personally I don’t want my secrets being stored in a glorified text file.

Thanks for the comment!

Collapse
 
trizz profile image
Tristan

Personally I don’t want my secrets being stored in a glorified text file.

So you store them at an external company? What if they are down, or have a data breach? (They are a bigger target than most of the websites). I'd like control over my secrets and not be dependent on third parties for such important stuff, and storing them in a .env is perfectly fine with the precautions and correct configuration mentioned by @ravavyr

Also, those services are not free. True, you can self-host HashiCorp Vault, but that costs also money.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

True, nothing is full proof. But that's why we choose techniques or companies that gives us the best guarantees.

Also no matter how secure you keep that .env file, you are giving someone FULL view of all secrets whenever its updated.

The services I listed have free tiers. HashiCorp can be self hosted for free forever, Google Cloud has a free tier for 6 secrets, AWS has a generous free tier for storing configs in parameter store.

If you don't want to go with an external company and want full control over your secrets, thats fine. There are free, open-source, or self-hosted alternatives. There's Spring Cloud Config, Github Secrets (if you trust the company enough), or roll your own.

Thread Thread
 
teamradhq profile image
teamradhq

I think the point that @tristan is making rather well is that your recommendation is just increase the surface area of your vulnerable systems.

The mindset that doesn't even trust employees with private information would deem providing that information to a third party (especially a faceless tech company) to be less secure than, keeping it contained within a closed system that is completely under their control.

The arguments you're offering for using a third party to host private information are actually the arguments against using such services. They are the weak points: If a system is compromised, it's almost certainly due to leaky abstractions like this...

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

It's an increase in surface area, but with the benefits I listed above.

Its not distrusting employees, it's being safe and following a secure practice. I don't know about faceless companies, I mentioned Google, AWS (which is the leading in the market for cloud) and other credible companies which provide a config service. I may be a little bias since I am a Google employee.

And if thats the case, why trust anything? Why host private code on Github or deploy on Digital Ocean? Its for the ease and guarantee.

I also mentioned open source config servers that you can host or deploy yourself.

If a system is compromised, most likely its from using bad practices...

Thread Thread
 
badpractice profile image
Bad Practice

DigitalOcean with firewall configurations is the problem solver. Only SSH works on my IP and only Cloudflare can access the HTTP directly. My name literally says "trust me".

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

What happens if your service expands and you have to share common secrets across different teams?

Do you just copy and past the file or use a centralized config?

Thread Thread
 
badpractice profile image
Bad Practice

I could very well say let's use Github/DigitalOcean for secrets and containers, but I work by myself and I have one project that runs about 20 servers (API's, webhooks, crons, etc.) with each having different slightly different .env's. I code in Rust instead of PHP or JS in the backend, so I'm more concerned with supervisor's configuration more than the actual env.

Thread Thread
 
stojakovic99 profile image
Nikola Stojaković

@tristan If you're having serious infrastructure you're already relying on external providers (whether it's AWS, GCP or Azure) so using different service for secrets doesn't make much difference.

Collapse
 
ashleyjsheridan profile image
Ashley Sheridan

But, how do you access your config server? At some point, there are credentials being held somewhere? If someone has access to your server where the code is deployed (which they must do if they can access your .env files) then they can also do what they will with your code to access whatever you have held in a config server.

Interesting, your screenshots are specifically from the Google offering, and you didn't disclose in this blog post that that is where you work.

Collapse
 
brense profile image
Rense Bakker

People absolutely get their secrets stolen through .env files if they commit them to their repository.

Collapse
 
ravavyr profile image
Ravavyr

Exactly, like, learn the BASICS of how to use them and you won't do that.
You should have a default gitignore that omits any "dot" files [chances are you don't want any of those to ever commit to your repo]

So yea, newbies make that mistake. Besides, so what?
You add it to gitignore , change all your passwords, and you're fine again.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

Or you can use a config server and never have to worry about that "newbie" making that mistake with a modern solution.

Thread Thread
 
jamesmortensen profile image
James

@ravavyr, you're fine until another newbie comes into the team and needs to edit .env but makes a backup of it to avoid making a mistake, since it's not in GitHub. Later, when doing a git add . the person forgets that the backup isn't in .gitignore -- he/she may not even know what a .gitignore is -- and accidentally commits the secrets.

This scenario might sound a bit far fetched, but I have seen things like this happen many times. Also, some people will hide the mistake instead of going and changing all the passwords... it's easier to just pretend it didn't happen, that reverting the commit will fix the problem, and that no hackers will ever look at git history. :)

I will say that config servers were initially very intimidating, but once I got used to it, I personally can't imagine going back.

From a security standpoint, it's not perfect though. A tool is still only as good as the people using the tool. We still struggle with how to avoid getting the secrets into the config server. IT has the access, but the devs all have the know-how regarding what the secret is for. Sometimes this means devs create the secret and then share it in the chat system (a bad practice) so that the IT person can then add it in the config server... I guess things can still not make sense even with a config server.

Thread Thread
 
brense profile image
Rense Bakker

I was strictly referring to your somewhat bold statement:

NO ONE gets hacked via their .env file. Ever.
If your secrets become public, you can absolutely get hacked. Which is why the rule exists: do not commit .env files to your repo. What you do on your local machine is your problem. If you want to use .env there or .myEnvIsBetterThanYourEnv it's all the same.

Thread Thread
 
ravavyr profile image
Ravavyr

If your secrets became public then the env is already irrelevant.
No one gets your secrets from your env unless they've already gotten into your server.
Even the most basic servers have [dot] files blocked from access (or should, i'll admit some don't do it by default)
And yes, if your env got into your repo, changes the passwords and keys and make sure you add it to gitignore so it doesn't happen again.

Either way, the .env file has never been the problem.

Thread Thread
 
brense profile image
Rense Bakker

If .env is in your repo, it public knowledge. Even if its a private gitlab, nobody keeps track of what secret is where and secrets in repos should therefor always be considered public knowledge.

Collapse
 
manchicken profile image
Michael D. Stemle, Jr.

There's plenty wrong with using .env files, especially in production. Permissions could be wrong, it could expose passwords to folks who are authorized to support the application but are not authorized to access the database, it could be slurped, version-controlled, etc.

Just because it is easy to maintain security of a single file in a single filesystem doesn't mean that the .env files sitting on your laptops and production servers (if you're using containerization and clusters than it's one copy per machine).

Add on to that the fact that if you use .env files then you have to go manually change the files whenever you rotate or change tokens/keys/passwords, which frequently leads to people not changing those aforementioned credentials.

Use a security service which encrypts, like a Secret Manager (GCP, Azure, and AWS have these), you could use Hashicorp Vault, there are a bunch of choices.

Don't use .env files, the odds that your program will suffer a security event or will perpetuate bad security hygiene is substantially higher than if you use a vault or managed service for your secrets.

Collapse
 
brense profile image
Rense Bakker

Do use .env files to define environment variables in local dev (which is what it is for). Don't commit .env files to your repo. github.com/motdotla/dotenv#should-... .env was never ever meant to define environment variables in production/hosted environments, its for local env ONLY.

Collapse
 
adamedwards profile image
Adam

You make a great point because in AWS permissions can't be wrong. 0600 is really hard to get right, but IAM policy docs are super straightforward.

Thread Thread
 
manchicken profile image
Michael D. Stemle, Jr.

The passive aggression isn’t helpful. It is possible for us to have a respectful conversation while disagreeing.

IAM is an auditable, traceable mechanism which can be monitored and alerted on. I can see who makes an api call to fetch credentials in CloudTrail. I can see if my policy statements are too permissive with things like AWS Config, Trusted Advisor, or Access Analyzer. I can set and forget those roles, and make access to credentials something that adheres to least privilege.

I’d much rather risk a detectible fault IAM policy documents and roles than try to manage .env files across a bunch of infrastructure, and constantly monitor engineers who will accidentally commit and push credentials to source control.

If we were still in the days of monoliths on bare metal servers running in data centers, I wouldn’t be disagreeing as I am. But we’re not, at least not all of us are. The threat is much bigger than you seem to be giving it credit for. Using .env files for production workloads in contemporary containerized cloud deployments is clearly a security anti-pattern.

Thread Thread
 
adamedwards profile image
Adam

Lol I was just messing around. You're right though. There's definitely not a way to audit syscalls about file and attribute operations and send those to a SIEM and alert on them. And even if that existed it's not like it's best practice to monitor those things anyway. So yeah I'm in your camp on this one.

Collapse
 
jarrodhroberson profile image
Jarrod Roberson

also, you can not do automatic rolling password updates across servers easily where there are files embedded in containers or app bundles, etc. Putting secrets where they belong, in a vault means they can be managed outside the lifecycle of the application. Where I work, developers do not even get to know the passwords of the production databases their apps access. They just get a common name across all environments to lookup the database password. It is managed by the database team, that has them automated to be changed on a schedule. How do I know, I work on the system that changes the passwords for them. They do not even know the passwords for some of the most sensitive systems.

Collapse
 
gregorygaines profile image
Gregory Gaines Author

This ^.

Collapse
 
jarrodhroberson profile image
Jarrod Roberson

if you do not understand my comment, you do not have experience with infrastructure with 10s if not hundreds of thousands of servers that need to be updated daily. We do thousands of password resets of thousands of servers everyday. Good luck on "deployments" at that scale, that only change a single password, and if you put all your passwords in the same file, well how do you manage updating a multiple passwords at different times, multiple deployments. Really. You might say, well I do not need that kind of scale, but you do need this kind of security and management, that is unless you have something that is not actually making any money or being used by anyone. Even our internal intranet services that only have 6 users are required to be secure, especially those, because usually those 6 users are very power users, most of the time C level financial users.

Collapse
 
fluffynuts profile image
Davyd McColl

we manage this with our deployments - Octopus already handles this kind of thing at deploy-time; of course, if you're looking to live-update, that's a different story, but if you're reading config every time from some remote service, good luck to ya

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Going to jump in here. Ideally, you only load your configs on startup. A config server generally have very low QPS.

Even if you had to query it rapidly, you should be accessing it from a VPC for little to no latency. So using the description of a "remote service" doesn't really apply in the context of a VPC.

Collapse
 
airtonix profile image
Zenobius Jiricek • Edited on

Lol mate...

You're so dead wrong on every point.

This is why nconf with it's ssm layer exists.

Collapse
 
ravavyr profile image
Ravavyr

care to elaborate or you just know one solution and that must be the best safest way to do things all the time?

Thread Thread
 
airtonix profile image
Zenobius Jiricek • Edited on

use what ever solution you like as long as :

  • it doesn't allow by stander processes to spectate on your secrets
  • it allows you to remotely rotate secrets without having to restart services
  • means you can control access by service identity.

So yeah, that pretty much eliminates your one trick pony.

you don't even need nconf, i could come up with something in several languages that do this:

  • lua, metadata table
  • nodejs, proxies
  • python, metaclasses.
Collapse
 
jarrodhroberson profile image
Jarrod Roberson

actually Ravavyr, in my almost 40 years of doing servers side work I have seen systems brought down from environment based config files multiple times. I get it ... you're like less experienced than us. Home Depot had a fat finger incident that took down 89% of their point of sale terminals ( cash registers ) and was not found out until stores opened on a monday morning and 89% of all the stores across the country could not sell anyone anything. So there is no such thing as "overly cautious", there is experienced and inexperienced, and experienced people know this.

Collapse
 
ravavyr profile image
Ravavyr

Has it happened? yes
Does it happen? yes
Is the problem having environment files with credentials? no

The problem is always people setting those files up wrong, and not securing them adequately.

That's literally where i was going with my original comment and everyone on here decided i was saying "we should all willy nilly throw env files everywhere! woooo!!!!"

I've got 16 years experience, worked on over 400 different customer sites/applications. Trust me, i've seen plenty of hacked systems, broken systems, badly programmed systems and well frankly there is no system that doesn't have holes, they don't exist. Oh and corporations are the worst, no one takes responsibility for anything and no one knows anything further than the tip of their own nose, which is often why different tools and systems conflict or rules in one place cause something in another place to break. I see that last part damn near every day, so when it comes to the credentials being the problem, that's the problem maybe 0.1% of the time. 90% of the time it's some non-tech person edited something they shouldn't have and broke it. the other 9.9% are the myriad of infinitely complex complications that may or may not happen at any given time. :)

Collapse
 
mcheung610 profile image
Michael Cheung

Didn’t Uber just got hack recently because they put their secret in their script?

Collapse
 
ravavyr profile image
Ravavyr

neat story:
portswigger.net/daily-swig/uber-ha...

and yea an admin screwed up, that's the point, people screw up, but that doesn't mean using environment files with secrets in them is the actual problem. Using them improperly is.

Thread Thread
 
ownupalways profile image
Oluwadipe Godwin Jesuropo

Please can you teach me the the proper way to use . env file?

Collapse
 
jmau111 profile image
jmau111⭐

NO ONE gets hacked via their .env file. Ever.

no one you know or no one ever ?

Collapse
 
ravavyr profile image
Ravavyr

if you're gonna say someone did, point them out pls.

Thread Thread
 
jmau111 profile image
jmau111⭐

I won't point them out cause I'm not here to expose anybody, but I've seen it personnally, on multiple occasions.

Good for you if you got some likes but your comment makes no sense to me. Besides, why fuzzing/hacking tools would include .env in their list if it's that irrelevant.

Thread Thread
 
ravavyr profile image
Ravavyr

Look, i can't help you see the reason this entire argument is pointless.
Suffice it to say that all security measures are flawed because they are implemented by human beings and have to be maintained by human beings.
What does hurt projects often [that i've experienced with at least half a dozen clients] is being overly paranoid and trying to secure everything to the point where basic assets are not accessible and sites go down when they shouldn't. At that point it's hurting more than it's helping. And having a .ENV file in 16 years has not once been the problem. So per my experience, it's not an issue. You claim otherwise, and as everything in this industry, we can leave it to personal preference.

Thread Thread
 
jmau111 profile image
jmau111⭐ • Edited on

I see you're really concerned, but you don't demonstrate anything. Why do you consider not using .env is being "overly paranoid"?

If you care about error 500 and other inconveniences, it happens a lot with .env, and many beginners have difficulties using them properly. Most of the time, teams use it because the framework forces them to use it, not as an internal methodology.

I don't know you, but it sounds like "I don't want to change my habits, I've been doing that for 16 years." If you're careful, which I assume you do, you might be ok with that approach, but that does not mean it's the best one.

Config files like that are primary targets that will be automatically scanned, and sadly, people tend to use the same credentials and API keys in all environments, sometimes making the attack even easier.

Thread Thread
 
ravavyr profile image
Ravavyr

lol

  1. 500 errors only happen if you wrote bad code or didn't debug it enough. This is fact. I fully expect 500 errors if i forget to setup the correct configs in the .env file. You're supposed to fix those across your application and account for any combination of them and make sure to log them and keep an eye on those logs for new ones and then fixing them.

  2. note, my habits extend 16 years, which means i've been coding since before env files existed and i still run some older monolith systems while also keeping up with various frameworks, platforms, services, tools and whatever else people keep coming up with. Config files only get scanned automatically if you don't secure the damn things which again shows that maybe you just lack experience in the field. Credential sharing happens yes, and it's just as bad as not securing your env file from external access, but so is clicking on a bad link in an email, or not setting folder permissions correctly, or a mountain of other issues. ENV files are not the problem, nor were they ever.

Thread Thread
 
jmau111 profile image
jmau111⭐ • Edited on

Discuss starts with "lol." If you think this is a battle, then win. Sorry to say that again, but you don't demonstrate anything. I've seen many uses of .env for convenience I did not find convenient or particularly efficient, but if I have to use them, then I use them.

Does not mean it's the best strategy out there. Does not mean you have to migrate all legacy projects right now because someone said you have to. Maybe think about other approaches for your next project.

Collapse
 
dishantpandya profile image
Dishant Pandya

True, and he also forgot to mention the dependency of SDK, .env isn't bad, if steps are taken to secure it, and infact there's no way people are going to directly update the code or version the .env, they are going use it for local development, and rather build validation in code to check for environment variables and add up new vars progressively, Secret Managers are special purpose services, they add up complexity for small systems, but solve the problem of scattered and untracked env for large systems, obviously with overhead of using client sdks. Still if you still wish use some secret store for even local dev, use Doppler.

Collapse
 
brense profile image
Rense Bakker

Then why do the people who made dotenv explicitly tell you to NOT commit .env to version control? github.com/motdotla/dotenv#should-...

Thread Thread
 
stojakovic99 profile image
Nikola Stojaković

People never stop to disappoint me with their clinging to bad practices.

Thread Thread
 
dishantpandya profile image
Dishant Pandya

not commiting it to version control is the right thing to do, but using it as source of truth for your variables is simplest thing to do, if one needs unified way of injecting secrets, from various sources there are tool out there like tlr.dev/ which can source secrets from AWS, Vault, etc. all in one place without even using any SDK. That totally depends on choice of the devs.

Collapse
 
gregorygaines profile image
Gregory Gaines Author

Depending on which service you use, you could slide by without an SDK.

I've never heard of a .env used for build validation, can you give an example.

Collapse
 
dotenv profile image
Dotenv

I think @ravavyr is largely spot on here.

That said, .env files do have their weaknesses. We are addressing those with dotenv-vault - from the same people that pioneered dotenv.

Collapse
 
gregorygaines profile image
Gregory Gaines Author

At the end of the day, your dotenv-vault is functioning like a config server.

At that point it doesn't matter who's spot, this is a win for me in my books and my principles are still in play!!

Good job, can't wait to try it out and see people using my principles whether they know it or not 😈.

Thread Thread
 
dotenv profile image
Dotenv • Edited on

At the end of the day, your dotenv-vault is functioning like a config server.

Yes, you are correct.

I think we are toward the same end here. You recognize the problem we see as well.

But throwing out the .env file will be a mistake. They need to work together. The config server should layer on top of .env files.

Currently, all implementations of config servers require you to learn a new proprietary system, rewrite code, and get locked into it. Plus, there is training on the new system for your dev team.

That's why we think all config servers should be built on top of the defacto .env file standard. This way, you get all the security benefits of .env files PLUS solve the insecure sharing and config issues.

That is what we are doing with dotenv-vault.

This has the added benefit that you could choose to leave dotenv-vault, and everything would still work. Or you could switch to a different provider that syncs your .env files for your team.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Sounds good to me no matter the underlying system as long as the benefits listed in my article gets implemented.

But seriously guys good job, it feels good to have the brains behind the bases of my very argument make amends with me. I’m so happy right now!!

Collapse
 
ravavyr profile image
Ravavyr

every single security measure has its weaknesses, going by the original post here, using .ENV files is a thousand times simpler than what he proposes and maybe slightly less secure, but a thousand times easier to repair in case of an attack than the original post's process. That's all i was getting at and this thing blew up lol

Collapse
 
davido242 profile image
Monday David S.

Honestly... This sounds great compared!!

Collapse
 
brense profile image
Rense Bakker

Read this and join me in knowing that people definitely do get their secrets exposed through .env files...
dev.to/mittal69353530/adding-an-en...

Collapse
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Oh my, oh my. I'm feeling a sense of irony from some of my criticizers.

Collapse
 
webjoyable profile image
webjoyable

Exactly

Collapse
 
martinmuzatko profile image
Martin Muzatko

It is myth busting time.

1. .env files are unreliable

Having the environment settings come via network adds a whole lot of overhead.
A lot of bad things can happen.

  • The centralized server providing the env can go offline - making my app not able to start
  • The centralized server could update, and then rename an env, that my app isn't expecting - crashing my app on the next restart
  • The centralized server could have an expired certificate - which will deny me my apps required environment vars
  • My app could be hosted offline, e.g. industrial applications where I only sometimes want to connect to the internet, but not at the start of my app - making my app not able to start without an internet connection (unless I cache the env, which leads us back to having local .env files alltogether)

You can by all means make a web service reliable. But how is an external web service more reliable than a file I have access to locally?
Sure, you can write bad code that allows attackers toaccess arbitrary files. But you might as well leak your environment variables even when you would retrieve them through a central environment provider. Object property injection is a thing. Essentially allowing you to instruct your server to serialize and send you the env via any API.
There is absolutely nothing from preventing you to write bad code. No matter if env is directly injected to the app or read from an .env file.

2. .env files have no access management

You can. Both locally and remotely.
How do you run your apps? If I run my docker containers, I can have my compose file read from an .env file and provide that to the containers. The app doesn't even need to know an .env file exists. But the only user starting apps would have access to the .env file. You can control very well on any system who is going to be the guy that gets to run apps.
Secondly, you can also manage access who is allowed to read and write the .env file.

3. .env files have no versioning

Check your .env file into git - no, not the public project. Create a separate repository that you can make private and only give access to limited people.

4. .env files have no safe updates

There is a little bit of lack of tooling here maybe, but you can create a contract between your app and what environment it expects.
In TypeScript and NodeJS you can simply overwrite the nodejs process.env interface, providing a clean contract between your app and the environment vars it needs. It would be even better, if you could generate that from a .env file. Problem solved.
When I roll out a new container, I update both my repo containing the new .env file for compose + the app.

Summary

.env files are a battle-tested and widely adopted and supported feature. They make deployments predictable and secure. If you have trust issues, then you can sufficiently lock it down and only inject it via docker containers.
I absolutely don't see a need for involving yet another server.

Collapse
 
gregorygaines profile image
Gregory Gaines Author • Edited on

I'm not sure you read the article completely.

  • Yea, nothing is full proof; anything can go down, doesn't mean its not a viable option. When config variables are updated, they keep the same entry point ex. config/DB_PASSWORD/v1. Only the value is changed, this is how an paper trail is kept.

  • When that .env is updated the updated has full access to all secrets, no matter how secure that file is nothing will change that. My point wasn't that the file couldn't be stored properly.

  • The creaters of dotenv tell you not to commit it in your repo. Look below, tons of comments say the sme thing.

Summary
Please re-read the article, your points are not aligning with what I was saying. Yea its widely adopted, but change takes time.

Collapse
 
wuya666 profile image
wuya666

From what I understand , he's more like talking about a file-based config management solution, with git-based version control, meaning a dedicated private git service to manage the config file versions not exposed to outside access, that is quite different from "commit it in your repo" which means more about committing it in your application code repo.

Also you can easily have a system that automatically merge multiple config files into one .env file, which should not be directly accessible to anyone, so people updating the individual config files won't have access to configs in other files.

Like I said, you can have a file-based solution that achieves more or less the same goals as a database-based solution, which may be easier or harder to implement depending on your specific situation and needs. After all, databases are file-based solutions themselves, they too store data in files (well, some store non-persistent data in memory, but you get the idea :P )

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Sounds interesting but still opening one .env exposes all secrets in it. A config server mitigates that risk while giving feature like audit logs and automatic secret rotation.

You also get the benefit of a ui if you care about that.

Thread Thread
 
wuya666 profile image
wuya666

The point is in such a file-based config management solution no one should be able to directly open the .env file, it should be dynamically generated and managed by the system, more akin to a "flat database file" if you like to think that way. And features like audit logs and automatic secret rotation can be implemented with no more than a couple dozen lines of code, without the need of a config server. Like I said, the main point of your post is actually not about "config servers" (albeit you are advocating their usage), but rather about storing the config data in remote databases vs. local files/environments.

And the existence of a UI can be a pro or con in the case of config administration depending on specific needs. It's also quite trivial to setup a simple database admin UI if you decide to store config data in remote databases anyway.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

Honestly at this point you are just implementing a config server yourself. Every feature I mention you are saying just write it. If that's what you want to do by all means. We can agree to meet in the middle at this point.

Thread Thread
 
wuya666 profile image
wuya666

That means you can just implement a file-based "config server" with .env files, and your "config server" itself would also use .env files for config, and it could have better security, cleaner code, and maybe even easier and faster to implement than trying to deploy and adapt to use one of those enormous "config servers" you mentioned in the post depending on your particular needs.

Which is exactly the point:

1) .env files (or config files in general) based config management solutions are not inherently worse than those based on remote databases. Don't just blindly diss config file based systems in favor of those based on remote databases, they both have their pros and cons, and one may be improved very easily over the other depending on your particular needs.

2) for experienced devops, it's usually quite trivial to implement a bespoke config management system for things like config versioning, sharing and access control, and it could likely be the preferred way over using one of those enormous "config server" with tons of code and myriads of dependencies.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

Yea, just like you can implement a no sql database with json files, we have tools built for various use-cases. How do you know config servers are enormous, have you used or checked one out? How is tons of code a useful measurement in this conversation again?

All these features you are saying that are trivial to mention can also grow into these "enormous" config servers you keep mentioning. OOOR you can use an already established and battle-tested implementation to avoid introducing the very bugs you are talking about.

And not to be rude, but how much experience do you have?

Thread Thread
 
wuya666 profile image
wuya666

I have checked the "config server" you mentioned in the post,, it has hundreds of dependencies and more than 600k lines of code, which is really ENORMOUS considering the fact that only several hundreds of lines of code are needed to realize the features you mentioned most in the post.

log4j was established and battle-tested, struts2 was established and battle-tested, and when there are orders of magnitude of difference in the amount of code involved, then it's a useful measurement. When it comes to managing important sensitive data like passwords in devops, I'd always trust 600 lines of code written by myself with a handful dependencies than 600k lines of code written by other people with 500 dependencies, when they basically serve the same goals for my particular needs.

And nope a simple bespoke config management solution is next to impossible to grow into those enormous config servers, for example if you code a simple server with koa and several self-made middlewares for your particular needs, it will never grow anywhere near the size of Spring or Rails. From what your post suggests, using a "config server" with 600k lines of code and 500 dependencies just to address pain points like version control, config sharing, access control, data encryption and secret rotation kind of stuff, that sounds like you wanting to deploy an entire Spring Cloud infrastructure just to serve a simple website. Or like wanting to use a NoSQL database when a plain JSON file is more than sufficient to store your data.

And like I said, the solutions to those pain points mentioned in your post is really not about config servers vs. dotenv files, but more about centralized remote databases vs. local config files.

I'll just say I have lead teams of devops with 5 to 10 years of experience, using many kinds of configuration management solutions across various projects of various sizes, from simple bespoke solutions based on config files and/or centralized databases, to distributed systems based on things like zookeeper, and tools for k8s, etc. From what I can see, those "config servers" mentioned in your post are simply WAY overkill as replacements for some config files to just address those handful pain points you mentioned in the post.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Again. WHY DO YOU KEEP BRINGING UP LINES OF CODE AS A METRIC OF USEFULNESS??

About half of HashiCorp Vault's code is unit, system, and integration tests.

They thoroughly test the front-end and the back-end. And to take it a step forward they have end-to-end tests and acceptance tests.

Tests written to avoid these "vulnerbilities" that you keep preaching have multiple lines of code create.


Ok then you can write a config server yourself if you are scared of vulernerbilities. While you are at it MySQL has a vulnerbility back in May so you might want to write your own database engine while your at it.

Also, Chrome just recently had a vulnerbility too. Don't forget to build a while web browser as well. Actually, Dev.to has a bug page, yikes you might wanna re-write this website too.


I mentioned in the article that config servers are usually accessed form VPCs so even if one of those "hundreds of dependencies" has a bug, the config server is protected from the internet.


Also I find what your saying kinda funny.

If a project uses tons of dependencies, then the project is bad. Instead, if they write the features by hand which increases the lines of code, that also makes the project bad.

Thread Thread
 
wuya666 profile image
wuya666 • Edited on

You really need to read what others' saying before replying completely irrelevant things. If I just need to store 1k of data, I'll not use MySQL, I'll just use a JSON file. If I just want to download a file, I'll not use Chrome, I'll just use curl or wget. You must have some serious problems with your eyes IF you can't properly read what others write.

I clearly said those handful of pain points you mentioned in your post does NOT require those enormous "config servers" to address. Those are some simple goals achievable with some very simple config management solutions based on config files, or if you want, with centralized databases, which may take even less time and easier to implement than deploying and adapting to one of those "config servers" mentioned in your post. If you want to call such simple config management solutions "config servers" too, fine. I guess you can call both koa and Spring as "web frameworks", but their differences are huge.

Like I said, using one of those enormous "config servers" to address those pain points mentioned in your post is like deploying an entire Spring Cloud infrastructure to just serve a simple website with features that can be done by using just koa and a handful simple self-made middlewares. Yes you can try deploy a complete Spring Cloud stack to just serve a simple website, but it will take more time, use more resources, and exposed to more potential vulnerabilities UNNECESSARILY, so noone would recommend that.

When you can address all your pain points regarding dotenv files with some simple bespoke solution of several hundreds lines of code, deploying and adapting to an enormous "config server" mentioned in your post to achieve the same goals is really not something to recommend.

Next time try really read and understand what others have said first.

===

You seem to really have some serious problems with your eyes, or your English comprehension skills. What I said is that achieving the same goals with less code is good, and if by orders of magnitude less amount of code, then that's really really good. More dependencies usually means more code in total to achieve your goals.

And about the lines of code as a useful measurement, yes they are when the differences are ORDERS OF MAGNITUDE kind of huge. A simple "Hello World" program practically has zero bug (of course it has next to nil functionality too), 600k lines of code may not differ from 500k lines of code much in terms of complexity and potential bugginess, but if THE SAME GOALS can be achieved by 600 lines of code instead of 600k lines of code, that's some big difference.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

I don't think we are going to get anywhere, we are clearly at a disconnect and throwing insults isn't going to solve much. Let's just agree to meet in the middle on this.

Thread Thread
 
wuya666 profile image
wuya666

no insults, just curious, is English your first language? I kinda understand what you are trying to say with "agree to meet in the middle" here, but that sounds really a little odd here, just saying.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Yes english is my first langauge. What i mean by meet in the middle, I'm saying we both respectfully acknowledge the other person side and agree to disagree.

Thread Thread
 
wuya666 profile image
wuya666

Yeah I know what it means, just don't see it usually used like this.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

I don't want to keep pinging you so I'll make this the last message, but I'm curious, how do you normally see the phrase used?

Thread Thread
 
wuya666 profile image
wuya666 • Edited on

usually when there's no compromise it's just agree to disagree.

Collapse
 
martinmuzatko profile image
Martin Muzatko • Edited on

I have read the article. I am very certain I understand what you propose. It does not work for the environments I work with and I know I am not alone. For the regular self hosted app running on a virtual private server, I would argue you also won't have a need for config servers.

I build industrial applications in demilitarized zones - low trust environments. The customer decides when to go online. We can't expect that an internet connection is there all the time unlike in a cloud application. Not when setting up the software, not when starting the software and also not when updating the software.

This is not a hobby project and it really misses a lot of tooling that yet has to be invented. Because neither docker, k8s or any tooling helps you in continuously rolling out your applications and updates to non-cloud environments. You need to have a very narrow Google-esque vision to assume every app is deployed, managed and run by some cloud.
The problem is a whole lot bigger than ".env files are not secure and don't version". There is a huge gap between the tooling and infrastructure a cloud provides, and the mostly self-baked solutions you have to apply for every tier below that. Docker and docker-compose does work for deploying, but there is an entire slew of tooling that we lack to properly update and version applications that don't run in the cloud.

You mostly have 3 ways of running your apps:

In the Cloud you probably have your complete kubernetes cluster and the entire infrastructure needed to run, monitor, update, version control and deploy your app and its dependencies. There you probably don't have a need for .env files. Even static site cloud hosts like netlify allow you to tune the env from a web ui.

On a virtual private server you have to come up with your own infrastructure. You can't expect everyone to run k8s for a business application. Even then, having too many moving parts can kill your software, as I outlined in my previous post. If I can avoid having a separate runtime dependency, I will avoid it.
All other external systems - A git repository, a CI server, a public key infrastructure, a letsencrypt ssl service, a monitoring service are all optional by design. You can still deploy an app if your CI server gets down. You can still build and package the software locally if your git repo is down. You just don't get monitoring data if sentry is down - the app will continue to run. A certificate will be stored locally and make your app at least secure for ~3 months. But your app won't even start, if your config server is not reachable or has other problems. Even for VPS I would use an .env file.

On bare metal - hardware demilitarized zones and low trust environments are very valid use cases for IoT or public service applications - Both industrial and homebrewn (e.g. smart home). You can't expect that the customer connects to the internet only to get some env vars when starting, installing or updating their app. And I also wouldn't recommend a nuclear power plant to connect to the internet - no matter how secure your communication is. Even for modern industries, sensor data is sacred and they want to very tightly control when software is allowed to synchronize its data with some cloud application. Your across-the-board suggestions "stop using .env files" stops to work here completely.


For Development For development and for documentation, .env files are still great. Setting environment variables for development on windows is a nightmare. In Linux you can at least do DB_PORT=3306 DB_HOST=whatever.com npm run start. But it still convoluted for development. Try to convey what environment variables are needed for your app in order to run to your coworkers. An .env file will document and communicate just that - a set of env vars required for your app to run. Configurable in one place.

We are very far away from having best practices or tools for running software on non-cloud environments.
Docker and compose make it easier, by having predictable deployments. But everything between is left as an exercise to the developer/devops guy deploying the application.

Before I start to figure out how to get rid of a well working tool like .env, I'd rather find out how to fill in the gap of all the missing tooling. Nx is a good job in providing better building tools, combining a slew of independent tools to make build less painful. GitLab is collapsing more and more tools into one tool - since we have experienced in the past years that running and combining a separate repository, a separate CI and a separate container registry is painful. I'd bet my money on these guys.

Thread Thread
 
martinmuzatko profile image
Martin Muzatko

Would love to have @jarrodhroberson opinion on this :)

Thread Thread
 
jarrodhroberson profile image
Jarrod Roberson

the article starts with ...

I've worked on huge enterprise systems ...

Why this person commented when their use case is *not * "huge enterprise systems" is the real question.

Their use case is very niche, very specialized and nothing to do with the OP article. Why should I comment on this persons lack of reading comprehension just to give free advice on their very specialized use case, which is even more reason not to use .env files and there are way better solutions. We have a very similar use case in factory application deployments, they have the same network limitation, and security concerns, we still use vault solution for distributing passwords and encryption keys.

Collapse
 
georgewl profile image
George WL

They read it, you're just ignoring anyone who disagrees with your opinion and assuming they're wrong, rather than listening

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

Hard to believe that when most of my responses are well typed and counter-points, and most of who disagrees are the ones who assume I'm wrong, haven't read it, and don't listen.

Recently, I've decided to leave this article in the past for now. Take care!

Thread Thread
 
georgewl profile image
George WL

I'm pretty sure you are the one who doesn't read counter-points of others, and doesn't listen to those who make them

Collapse
 
jarrodhroberson profile image
Jarrod Roberson

for rinky dink environments your naive duct tape and spit might work, for apps at "internet" scale that actually companies actually rely on for business critical applications not even "not so much', your "system" would never work. I do automation for 10s of thousands of servers on a daily basis for our medium apps, our larger apps are multiple time zones that support people all over the world. We update hundreds of thousands of updates to app passwords DAILY.

you can not do automatic rolling password updates across servers easily where there are files embedded in containers or app bundles, etc. Putting secrets where they belong, in a vault means they can be managed outside the lifecycle of the application. Where I work, developers do not even get to know the passwords of the production databases their apps access. They just get a common name across all environments to lookup the database password. It is managed by the database team, that has them automated to be changed on a schedule. How do I know, I work on the system that changes the passwords for them. They do not even know the passwords for some of the most sensitive systems.

Collapse
 
dbroadhurst profile image
David Broadhurst

.env files should only be used locally in a dev environment. Not sure using them in production is a thing anyone does?
Using something like KeyVault for production makes sense but I prefer to use CI/CD secret services that github / gitlab provide. Makes sense to me that secrets belong to the build / deploy process.

Collapse
 
semiautomatix profile image
semiautomatix

A word of caution with this approach - make 100% sure you're not exposing your secrets in your artifacts!

Collapse
 
jarrodhroberson profile image
Jarrod Roberson

doing dev different than prod is a recipe for disaster. Dev should look just like Prod even if it is not the same scale.

Collapse
 
teamradhq profile image
teamradhq

Can you explain why? If you're configuring secrets in your environment at the build step, they would still be accessible in the deployed system, thus no less vulnerable than if they're in a .env file aren't they?

I mean, if I have enough privilege to access a private file on a server, then theoretically, I can inspect the server's environment anyway.

I just feel like I'm missing something here...

Collapse
 
dbroadhurst profile image
David Broadhurst

Using secrets in CI/CD adds an additional level of protection for secret values through additional access controls but it isn't the only security needed. Assume you have a public repo but want to keep the secrets safe from people who have access to the source code, or you are a company with contractors who need to access the source code but should not have access to secrets.

If someone is able to access the server then other security should be considered such as using a VPC for private API's. Security should have lots of layers, protecting secrets by moving them outside the source code is just one layer.

Collapse
 
xgenvn profile image
Anh Tu Nguyen

I think this depends on what kind of secrets. CI/CD secret can be used for CI/CD, eg: secrets to access Docker, K8s cluster, artifact stores ... Application secrets are different layer, so we need extra tool to provide those. All artifacts should be stateless, loading application secrets is likely effect that happens on runtime instead build/deploy time.

Collapse
 
wiseai profile image
Mahmoud Harmouch

I don't think there's any harm in storing secrets in a .env file, as long as the file is kept safe and secure. In fact, I believe it's a good practice to follow the Twelve-Factor App's recommendations.

In their chapter on Config, they state that config should be in environment variables. This is good advice to follow, as it can help keep your application secure.

Moreover, by taking the necessary precautions, the risks of storing secrets in a .env file can be minimized. For instance, be sure to keep your .env file in a secure location and make sure that only authorized personnel have access to it. Additionally, you should encrypt any sensitive data that you store in your .env file.

By following these guidelines, you can ensure that your secrets are safe and secure while still being able to take advantage of the benefits of using a .env file.

Collapse
 
gregorygaines profile image
Gregory Gaines Author • Edited on

This doesn't solve that anyone who updates it will have access to all your secrets in plain text. No matter how secure the .env it doesn't change that.

Also, environment variables are global to that machine, if someone gains access then they can read out your variables. This was one of the main techniques when the Log4J was exploited.

Collapse
 
wiseai profile image
Mahmoud Harmouch

As I mentioned, it's essential to encrypt your secrets rather than storing them as plain text. This way, even if someone can read your env variables, they won't be able to use it because it is a useless scrambled string of characters. Additionally, you can set the file permissions so that only the owner can read it, further protecting your secrets. Take the following Unix command as an example:

chmod 400 .env
Enter fullscreen mode Exit fullscreen mode

This will ensure that only the file owner can read it and that no one else can access it. This is a great way to keep your sensitive information safe and secure and ensure that only those who need to see it can do so.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on

What about sharing a secret to other? With a config server it’s as simple as ‘corp.secrets.com/config/DB_PASS/v2’.

Thread Thread
 
wiseai profile image
Mahmoud Harmouch

In this case, you can create an Inbound firewall rule or add an entry in the ACL to allow only specific users to access this file.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author

Again giving full access to every secret in the file to that user.

Thread Thread
 
wiseai profile image
Mahmoud Harmouch

Now, the problem becomes tied to the party that you are sharing it with rather than the .env file itself. There is a risk in giving away your secrets to a centralized third party(Like Config servers), as it can become the main target for hacky wacky organizations. It is important to consider who you are sharing this information with and whether or not they can be trusted.

Thread Thread
 
gregorygaines profile image
Gregory Gaines Author • Edited on