Env File: The Only Guide You'll Need
At Onboardbase, we found that 37% of all surveyed engineering teams have experienced a security breach, and 47% of these security breaches are caused by negligence. Incorrectly using an env file is probably the easiest way to expose yourself to an attack. In fact, cybersecurity researchers found that thousands of IP addresses are scanned with the intent to expose and leverage insecure .env files.
Environment variables have been an integral part of software development ever since they were introduced in UNIX operating systems in 1979. While environment variables are vital to software processes, they also become double-edged swords when used improperly to store keys, secrets, and credentials. In the following article, you’ll learn everything you need to know about creating and managing an env file to securely define custom environment variables.
What is an env file
A .env file (pronounced dot-env file) is a configuration file written in YAML (YAML Ain’t Markup Language) to define environment-specific variables.
You’d typically use it to store database logins, API keys, or global constants to be used across the whole application. An env file example:
.env
APP_NAME=my app
NODE_ENV=development
DATABASE_USERNAME=terry
Why env files
As we explained, an env file defines environment variables. Like system environment variables, you can access them from any process. But unlike global environment variables, they are scoped to the folder they are defined in. This is interesting for several reasons:
- To prevent name collisions - A .env file acts as a separate namespace. If you define an environment variable in a .env file, its value will take priority over its global counterpart. For example, if you have an ENV variable set to “production” as a global env variable and an ENV variable set to “development” in your local env file, reading the variable in your local program will display “development”.
- To ease development - As a developer, you probably have dozens of projects sitting on your machine. It wouldn’t be sustainable to define global environment variables from the command line interface each time you have to do some work.
- To avoid hardcoding constants - Using .env files is a common web server security best practice, as they prevent you from directly writing down sensitive information in your code. Instead, processes inject environment variables at runtime. It makes managing these variables more manageable as you only need to update them in a single place instead of looking for every single occurrence in your code.
How To Manage .ENV Files: An 8-Point Checklist
1. Setting env file variables: the .env file format
In .env files, every value is a character string. You can’t natively use any other data type, but you can store them in serialized form and parse them from within your software program later on.
For example, the following JSON value is a valid character string:
.env
JSON_VAR={"test": "value"}
2. Using a .env file from within your app
Each programming language and development framework has its own way to deal with environment files.
In Javascript, for example, you can define environment variables both in backend and frontend development. In your backend, you can require the dotenv module to read values in a node env file (Node.js) at the root of your project and use the process.env variable to call environment variables:
index.js
require('dotenv').config();
(() => {
console.log(process.env.JSON_VAR)
})()
On the front side, it will depend on your framework. Sometimes you need to define env variables within a bundler like pngack, and sometimes this step is integrated in the default tooling so you can just use an env file as usual. With React, for example, you can just add a REACT_APP_ prefix to variable names in your react env file and use them in HTML and React components:
.env
REACT_APP_ENV=development
3. Organizing env files with comments
Env files support comments. You just need to append a hash sign # to a line to comment it:
.env
# this is a comment
NODE_ENV=development
For example, if you’re building an app interacting with many APIs, the list of API keys will soon become unreadable. Adding comments to break down the env file into smaller groups will help improve readability:
.env
# general
NODE_ENV=development
# database
DATABASE_USERNAME=X
DATABASE_PASSWORD=X
DATABASE_HOST=X
# Stripe API key
STRIPE_PK=XYZ
Comments are also often used to give indications on expected values or features of your program:
.env
# edit the following line to change database systems
DB_TYPE=sqlite
4. When to use .env files vs global environment variables
A modern software development life cycle usually includes three separate coding environments to allow for seamless code releases: a development environment for coding new features and bug fixes on a local machine, a staging environment to test the code on remote web servers configured with production settings to mimic as closely as possible real-life conditions, and the final production environment that interacts with end-users.
Since an environment variable is environment-specific by definition, it implies you’d need three different .env files. But while env files are handy to define environment variables without having to worry about name collisions, they are best avoided in staging and production environments as reading the env file every time a variable is needed is less performant than having them already available as global environment variables.
This is why hosting providers often offer an interface to define environment variables. If you don’t have this possibility or if you manage your own server, you can instead create your own environment variable with the export command or init utilities like systemd or upstart:
export MY_ENV_VARIABLE="custom value"
echo MY_ENV_VARIABLE
> custom value
5. Never put an env file in a public folder
If you really have to keep your env file in staging or production―again, you should find a way around it―make sure to never have the .env file in a publicly accessible folder.
Most web project structures include a public folder containing HTML, CSS, and other assets configured for web servers to access. It’s often named app, public, build, www, or static. Env files should always be in the root folder instead.
Even if you change the file’s access rights, it only takes one bad command to release it in the wild. And as we previously explained, leaking your environment variables has a high chance of causing catastrophic damages to your business.
6. Do not store env files in Git
Equally as bad as the previous point, you shouldn’t commit .env files to git repositories―or any other version control system. First, because git repositories are accessible to the whole development team and leaking secrets would be trivial. And second, because every commit will forever live on in your version history. If you make this mistake, you must invalidate all your credentials and use different ones to avoid future security breaches.
Instead, you should always start a new project by adding .env to the list of ignored files in your .gitignore. Example for a Javascript project:
.gitignore
.env
.env.*
node_modules
build
7. Remove the need for .env files entirely
What if you could have all the flexibility of an env file without compromising on security? That’s exactly what you can do with an app secret manager like Onboardbase.
Onboardbase stores your app secrets in a single repository. For example, we define two environment variables to connect to a database in the following screenshot:
Onboardbase also makes it easy to switch between several environments. You pick a project from your dashboard, define a new environment in a click, and navigate from one to another just as easily:
You can then use Onboardbase CLI’s setup command to pick the right project and environment in a few seconds:
onboardbase setup
The command generates an onboardbase.yml file that doesn’t contain any sensitive information. It’s only used to access the central repository:
setup:
project: projectname
environment: development
All you have left to do is to run the build command to inject .env variables from Onboardbase at runtime, removing the need to define environment variables in a .env file entirely:
onboardbase build --command="your project's build command"
8. Bonus: Never use debug mode in production
Even if you remove your env files, your info will still leak if your server credentials are compromised, of course. If attackers have access to your Shell, they can always print env variables. In the same vein, you need to make sure to disable debugging mode in production to avoid exposing env variables.
Debugging features often give out sensitive information like system variables that attackers can use to take over your service, so it’s primordial to use a hidden staging environment for debugging if you can’t find the source of an issue in development. Debugging in production is simply a big no-no.
Use Onboardbase To Replace Env Files
That’s everything you need to know about managing env files. The obvious problem is how hard it is to share environment variables with fellow developers using a .env file―you can’t use Github or normal means of communication without creating security threats.
Onboardbase makes developers’ lives easier by making sharing and integrating environment variables simple and delightful. A dashboard centralizes app configurations for the whole team, and a command-line interface is available to integrate env variables in any workflow. The best part? You can get started for free in a minute.
Subscribe to our newsletter
The latest news, articles, features and resources of Onboardbase, sent to your inbox weekly