Using nConf and Azure to avoid leaking secrets on GitHub
Azure, Node.js By Dave Ward. Posted February 26, 2013GitHub recently released a new version of its search feature. Unfortunately, it quickly became obvious that the feature could be misused to locate data that wasn’t intended to be exposed publicly. Passwords, oAuth tokens, and private API keys are particularly common in source code, and well-crafted searches to find them were making the social media rounds almost immediately after the new feature was released.
Of course, this sort of thing is nothing new. Similar Google searches have been possible for years. However, GitHub currently seems to house a concentration of particularly sensitive secrets. Maybe that’s because it’s so easy to accidentally commit these things along with associated code with a quick git commit -a.
I’ve been working on a few Node.js projects hosted on Windows Azure lately, and one in particular is stored in a public GitHub repository but needs access to private oAuth keys. So, this topic is something I’ve been dealing with myself lately. Through that project, I’ve been fortunate enough to stumble onto a nice symbiosis between Azure and a Node.js module called nConf that solves the problem of storing secrets in my public repositories.
Adding nConf to your Node.js app
nConf is a simple, but handy, module by Charlie Robbins. As with any other npm module, adding nConf to your app is easy. A quick npm install nconf from your project’s root directory will do it:

You’ll see npm downloading nConf and its dependencies, and then you’ll be ready to start using the module in your code right away.
I can’t say enough good things about how well the folks at Joyent and Microsoft have made this work on Windows. I have a MacBook and I host this site on an Ubuntu VPS, but I still do the overwhelming majority of my serious development work on a Windows 8 desktop. In the early days, working with Node.js on my Windows desktop was tedious and painful, but things have changed significantly for the better during 2012. Kudos to everyone involved in making that happen.
Using nConf to read settings from a config file
With nConf installed, exposing configurable settings for your app is simple. For example, let’s say we want our app to have a configurable username and password. You might create a file called settings.json like this:
{ "username": "dave@encosia.com", "password": "password123" }
Then, you could pull those settings into your application with code like this:
var nconf = require('nconf'); nconf.file('settings.json'); var username = nconf.get('username'), password = nconf.get('password'); // Output: dave@encosia, your password is password123 console.log(username, ', your password is:', password);
That’s a handy way to read in settings from a config file, but this approach alone brings us right back the point where settings.json might accidentally get committed to a public repository.
Reading environment variables instead of a config file
Along with pulling settings out of a JSON file, nConf also supports reading arguments from environment variables. That’s particularly useful if your app is hosted on a PaaS like Azure that allows you to configure those environment variables through an interface that’s independent of your code.
For example, providing a username and password setting in this section of Azure’s “Configure” tab makes those settings available to Node as environment variables:
That’s great because nConf can read configuration from environment variables just as easily as a JSON file. All you need to do is a call nconf.env() instead of nconf.file():
var nconf = require('nconf'); nconf.env(); var username = nconf.get('username'), password = nconf.get('password'); // Output: dave@encosia, your password is hunter2 console.log(username, ', your password is:', password);
By itself, that’s not particularly impressive. You could also read those environment variables via process.env.username and process.env.password, without any extra modules.
However, the beauty of nConf is that you can combine both approaches.
The best of both worlds
Using environment variables works pretty well once the code is deployed to Azure, but I think the simple config file is a lot more convenient when I’m developing locally. The best thing about nConf is that it supports reading settings from both locations, in the priority that you specify.
So, you can use a settings file locally, but supersede that with environment variables if they’re present (i.e. once deployed to Azure). To do that, you can chain nConf initialization calls to both .file() and .env():
var nconf = require('nconf'); nconf.file('settings.json') .env(); var username = nconf.get('username'), password = nconf.get('password'); console.log(username, ', your password is:', password);
Now, running this locally with the settings.json file from earlier will output “password123″, but deploying it to the Azure site with the app settings shown above will change the output to… a 500 error, of course.
This simple example code doesn’t handle HTTP requests, nor does it output HTTP responses, so running it on Azure doesn’t work. But, the password variable will be correctly initialized to “hunter2″ instead of “password123″ when running on Azure with the environment variables we set in the previous section.
Now, add settings.json to your .gitignore and you’ll never need to worry about pushing your local, potentially-sensitive, credentials to a public repository.
Similar posts
What do you think?
I appreciate all of your comments, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to another comment, use the threading feature by clicking "Reply to this comment" before submitting your own.




Dave,
I’ve done another approach to overcome committing sensitive data to public github repository, by writing module in a separated file which is not part or included in the repository project, and then referencing it from inside nodejs code
for example:
C:\appConfig.js
exports.config = function(){
return {
settings{name:’myName’,password:’myPassword’};
};
} ;
and to get access to this data from Node code:
var config = requires(‘c:\\appConfig.js’);
var name = config.settings.name;
but I think that nConf still good approach and also it is more useful for azure based apps
Thanks for your post :)
Love the DailyWTF reference with the hunter2 password!