Best way to store secrets in application - node.js

Which one would be a better way to store secret API keys in Node js applications.

Create .env file at root folder and add your all keys, password in that file. To make it secure never ever add file in git repo. Instead add this file in .gitignore file so that git ignore this file when you push your changes.
Syntax of .env file
APP_URL=http://localhost:3000
APP_KEY=SECRETKEY
Additionally to access the keys from your .env file is process.env.APP_KEY
Its secure method, no one can access this file. I use this way.
Hope it gives your answer.

Related

node and github secrets. how to test locally

i'm using node and github actions for a simple twitter api script.
twitter credentials are stored in github secrets
other than hard coding the twitter credentials and then changing the code to use secrets before pushing to github how do i test locally?
I need some way to retrieve the credentials locally if running locally and from secrets if running on github.
what is best practice way to do this please?
Essentially, what David is trying to say is that you'll need to store your credentials in two separate places:
Inside GitHub Actions Secrets
Your local filesystem inside a gitignored .env file
GitHub Actions Secrets
GitHub Actions Secrets uses encryption to store the secret value, and this information is only decrypted while the workflow is running. Note that the secrets are not stored in the codebase. Instead, this is managed entirely via the GitHub web interface, and perhaps the GitHub API. I do want to emphasise again that none of this is stored inside your git repository as that would essentially be considered a security leak.
Now, this works fine when running in GitHub Actions, but the question you have is how do you run locally. This is where the .env file comes into play.
Running Locally with .env and dotenv
Create the following file, and add the same value you used as the secret in GitHub Actions secrets inside the .env file as a key/value pair. Let's assume the secret name is MY_SECRET_CRED and the value is abcdefg:
.env:
MY_SECRET_CRED=abcdefg
Next, add this file to .gitignore. You do not want to commit this, because it would violate your security, and you also don't need it to be committed, since GitHub has stored the credential as a secret. You only need this file locally.
.gitignore:
.env
The purpose of adding the file to gitignore is because you do not want to commit this file. This file is local to your workstation only.
Next, install the dotenv npm module:
$ npm i dotenv
In your main file, be sure to require the dotenv module. This module reads the contents of .env and loads the key value pairs up as environment variables:
require('dotenv').config()
Tying it all together
In your application code, you're probably already using the secret in GitHub Actions as some kind of environment variable. If running in GitHub Actions, you can load the secret as an environment variable with the same name you used in the .env file:
- name: Test application
env:
MY_SECRET_CRED: ${{ secrets.MY_SECRET_CRED }}
run: npm run test
In the above example, the Node.js process can access the secret as the environment variable MY_SECRET_CRED
doSomethingWithSecret(process.env.MY_SECRET_CRED);
But do note that, if you try to print it, GitHub will mask it, since it knows it's a secret that shouldn't be leaked.
When running locally, the environment variable is loaded into the Node.js process via the dotenv module.
Downside to .env files
The downside to .env files is that the secret is stored in plain text in your workstation, and it's difficult to share with other developers. Ideally, we don't want to share secrets through chat systems or email for the same reasons we don't want to commit and push them.
One solution is to use a secret manager or key management store to encrypt secrets locally. Your local application then decrypts them when running the application. This also means you can commit the encrypted data directly to the GitHub repository. One example of this is Google KMS.

How to keep an encrypted file and read the file using nodejs

I have a set of passwords which I have saved in git repo. But I want to keep the file always encrypted. But in my automation, I should be able to decrypt and read data from that file.
Any idea how its possible ?

where should I store personal data for npm package?

For example, I have a npm package which is a cli-tool. Users should set their yahoo email and password first before using the functionalities.
My question is where should I store the personal data? Is there a convention?
Most cli's use a hidden configuration file commonly stored in the home directory of the user. For example .cli-config, it is also good to store the configuration data as JSON or YAML.
Finally be carful to save sensitive data in the config file as it still is just a file and can be accessed by anyone with correct permissions.

credentialSecret option and _cred.json file

Without making any changes to settings.js file, I can see two JSON documents in .node_red folder - one for the flows and other for credentials. For example, flows_ip-xxx-xxx-xx-xx_cred.json and flows_ip-xxx-xx-xx-xx.json. Then, there is a field as credentialSecret in the settings.js file.
On a fresh Node-RED installation, suppose, I manually copied flows_ip-xxx-xx-xx-xx.json only, from an earlier installation, followed by a restart. I will copy into a different_name.json that is also mentioned for the flowFile property. Then, are the credentials still copied over but encrypted with a (different) auto-generated password? In which case, if I defined a common value for credentialSecret option in settings.js for both installations, the nodes would get correct credentials in the new installation?
I should probably be using the projects option; but, until then, I want to figure out the credentials behavior.
If you do not set a credentialSecret in settings.js then Node-RED will create a key the first time it starts and store it in the hidden file called .config.runtime.json in the user directory.
This key will be used to encrypt the flows_creds.json to protect the credentials file.
If you need to move a flow to a new machine then you can copy the _credentialSecret value from .config.runtime.json to the credentialSecret in the new settings.js to allow it to decrypt the existing credentials file.
If you are starting from scratch then you can choose to define your own credentialSecret in the settings.js on both machines to allow them to decrypt a common flow_creds.json file.
And yes the new project feature makes this a lot easier.

where to store admin password in sinatra + heroku app?

I have a small Sinatra app I'm running on Heroku that uses a single admin password, plus a couple API authentication keys.
Where's the best place to store these things? Do I put them in environment variables, and use
heroku config:add ADMIN_PASSWORD=foobar
? Or do I use a config file that contains them, and I simply don't commit the config file?
I stick API keys and that sort of thing in a config yaml, like so
development:
twitter_api_key: stringstringstring
chunky: bacon
production:
twitter_api_key: gnirtsgnirtsgnirts
foo: bar
then use Sinatra's builtin set to handle the data.
configure do
yaml = YAML.load_file(settings.config + "/config.yaml")[settings.environment.to_s]
yaml.each_pair do |key, value|
set(key.to_sym, value)
end
end
And I can then access them from the settings object. I'm not sure why you wouldn't commit the config file, though . . . there's no major security risk here, since only those paths that you've explicitly defined can be accessed via the web. I guess the admin password could be stored in the same manner if you don't want to put it in a database, but I would at least encrypt it with a salt.
Just be careful not to step on Sinatra's Configuration settings when defining your own.
EDIT:
I think I just realized why you would prefer not to commit the config file. If you're working on an open source project, you certainly wouldn't want to commit the config file to your open source repo, but you would need to commit the file to Heroku in order for it to work. If this is the case, I'd either:
Use two separate local repos: one for the open source project, and one for the heroku project. Just set the open source project as an upstream repository in the Heroku project, then you can fetch changes.
Put both the API keys and encrypted/salted password in a database; MongoHQ offers a free tier to Heroku users as an addon for simple nosql storage using MongoDB.

Resources