Posted on April 10, 2014 by Chris Harrington

Securing configuration files with Node for Travis and Heroku

I’ve recently been building an issue tracker using Node called Leaf. It’s a fun project that lets me dive into Node and learn its pros and cons. It uses a number of services that require either API keys or username/password combinations and I ran into the problem of how to secure these sensitive bits of information so that anyone browsing my Github repository wouldn’t be able to sign into those accounts for nefarious purposes.

Leaf is using a couple of different services. It uses Travis for continuous integration and Heroku for scalable hosting (both are excellent, by the way). The convention for configuration variables in Node is to use environment variables, which means that for every environment that builds and runs the application, we have to set the environment variables that correspond to each of our configuration variables. It’s quite the pain in the ass. I’ve broken down this post into three sections, one each for setting the appropriate environment variables locally, for Travis and for Heroku.

Local Development

Reading configuration data for local development is a little tricky. Because I don’t want to check in plaintext versions of tokens and passwords, I’m using the config-leaf npm package.

npm install config-leaf

Once installed, we’re going to add npm scripts to easily encrypt and decrypt our configuration file that contains the sensitive information. The config-leaf npm page has all the details you need to do this, but you can just copy the “encrypt” and “decrypt” scripts from below into the package.json file for your Node project to get started. Obviously make sure to replace “config.json” with your configuration file (for Leaf, it’s secureConfig.json).

{
  "name": "my-project",
  "version": "0.0.1",
  "scripts": {
    ...
    "encrypt": "encrypt config.json config.json.cast5",
    "decrypt": "decrypt config.json.cast5 config.json"
  }
}

To encrypt your configuration file, run:

npm run encrypt

This will prompt you for a password. You’ll need this password to decrypt the configuration file later. Once encrypted, make sure to add your raw configuration file to your .gitignore or equivalent:

echo secureConfig.json >> .gitignore

Without this, you’ll check in the plaintext configuration we’re trying to hide from prying eyes. Once this is done, when making changes to your secure configuration file, you’ll need to encrypt it again. When pulling down for the first time or after a configuration change, you’ll have to decrypt the configuration file to be used in your application:

npm run decrypt

Leaf’s config.js class reads in the contents of secureConfig.json uses Node’s process.env object to add the appropriate configuration keys and values to be read later.

Travis

I’m using Travis CI to build, test and deploy Leaf to Heroku. To run the tests, Travis needs to have access to a number of configuration variables that I’ve set. I’m not using any of the secure configuration variables to run my tests, but I figure I should set it up for posterity’s sake. Because we’ve added secureConfig.json to our .gitignore, Travis won’t have access to these configuration variables. To get around this, Travis allows you to encrypt environment variables. You’ll need to install the Travis command line utility to get started.

gem install travis

Once installed, you can run the following from your project root where your .travis.yml file exists.

travis encrypt BLAH=boo --add

This command indicates to Travis that it should add a secure environment variable called “BLAH” with value “boo” to the .travis.yml file. You’ll have to do this for each of the environment variables you want to secure. It’ll show up looking like this under the env/global space:

secure: NF11l3g3JG1vfRurqYDptVHuQ...

When your build runs on Travis’ servers, it’ll decrypt the value and apply the variable to its environment before running your build. That’s it!

Heroku

Finally, Heroku. This is the easiest of all the environments. Make sure you have your Heroku toolbelt installed and you’re logged in. Once that’s done, you’ll want to add your environment variables as follows:

heroku config:set BLAH=boo

Again, you’ll have to do this for each of the configuration variables you want secured. That’s all you need to do. No encryption is required here because the environment your application runs in on Heroku is private.

Conclusion

Compared with having plaintext passwords in your source, this is a huge pain in the ass. Despite that, however, it’s definitely worthwhile to hide your sensitive data. I’m a big proponent for open source software and this is necessary for me to continue to host my code in publicly available repositories.

gisonline-me-gray