Cover your environment variables at runtime

Dũng Trần
Oct 17, 2020

dotenv is a popular package to load environment variables from .env file. It’s easy to use and noob friendly. Everyone love it, I’m not an exception. I just have concern about how does environment stored.

require('dotenv').config();

This one is simplest code to load all environment variables from .env file:

TEST_ENV=This is a test string

After dotenv triggered, .env file will be loaded to process.env as a key values object.

console.log(process.env.TEST_ENV); // This is a test string

What’s wrong?

  • process.env able to access everywhere without restriction
  • process.env is also store all credential data
  • All key in process.env could be overwrite
  • TEST_ENV wasn’t friendly to typescript and linter

How could we improve that?

In the try to improve everything that was pointed above, I’ve found Proxy could help a lot. The idea is, I will clone a copy of process.env and wrapper all accesses through and Proxy object.

This code get things done following steps:

  • Cache default environments variables
  • Load configuration from .env file
  • Create a singleton Proxy that’s hide all keys and protect read and write

Result

Let’s take a look into example .env:

DB_USERNAME=1usd
DB_PASSWORD=somestring

Here is the result:

console.log(exportedConf.dbUsername, exportedConf.dbPassword);
// -> 1usd somestring
console.log(exportedConf.authentication);
// -> Error: You are trying to access undefined key
console.log(process.env);
// -> Default enironment variables
exportedConf.dbUsername = 1;
// -> Error: You can not set value to immutable object

It works, just like expected.

--

--