Storing credentials the right way!
I have heard the stories of people that have ripped off companies because they stored credentials along with the code. Once the code goes public, it’s not easy to keep it away from bad eyes. And come on, everyone has been there at some point in their career.
There are a lot of security aspects that you need to take care of and securing your app’s credentials is one of them. By decoupling configuration from the application code, you can create a highly secure and scalable application.
Twelve-Factor App says, “A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials.”
Today, we will learn how to store credentials the right way on the server. But first, let's understand why keeping credentials with the code is a bad idea… wait! You know that all repetitive stuff… cut short,
Use Environment Variables
Environment variables (or env vars) are operating system level variables whose value can be used by one or more software programs, in our case, our backend application. As the value remains in the system, so there’s no risk of exposing credentials through your code.
Because all the system variables are stored at the same level, you have to carefully name your variables and avoid clashing names or you’ll end up screwing up your system. A good practice is to prefix your app name before the variable name.
You can easily find a library for managing your environment variables in your package manager repository. The most popular package for Node.js is dotenv and here is how you do it.
First, create a .env
file. This file should generally be inside your app directory, either at app’s root directory or a common directory inside (I usually store all credentials and certificates inside bin/
folder which is located at the root directory of app code).
Now define your variables along with their values in this file.
Now, the next step is to ignore this file from getting committed, after all that’s what we want to achieve. So, just add this newly created .env
file in your VCS ignore file. For example .gitignore
file, if you are using git.
Next, in Node.js after installing the dotenv package, you need to configure it and access the variables from process.env
object.
What goes inside an environment file?
Generally, things that you do not want the show to someone else, you hide them safely as an env variable. Your AWS secret key is an obvious example, while you can safely store the default query limit in your config file.
The variable naming should be independent of the deployment configuration. That means variables should not be prefixed with likedev-
or stag-
for different deployments. Instead, they should be kept in different files with the same name.
For example, your development env file name should be .env.dev
and likewise for other deployments, so that you can easily switch between the environments with a decision env variable. Here’s an example of this approach in Node.js.
if( process.env.NODE_ENV === 'development' ) {
// parse development environment file
} else if( process.env.NODE_ENV === 'staging' ) {
// parse staging environment file
} else {
console.error("No environment defined. Exiting app");
process.exit(1);
}
Here the NODE_ENV
is a decision env variable. You can set this variable when you run your code either from the command line or start script, like this,
NODE_ENV="development" node server.js
You must have also noticed that we kept APP_PORT
in the env file. If you are running multiple deployments on the same server, you can easily change port without even touching the code. Voila. Your code is more scalable for new deployment environments without affecting the other deployments.
Hope you learned something new. If you like this article, please share and do follow us for more such interesting secrets.