Keep Your Azure Secrets Safely Out of Git

Application development these days often requires maintaining and securing credentials for numerous third party services and external tools. Your database, error tracker, and email integration services all require you to present a token or password for authentication and authorization.

If you’re keeping your source code out in the open, like on GitHub or CodePlex, or what-have-you, you want to be careful to keep those secrets to yourself.

ASP.NET and Windows Azure make that pretty easy through the web.config’s ability to import external files.

The idea is to keep your secrets in a second file that is never itself added to source control.

In development, during application start, the ASP.NET runtime will automatically import the external file and override any settings already configured in the web.config.

In production, you can set these overridden values manually through Azure’s management portal.

While the instructions below are specific to Azure, the main idea can be applied to any other deployment scenario. For example, instead of using the Azure management portal to override the web.config settings, maybe you have a deployment script that drops the necessary files in the necessary places.

As an example, one of my apps uses Rollbar to handle errors. In order to authenticate with Rollbar, the client library needs an access token. Since the source code is available on GitHub, I can’t simply commit the token as part of the web.config.

Luckily, we don’t have to store the secrets in the web.config itself, rather we can store them in an external secrets.config. This is just another XML file with the same syntax as web.config and ASP.NET merges its values into the section that imported it.

web.config
1
2
3
4
<appSettings file="secrets.config">
  <add key="Rollbar.AccessToken" value="OVERRIDE_ME_IN_SECRETS_CONFIG" />
  <add key="Rollbar.Environment" value="development" />
</appSettings>

Notice the file="secrets.config" attribute on the appSettings element. This attribute tells the .NET runtime to load the reference file (if it exists) and merge the external settings in with those defined below it. If there is a conflict (in this case using the same key), the external file’s value will win.

secrets.config
1
2
3
<appSettings>
  <add key="Rollbar.AccessToken" value="** my access token **" />
</appSettings>

Then all we need to do is add secrets.config to the .gitignore. Other SCM systems will have similar features.

~/projects/Landmine
1
2
3
# Add a line with "secrets.config" to the end of the .gitignore
# You can use notepad or any other text editor if you'd rather.
$ echo "secrets.config" >> .gitignore

I like to keep the setting in web.config with a placeholder value as a reminder to myself or other developers that a secrets.config file needs to be created with the requisite settings. Since that file is never committed, a future developer cloning the repo won’t get a copy of it.

In production, you can use the Azure management portal to override any value in the appSettings section:

Keys set here will override anything in the web.config

Comments