- Published on
A gentle introduction to .env files
- Tony Dang
It wasn’t long ago when Uber had to pay a $148-million settlement for a data breach which exposed the data of some 57-million drivers. The culprit? — a hardcoded secret published out in the open for any bad actor to exploit.
Today, millions of software developers keep their secrets (i.e. credentials like access keys and tokens to services used by programs) safe with .env files. For those unfamiliar with the matter, .env files were introduced in 2012 as part of a solution to the hardcoded secret problem mentioned in the introductory paragraph above.
Instead of pushing secrets together with their codebase to the cloud, developers could now push their codebase to the cloud and keep their secrets separate back on their machines in key-value format in .env files; this separation reduced the risk of bad actors getting their hands on the sensitive credentials in the cloud. To run programs, developers would now just have to pull their latest codebase from the cloud and inject the secrets contained in their local .env files into the pulled code.
Unless a development team is small and “scrappy,” not caring much about devops, then it typically maintains multiple “environments” for their codebase to ensure that changes are well-tested before being sent to production to interact with end-users. In the case of multiple environments, developers may choose to employ multiple .env files to store credentials, one for each such environment (e.g. one .env file to contain development database keys and another to contain production database keys).
To summarize, .env files contain credentials in key-value format for services used by the program they’re building. They’re meant to be stored locally and not be uploaded to code repositories online for everyone to read. Each developer in a team typically carries one or more .env files for each environment.
In this section, we’ll walk through how to use a .env file in a basic project assuming that you’re using Node.js and git for version control; this should apply across other languages too. Feel free to skip this section if you’re not interested in the technical aspects of how to use a .env file.
To begin, head to the root of your project folder and create an empty .env file containing credentials you’d like injected into your codebase. It may look something like this:
Next, you’ll want to ignore the .env file from being committed to git. If you haven’t already, create a .gitignore file. It should look like this:
Now to inject the secrets into your project, you can use a popular module like dotenv; it will parse the .env file and make your secrets accessible within your codebase under the process object. Go ahead and install the module:
npm install dotenv --save
Import the module at the top of the start script for your codebase:
That’s it — now you can access the secrets anywhere in your codebase:
process.env.SECRET_1 // injects the value of SECRET_1 into your code
Great. You’ve successfully added a .env file into your project with some secrets and accessed those secrets in your codebase. Additionally, when you push your code via git, your secrets will stay on your machine. If you have any questions, feel free to shoot me an email at firstname.lastname@example.org.
Although simple and powerful, .env files can be troublesome when mismanaged in the context of a larger team. Imagine having to distribute and track hundreds of keys to your software development team; in our previous startup called Auledge, which by the way only had 3 software developers working on 3 code repositories, we found ourselves managing 40+ keys and already getting bogged down about it. On a simplified level, between Bob and Alice, here’s what might happen:
- Bob might add an API key to his local .env file and forget to inform Alice to add it to hers; this cost Alice 15 minutes in the future debugging why her code is crashing only to realize that it’s due to the missing API key.
- Alice might request Bob to send her the API key so she can add it to her .env file after which Bob may choose to send it over text or email; this now unnecessarily put their organization at risk of bad actors like Alice waiting precisely to intercept the API key.
Unfortunately, these challenges are common and even have a name: secret sprawl. As problematic as it is, secret sprawl for .env files remains a huge problem with no default solution for developers around the world. In recent years, many companies have tried to solve this problem. HashiCorp Vault is one product that securely stores secrets for large enterprises; it, however, is far too expensive, cumbersome, and frankly overkill to set up for the average developer who just needs a quick and safe way to store these secrets. Simpler solutions exist like but they often lack the security infrastructure needed to gain mass adoption.
What’s needed is an easy-to-use, secure, and universal solution against secret sprawl. We need teams to be able to sync and manage the many .env files roaming around their developer workforce in a way that’s accessible to everyone and not just large corporations who may have dedicated people and funds to pay for expensive, complex solutions.
At Infisical, we’re tackling the secret sprawl problem differently by focusing on being simultaneously simple and secure; we think a proper solution is one that can be set up in minutes and be so secure that even we cannot read anyone’s secrets. Our secret sauce is in offering an interface for developers to pull back and inject secrets directly into their local processes with 1 line of code, all whilst being end-to-end encrypted (E2EE); we even support push/pull commands to keep working with .env files if you want to stick to that. All in all, you can think of it as a minimalist tool to sync and manage your environment variables.
If you’re interested in learning more about Infisical, check out this article; better yet, sign up and try it out yourself!