Click here to Skip to main content
15,867,330 members
Articles / Hosted Services / Azure

How to Use Microsoft Azure Key Vault

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
25 Apr 2019CPOL6 min read 8.7K   9   4
How to set up and use an Azure key vault to store your secret values

Introduction

In this post, I will describe how to set up and use an Azure key vault to store your secret values.

Sometimes, we see secrets like storage keys and connection strings written as literals in the code of a project, such as:

C#
public static class Secrets
{
  public const string ApiKey = "MyAppKey";
  // ...
}

This doesn’t seem too bad because:

  • It is the fastest way to obtain a key
  • Probably the key won’t change too often in time

But there are some serious drawbacks to this way of working as well:

  • If the key does change, code needs to be adapted and redeployed.
  • The key is plain visible in the code.
  • The key is “for ever” in the source code system, maybe even on a public repository.
  • When you change the environment (from DEV to ACC to PROD), the key will probably change as well. This becomes a problem with a hard-coded key.

It would be nice to store the key elsewhere, but what are the options?

  • The key can be stored in a configuration file. This is better already, but this file will still be readable by developers (and on the public repo).
  • The key can be stored in Azure. This is what we’re going to talk about in this article.

Prerequisites for this Article

If you want to follow along with the examples, you’ll need an Azure subscription. On the Azure home page, you can find the steps to create a free subscription, that will be valid for 3 months.

Introducing Azure Key Vault

We can store the following items in a Key Vault, for later use:

  • Secrets - A lot of types of data can be stored here, such as tokens, passwords, keys, …
  • Keys - Encryption keys can go here, and can be references later to encrypt / decrypt your data.
  • Certificates

These items are stored securely in the vault, only users (or processes) with the right access rights will be able to retrieve them. This access is monitored, so you can know who accessed what, and how the performance of the Key Vault is.

KeyVault

Creating an Azure Key Vault

In the Microsoft Azure Portal

image

  • Click on the “Create a resource” button at the top left.
  • In the blade that appears, enter “Key Vault” in the search box and select “Key Vault” from the list below.

image

Click “Create” and fill in the necessary parameters:

  • Name: A unique name for the key vault
  • Subscription: The subscription that will contain your key vault
  • Resource group: Here, you can either select an existing resource group or create a new one. For this example, you may want to create a new resource group so you can clean up everything easily when you are done “playing”.
  • Location
  • Pricing tier: Standard, unless you want HSM backed keys.
  • Access policies: By default, the current user will be the owner of the key vault. You can add or remove permissions here.
  • Click on “Create” and the key vault will be created for you. This can take some time.

Inserting Values in the Key Vault

  • Find your new key vault in Azure, and click on it. If your subscription contains a lot of objects, you may first select the resource group that the key vault is in.
  • You now see the overview page, with some useful information.

    image

     

    • The main important piece of information here is the DNS Name (top right). You will need this to connect to the key vault from your code.
    • You can also see the number of requests, the average latency, and the success ratio.
    • Pro tip: Make a note of the average latency as a baseline value for future requests.
  • On the left side, click on “Secrets”. You will see all the currently stored secrets. If you just created the key vault, this will be empty.
  • Click on “Generate/Import” to create a new secret:
    • Upload options: Manual
    • Name: Password (for our example)
    • Value: My Secret
    • Content type: Leave this empty
    • If you wish, you can also set an activation date and an expiration date for this secret. We will leave this empty for our example.
    • Make sure that “enabled” is set to yes and click “Create”.

When you click on the “Secrets” button on the left again, you will now see an entry for this key.

If you prefer to do this by scripting, the next section is for you.

Setting Up the Key Vault Using Azure Cloud Shell

Using a script to create an Azure object makes it repeatable. If you have multiple tenants, you can compose a script that will create the necessary objects for each tenant. This will save you time because:

  • Obviously, executing a script is faster than creating each object by hand
  • Consistency. If everything is scripted, you can be sure that all the objects are created the same for each tenant. This can save you hours of finding configuration bugs.
  • You can keep the scripts in source control, which allows you to version them as well.

Open Cloud Shell

image

At the top, click the “Cloud Shell” icon. If this is the first time that you open the cloud shell, a wizard will be shown to set up the shell. You can choose the scripting language to use (PowerShell or Linux Bash), and then Azure will create some storage for you. There is also a fair warning that the storage will cost you some money.

For this example, I will use Linux Bash.

RESOURCE_GROUP='CodeProject'
LOCATION='WestEurope'
KEY_VAULT='CPKeyVault666'

az group create --name $RESOURCE_GROUP --location $LOCATION
az keyvault create --resource-group $RESOURCE_GROUP --name $KEY_VAULT
az keyvault list
az keyvault secret set --vault-name $KEY_VAULT --name Password --value 'My Secret'
az keyvault secret list --vault-name $KEY_VAULT
az keyvault secret show --vault-name $KEY_VAULT --name Password --query value --output tsv

Using Azure Key Vault in Your .NET Project

Project Setup

clip_image001

Using Visual Studio 2019, create a new .NET Core Console App, name it ‘KeyVault’.

NuGet Packages

To use Azure Key Vault, you’ll first need to add 2 NuGet packages to your project:

  • Microsoft.Azure.KeyVault
  • Microsoft.Azure.Services.AppAuthentication

Open the “Package Manager Console” (Tools > NuGet Package Manager > Package Manager Console…) and type the following statements:

C#
install-package Microsoft.Azure.KeyVault
install-package Microsoft.Azure.Services.AppAuthentication

In your source file, you will need the following using statements:

C#
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.Services.AppAuthentication;

Reading a String From the Key Vault

To separate the concerns in the application, it is best to create a separate class for this, such as:

