module.exports vs environment variables - node.js

What is the difference between storing sensitive credentials in a credentials.js file as opposed to an .env file?
With module.exports you can write:
const KEY = require("./credentials.js");
Whereas with .env files you can write:
const KEY = process.env.KEY;
In both cases you accomplish the same goal of making some variable "global" and accessing it globally. Why do people use .env and dotenv instead of just using Node's built in module.exports system?

Environment variables are meant to be defined on the machine (system). The environment variables can be used on multiple application running on the same system.
Exported variables are only limited to the application you are running.
In your case: If you want to deploy your application on 3 servers (Dev, QA, Prod) but on with different credentials, it doesn't make sense to change the credentials every time when deployment. Even if you define credentials for every server it has to be static and if you want to change it, you must do changes in file and deploy the app again to reflect the changes. In case of environment variables, you just have to change it on the targeted system and restart the server, so there is no need to deploy the app again.
It becomes a mess to manage when there are changes in more than one environment variables. Also, environment variables are useful when it comes to integration with other services.
For security in environment variables, you can read this
When storing credentials:
There is risk of exposing credentials to version control system when stored in config file
It doesn't matter where credentials are stored, if the system is compromised
You can use a runtime configuration file. Find it here

Related

How to change values of .env variables depending on URL where the application is launched?

There is a react application that can run on three different urls, depending on whether it is production, development or UAT. How to change the values of variables in the .env file depending on which url the application is running on?
Well, or at worst, how to connect different .env depending on the url?

Pre-defined, special purpose system environment variables for Node/NPM

Are there any special-purpose variables that I can pre-define for Node?
I've noticed that the in Windows, system environment variables are available to Node, like %PATH%, %OS%, and others. You can define your own too, and they are all available via process.env.your_var_name.
In a lot of the documentation I've been reading, there are references to things like PORT, ENV, NODE_PATH, DEBUG, etc.
Are these "special" to Node itself, or are these just variables I can name & define on my own in the OS?
%PATH%, %OS% are system environment variables and not specific to node. You can access them from the command line also.
Other environment variables like PORT, ENV are defined in a .env file to store credentials related to hosting and database.
You can create a .env file in the base directory of your project and store your own environment variables and access it using dotenv package.
More about environment variables:
https://www.freecodecamp.org/news/heres-how-you-can-actually-use-node-environment-variables-8fdf98f53a0a/

Node.js environment Variables VS configuration file

Can someone explain what's benefits of environment variables in Node.js over regular config file?
In my project I have config.js files with DB details, AWS keys, etc. This file is added to .gitignore and never shared on repository, instead there is demo.config.js file with all required parameters filled with fake creditentials, so you can just copy it as config.js and fill it with correct details after fresh install.
This file is "required" in every file when I need credentials in my project and on my development machine this config file is configured with test server details and with actual production server details on production machine.
Lately I read everywhere that everyone should use environment variables to store credentials safely, but I don't see any benefit to doing so in my project.
I'm not saying it's bad and my approach is better, I just want to know what actual benefit (security or otherwise) will I get with environment variables over my setup?
For me it is more like a common standard than anything else. The way how you use config.js is practically the same as using environment variables. But instead of storing the configuration in environment variables, you store it in js file.
The main difference is how you read that config. All mainstream languages I know, will easily allow you to read from environment variables, there is really wide support for it. Reading from config files brings additional complexity as you need to know the structure of that file, how to parse etc. In some languages (maybe node.js) it is probably easy to read from js file, but in others it could be difficult task.
That's why using environment variables is just a common standard and language agnostic. You can even read it in bash scripts etc.
Edit: adding reference to The Twelve-Factor App, the Config section is particularly connected with above question:
https://www.12factor.net/config
One benefits i see when you are using docker for local development and kubernetes or any container orchestration for SIT/UAT etc where config setting is there . In local development we keep all env variable required and move the same on container based system

what's the preferred way to store sensitive settings in web apps?

I know that a good way to store data like db passwords, etc. is via environment variables, but setting environment variables manually for every server instance created is time consuming.
I'm planning to deploy my project to the cloud (using aws ebs or heroku).
where should I store my db password?
I think the .ebextensions file isn't a good option because it's tracked in vcs
Don't ever store secrets in source control. A common practice is to either put them in a secure file or in something like https://www.vaultproject.io/ then inject them (programmatically via a script or some other deployment/configuration tool) into the environment when you bring up your VM (or container or whatever).
My recommendation is to create a properties file which can be stored in the resources folder of your application and the code can access the resources. do not need environment variable. One property file can contain all db's userid and passwords. Deploy job based on url mapping in the properties file. For example, look at a spring hibernate example project which uses a property file. Or look at ant deploy scripts. Hope it helps.

secure nodejs production environment that use dotenv

By using dotenv I can ignore development .env file before pushing it to the git repository, it comply with The Twelve-Factor App config factor. It prevent configuration from exposing to others especially open source project.
But I am stuck when deploying it to the production, either using cloud deployment or using docker.
How can I include this file? Should I save the file into Vault or something?
Please help me to understand how can I secure my deployment environment.
You don't. The server environment (docker or otherwise) needs to be configured with its own environment variables, not the development ones. Any that will be the same in both you configure as default values for the application so that they have that value even if the variable isn't set.
You can use a file transfer protocol such as filezilla or cyberduck and transfer the file to your production server environment. Make sure the .env file you send to your server contains the credentials for the production database and not the development one and so on. You could alternatively just add environment variables to your remote server's .env or .bashrc file, but this is probably not advisable compared to a .env file. As long as no one but you has access to the remote server (docker, heroku, aws, etc) your credentials should be secure. Never share your .pem files.

Resources