Last time out, we established there are some things you shouldn’t leave lying around in your code.

Connection strings, API Keys, client secrets, the list goes on.

We can use the .NET Core User Secrets system to store these values during development, but what about when we deploy to production?

How sensitive are your secrets?

In reality, not all secrets are created equal.

Take an API key for a third party API (such as the OpenWeather API we’re using in the .NET Core Angular 2 sample app).

It’s obviously not a good idea to go sharing that around all over the place (especially if you’re set up to pay for usage) but equally it’s not the kind of secret that could bring your company down. After all, if it did get into the wrong hands, you could easily cancel it and create a new one.

But let’s say you wanted to provide a “software as a service” app, which allowed customers to retrieve data from third party APIs using their own credentials/keys.

This is different. Now you’re handling someone else’s private data and they probably want some assurances that you’re looking after it properly.

In Azure you have two clear options for storing your secrets.

Option 1: Using App Settings

The .NET Core configuration system lets you store your keys and secrets in various places. When you subsequently ask for the value of one of these keys, it looks in these places and returns the relevant value (if it finds one).

It uses Configuration Providers to pull the values from various places, such as…

  • File formats (INI, JSON, XML)
  • Environment Variables
  • Azure Key Vault

There are others, check out the official site for a more complete list.

In the last post we wrote this code to pull in the secret values from user secrets via our app’s configuration.

if (env.IsDevelopment())
{
  builder.AddUserSecrets<Startup>();
}

The app also loads in configuration values from appsettings.json, appsettings.{EnvironmentName}.json (if found) and environment variables.

var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();

When you run your app, each of the locations above is inspected, and all configuration values are loaded into memory.

You can store your secrets in different places for different usages. For example you can make use of User Secrets for development but opt for Application Settings in production. .NET Core will still find your secrets (that’s right, there’s nowhere to hide).

That means, if we deploy this app to Azure, we don’t have to change any code to access our secrets. We can simply add the values to Application Settings via the portal, and ASP.NET Core will find them.

In the Weather Checker app, our authentication requires a googleClientId and a googleClientSecret.

ClientId = Configuration["googleClientId"],
ClientSecret = Configuration["googleClientSecret"],

We can deploy our app to an Azure app service, go to Application Settings and add the super secret values there.

Azure makes these values available to our app as Environment Variables.

Remember the .AddEnvironmentVariables() line we had in configuration? That ensures ASP.NET Core pulls these values in.

The app will use these keys in production and we’ve kept them out of source control.

Option 2: Azure Key Vault

An Azure Key Vault is the way to go for anything where you need to offer more assurances about security.

Take our SaaS example earlier (storing other people’s secrets).

You could let your users enter their secure information and save it directly into an Azure Key Vault without your application ever taking ownership of it (or directly storing it). Then you could seamlessly ask Key Vault to provide those secrets as needed, to connect to the third party API.

Furthermore, if you’re required to offer certain guarantees about your key storage (compliance with FIPS 140-2 Level 2 HSMs, for example) then Key Vault is the way to go.

It’s also a little more complex and deserves a post in it’s own right (coming right up).

In Summary

If you’ve no idea what FIPS 140-2 Level 2 HSMs are (me neither) and just need to store your own OpenWeather API Key, then app settings (option 1) may well suffice.

It’s trivial to set these secrets in production, then go about your day, happy that your secrets aren’t lying around in your source code. You also get to change them (if needed) without re-deploying your app.

For anything more important, Azure Key Vault offers much greater security out of the box. We’ll take a look at that in the next post.

Whatever you choose, there’s really no need to air your secrets in public (AKA source control).

photo credit: Charos Pix A combination of locks via photopin (license)