C#
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Azure.KeyVault;
using Microsoft.Azure.KeyVault.Models;
using Microsoft.Azure.Services.AppAuthentication;

namespace KeyVault
{
  public class KeyvaultUtilities : IKeyvaultUtilities     
  {
     private readonly IKeyVaultClient _keyVaultClient;         
     private readonly string _vaultBaseUrl;

     public KeyvaultUtilities(string keyvaultName)         
     {             
        _vaultBaseUrl = $"https://{keyvaultName}.vault.azure.net";             
        AzureServiceTokenProvider azureServiceTokenProvider = 
		new AzureServiceTokenProvider();             
        _keyVaultClient = new KeyVaultClient(
		new KeyVaultClient.AuthenticationCallback
                  (azureServiceTokenProvider.KeyVaultTokenCallback));         
     }
     /// <summary>         
     /// Get the value for a secret from the key vault.         
     /// </summary>         
     /// <param name="keyname"></param>         
     /// <returns></returns>         
     /// <exception cref="KeyVaultErrorException">
     /// When the key is not found, this exception is thrown.</exception>         
     public async Task<string> GetSecretAsync(string keyname)         
     {       
        try             
        {
           var secret = await _keyVaultClient.GetSecretAsync(_vaultBaseUrl, keyname)
                         .ConfigureAwait(false);
           return secret.Value;             
        }
        catch (KeyVaultErrorException kvex)
        {
           throw new KeyNotFoundException
           ($"Keyname '{keyname}' does not seem to exist in this key vault", kvex);
        }
      }
   }
}

The purpose is to read a secret from the key vault, so that is the only method that I have implemented. You can add other key vault related methods in the class when needed.

Using this class is easy. Instead of passing the key vault name as a string, you may get it from a settings file. That will also allow you to travel easily through your development environments.

Notice that we never created a secret with a name “xyz”. Trying to retrieve this value will throw a KeyNotFoundException.

C#
using System;
using System.Threading.Tasks;

namespace KeyVault
{
  class Program
  {
     static async Task Main(string[] args)
     {
        Console.WriteLine("Hello World!");
        IKeyvaultUtilities util = new KeyvaultUtilities("cpkeyvault666");

        string pwd = await util.GetSecretAsync("Password");
        Console.WriteLine("Password: " + pwd);
        string xyz = await util.GetSecretAsync("xyz");
        Console.WriteLine("xyz: " + pwd);
     }
  }
}

Cleanup in Azure

On the Azure Portal, go back to the Cloud Shell. Delete the ‘CodeProject’ resource group:

C#
RESOURCE_GROUP='CodeProject'
az group delete --name $RESOURCE_GROUP --yes

This will delete the ‘Codeproject’ resource group, with all of its contents. Don’t worry if you don’t perform this step, the key vault only costs you a wobbling 3 cents per 10000 operations. You can calculate your costs here: https://azure.microsoft.com/en-us/pricing/calculator/.

You can also delete the resource group through the Azure portal.

First Retrieval of the Secret Can Be (very) Slow

Retrieving the first key can take several seconds. If you are not sure that you will always need a secret from the key vault, you may consider using the class Lazy<T>.

The next retrievals are fast.

For this reason, you may consider to register the KeyVaultUtilities as a singleton and inject it instead of recreating it each time. How you do this will depend on the type of application that you are creating.

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Faq.be bvba
Belgium Belgium
Gaston Verelst is the owner of Faq.be, an IT consultancy company based in Belgium (the land of beer and chocolate!) He went through a variety of projects during his career so far. Starting with Clipper - the Summer '87 edition, he moved on to C and mainly C++ during the first 15 years of his career.

He quickly realized that teaching others is very rewarding. In 1995, he became one of the first MCT's in Belgium. He teaches courses on various topics:
• C, C++, MFC, ATL, VB6, JavaScript
• SQL Server (he is also an MSDBA)
• Object Oriented Analysis and Development
• He created courses on OMT and UML and trained hundreds of students in OO
• C# (from the first beta versions)
• Web development (from ASP, ASP.NET, ASP.NET MVC)
• Windows development (WPF, Windows Forms, WCF, Entity Framework, …)
• Much more

Of course, this is only possible with hands-on experience. Gaston worked on many large scale projects for the biggest banks in Belgium, Automotive, Printing, Government, NGOs. His latest and greatest project is all about extending an IoT gateway built in MS Azure.

"Everything should be as simple as it can be but not simpler!" – Albert Einstein

Gaston applies this in all his projects. Using frameworks in the best ways possible he manages to make code shorter, more stable and much more elegant. Obviously, he refuses to be paid by lines of code!

This led to the blog at https://msdev.pro. The articles of this blog are also available on https://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=4423636, happy reading!

When he is not working or studying, Gaston can be found on the tatami in his dojo. He is the chief instructor of Ju-Jitsu club Zanshin near Antwerp and holds high degrees in many martial arts as well.

Gaston can best be reached via https://www.linkedin.com/in/gverelst/.


Comments and Discussions

 
GeneralMy vote of 5 Pin
E. Scott McFadden28-Apr-19 16:23
professionalE. Scott McFadden28-Apr-19 16:23 
QuestionHow is the user / process authenticated? Pin
Klaus Luedenscheidt25-Apr-19 19:01
Klaus Luedenscheidt25-Apr-19 19:01 
AnswerRe: How is the user / process authenticated? Pin
Gaston Verelst25-Apr-19 22:35
Gaston Verelst25-Apr-19 22:35 
AnswerRe: How is the user / process authenticated? Pin
Bob Crowley26-Apr-19 12:55
Bob Crowley26-Apr-19 12:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.