# Taking a peek at Azure Key Vault Part 2 of 2

In the previous post, you set up Key Vault and added a secret via the Azure portal. Now you'll see how to securely access that secret programmatically. Let's start by creating a ASP.NET Core API app in Visual Studio (or you can grab the completed project here (opens new window)):

After the project is generated, add a new controller file called SecretController.cs with the following code.

using Microsoft.AspNetCore.Mvc;

namespace KeyVaultApi.Controllers
{
    [Route("secret")]
    [ApiController]
    public class SecretController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public IActionResult Get()
        {
            string secret = "TBD";
            return Ok(new { Secret = secret });
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

As you might expect, the response from a browser request (or a tool like Postman (opens new window)) looks like:

To retrieve the secret from Key Vault, you'll want to pull in the Azure.Security.KeyVault.Secrets (opens new window) and Azure.Identity (opens new window) NuGet packages. The SecretClient class is the entry point for interacting with secrets in the Azure Key Vault, and the client code is actually pretty simple. Here the Key Vault service name is fort-knox and the secret's name is deep-thought; you should provide the appropriate values for your service.

public async Task<IActionResult> GetAsync()
{
    string secret = "TBD";

    var secretClient = new SecretClient(new Uri("https://fort-knox.vault.azure.net"), new DefaultAzureCredential());
    secret = (await secretClient.GetSecretAsync("deep-thought")).Value.Value;

    return Ok(new { Secret = secret });
}
1
2
3
4
5
6
7
8
9

The DefaultAzureCredential is appropriate for most scenarios. You can refer to here (opens new window) for more information.

During development, if you are signed in via the Azure CLI (opens new window), the app will authenticate using AzureCliCredential. Of course, that identity needs requisite (Get) access to secrets in Key Vault, but if it's the same user that set up the secret, it already has more permissions than needed.

To set up the application to run within Azure, create a new API app in the Azure portal, and via the Managed service identity option under Settings, select On to register with Azure Active Directory. This creates a service principal that the API app can use to authenticate itself to other Azure services like Key Vault.

At this point, your Azure Key Vault does not have an access policy associated with this new identity, so any attempts to run the app in Azure would result in a Forbidden (403) error. To remedy, create a new policy that refers to the API app you just created (or more precisely to the MSI associated with that API app). For purposes of this exercise, the only needed operation is to get secrets from Key Vault.

Now, you can deploy the application and run it from Azure as well.

If you are building ASP.NET Core applications, you can add package Azure.Extensions.AspNetCore.Configuration.Secrets (opens new window) to your project.

In the Program.cs of your ASP.NET Core application, add the following call to ConfigureAppConfiguration to first get the name of the Key Vault from standard app properties and then use the AddAzureKeyVault extension method to gather all the names of the Key Vault secrets into the IConfiguration reference. Note, because the extension enumerates the secrets in Key Vault, you will need to grant the MSI List as well as Get permissions on the Key Vault instance.

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            var builtConfig = config.Build();

            config.AddAzureKeyVault(
                new Uri($"https://{builtConfig["Vault"]}.vault.azure.net/"),
                new DefaultAzureCredential());
           }).UseStartup<Startup>();
1
2
3
4
5
6
7
8
9
10

The complete body of the controller then becomes

[Route("secret")]
[ApiController]
public class SecretController : ControllerBase
{
    private readonly IConfiguration _config;
    public SecretController(IConfiguration config)
    {
        _config = config;
    }

    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new { Secret = _config.GetValue<string>("deep-thought") });
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

For more on this subject, Use Key Vault from App Service with Managed Service Identity (opens new window) on GitHub has a larger sample of using MSI to authenticate to Key Vault. Additionally, you can find examples (opens new window) that cover manual application registration using client secrets and certificates; however, those techniques are no longer recommended whenever MSI can be used.

I hope this helps someone out there!