Secure Node.js Config with Environment Variables

Managing sensitive configuration data like API keys, database credentials, and encryption keys is a critical aspect of Node.js application security. This article provides a straightforward guide on how to secure this sensitive information using environment variables and the popular dotenv package. You will learn how to set up environment variables, load them into your application, and prevent accidental exposure in your version control systems.

Why Use Environment Variables?

Hardcoding sensitive data directly into your source code is a major security risk. If your code is pushed to a public repository like GitHub, your credentials will be exposed to the public.

Environment variables solve this problem by decoupling your configuration parameters from your application code. This practice aligns with the “Twelve-Factor App” methodology, which recommends storing configuration in the environment. It also allows you to easily switch configurations between development, testing, and production environments without changing your code.

Step 1: Install the dotenv Package

The easiest way to manage environment variables in a local Node.js development environment is by using the dotenv npm package. This library loads variables from a .env file into Node’s process.env object.

Run the following command in your project terminal to install it:

npm install dotenv

Step 2: Create a .env File

In the root directory of your Node.js project, create a file named .env. This file will store your sensitive configuration options as key-value pairs.

PORT=3000
DATABASE_URL=mongodb://localhost:27017/myapp
API_SECRET_KEY=your_highly_secure_super_secret_key

Note: Do not put spaces around the = sign, and do not wrap values in quotes unless they contain spaces.

Step 3: Secure the .env File with .gitignore

Before writing any code, you must ensure that your .env file is never committed to your Git repository.

Open your project’s .gitignore file (or create one in the root folder if it doesn’t exist) and add the following line:

.env

To help other developers on your team understand what configuration is required, create a template file named .env.example. This file should contain the keys but leave the sensitive values blank:

PORT=
DATABASE_URL=
API_SECRET_KEY=

You can safely commit .env.example to your version control system.

Step 4: Load and Access Variables in Node.js

To load the variables from your .env file into your application, require and configure the dotenv package as early as possible in your application’s entry point (e.g., app.js or index.js).

Here is how to access the variables using process.env:

// Load environment variables
require('dotenv').config();

const express = require('express');
const app = express();

// Access the variables
const port = process.env.PORT || 5000;
const dbUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_SECRET_KEY;

app.get('/', (req, res) => {
  res.send('Application is running securely!');
});

app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});

If you are using ES modules (import syntax), you can load the configuration like this:

import 'dotenv/config';
import express from 'express';

Step 5: Managing Variables in Production

You should not upload your .env file to your production server. Instead, you should inject environment variables directly through your hosting platform’s dashboard or CLI: