Hello! Let's continue our exploration of secure cloud solutions.
In our last lesson, we covered the "what" and "why" of Azure Key Vault. You learned that it's a secure, centralized service for managing your application's secrets, keys, and certificates, solving the security risks of storing sensitive data in configuration files.
Today, we transition from theory to practice. Our goal is to retrieve secrets from Azure Key Vault programmatically using the Azure.Security.KeyVault.Secrets .NET SDK. We will take the final step in securing our application by removing a hard-coded secret and fetching it directly from Key Vault at runtime. This lesson is heavily focused on C# code, which will be very familiar given your background.
1. Setting the Stage: Permissions and Packages
Before we can write any code, we need to ensure our application has permission to access the Key Vault and that we have the right tools (NuGet packages) for the job.
Granting Access with RBAC
Your application, and you as a developer running it locally, need explicit permission to read secrets. While the older "Access Policies" model exists, the modern and recommended approach is to use Azure Role-Based Access Control (RBAC).
For our purposes, two roles are important:
- Key Vault Secrets Officer: Allows managing secrets (create, set, delete).
- Key Vault Secrets User: Allows reading secret values. This is the one we'll focus on for our application's identity.
The following resource provides a clear walkthrough of creating a Key Vault and assigning the necessary roles.
Stop Storing Secrets in appsettings.json! Use Azure Key Vault Instead
In this video, 'Stop Storing Secrets in appsettings.json!', Milan Jovanović demonstrates how to create a Key Vault and, importantly, how to configure role-based access control (RBAC).
Watch from the beginning to 04:40. Focus on these key steps: Creating the Key Vault resource. Navigating to Access control (IAM) and adding role assignments. Understanding the purpose of the 'Key Vault Reader' and 'Key Vault Secrets User' roles being assigned to the developer's identity.
Required .NET Libraries
To interact with Key Vault, you'll need to add a couple of NuGet packages to your .NET project. Given your experience, you know how to do this using the Visual Studio NuGet Package Manager or the dotnet add package command.
Azure.Security.KeyVault.Secrets: This is the core SDK library. It contains theSecretClientclass that we'll use to perform operations on secrets.Azure.Identity: This is a crucial helper library. It provides the authentication mechanism, most notably theDefaultAzureCredentialclass, which simplifies connecting to Azure services.
2. The Direct Approach: Using SecretClient
The most direct way to retrieve a secret is by using the SecretClient. This approach gives you explicit control over when and how a secret is fetched.
The process involves three steps:
- Authenticate: Create an instance of a credential class from the
Azure.Identitylibrary. - Create a Client: Instantiate
SecretClient, providing the URI of your Key Vault and the credential object. - Get the Secret: Call the
GetSecretAsync()method on the client instance.
The official Microsoft documentation provides the most direct and authoritative guide for this.
Quickstart - Azure Key Vault secrets client library for .NET
This Microsoft Quickstart document walks through the entire process of creating a simple console app to interact with Key Vault.
Please read through the following sections to understand the code structure: 'Install the packages': Confirms the NuGet packages we just discussed. 'Authenticate and create a client': This is the most important part. Focus on the explanation of DefaultAzureCredential and how it automatically handles authentication in different environments. Note the code sample that creates the SecretClient. 'Retrieve a secret': This shows the simple GetSecretAsync method call.
How DefaultAzureCredential Works
The DefaultAzureCredential class is powerful because it creates a chain of credential providers. It tries each one in order until one succeeds. When you're developing locally and are logged in via the Azure CLI (az login) or Visual Studio, it will use those credentials. When your app is deployed to an Azure service (like App Service or an Azure Function) with a Managed Identity enabled, it will automatically use that identity. This means you can use the exact same code for both local development and production deployment without any changes.
Here's what a simple implementation looks like in a minimal .NET API:
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// Replace with your Key Vault name
var keyVaultName = "your-key-vault-name";
var kvUri = $"https://{keyVaultName}.vault.azure.net";
app.MapGet("/secret", async () => {
// 1. Create the SecretClient
var client = new SecretClient(new Uri(kvUri), new DefaultAzureCredential());
try
{
// 2. Get the secret
// Replace "YourSecretName" with the name of the secret in your Key Vault
KeyVaultSecret secret = await client.GetSecretAsync("YourSecretName");
// 3. Return the secret's value
return Results.Ok($"The secret value is: {secret.Value}");
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
});
app.Run();
To see this pattern in action, the following video provides a live demonstration.
AZ-204 Key Vault Masterclass: Secrets, Security, and Best Practices Explained
The 'AZ-204 Key Vault Masterclass' video demonstrates retrieving a secret from a local .NET 8 application.
Watch from 13:06 to 17:40. The presenter shows how SecretClient and DefaultAzureCredential are used in a controller. Pay attention to their explanation at 16:37 about why the code works locally: because they are logged into Visual Studio with an account that has permissions on the Key Vault.
3. The ASP.NET Core Way: IConfiguration Integration
While using SecretClient directly is effective, an even more seamless approach for ASP.NET Core applications is to integrate Key Vault directly into the configuration system. This allows you to treat secrets in Key Vault just like settings in appsettings.json.
This is achieved with another NuGet package: Azure.Extensions.AspNetCore.Configuration.Secrets.
This package provides an extension method, AddAzureKeyVault, that you call on the configuration builder in your Program.cs. It registers a configuration provider that automatically loads all secrets from your Key Vault.
This next video is an excellent and concise demonstration of this powerful pattern.
Stop Storing Secrets in appsettings.json! Use Azure Key Vault Instead
Milan Jovanović's video, which you viewed earlier for RBAC, also has a perfect segment on integrating Key Vault with IConfiguration.
Watch from 08:09 to 12:00. This is the core of this section. Observe how: The AddAzureKeyVault extension method is called in Program.cs. The application can then retrieve a secret using standard IConfiguration methods like builder.Configuration.GetConnectionString(...). A naming convention (ConnectionStrings--MyDatabase in Key Vault becomes ConnectionStrings:MyDatabase in code) is used to handle hierarchical configuration.
Here is how you would modify your Program.cs to use this pattern:
using Azure.Identity;
var builder = WebApplication.CreateBuilder(args);
// --- Key Vault Integration ---
if (builder.Environment.IsProduction()) // Or anytime you want to use KV
{
var keyVaultName = builder.Configuration["KeyVaultName"];
var kvUri = $"https://{keyVaultName}.vault.azure.net";
// Add Key Vault as a configuration source
builder.Configuration.AddAzureKeyVault(new Uri(kvUri), new DefaultAzureCredential());
}
// ----------------------------
var app = builder.Build();
// Now you can inject IConfiguration and use it as normal
app.MapGet("/secret-from-config", (IConfiguration config) => {
// The secret name in Key Vault is retrieved like any other app setting
var secretValue = config["YourSecretName"];
return $"The secret value from IConfiguration is: {secretValue}";
});
app.Run();
With this setup, you have successfully externalized your secrets to Key Vault while keeping your application code clean and decoupled from the secret retrieval logic. This is the preferred pattern for most ASP.NET Core applications.
Practice Exercise
Now, let's put this into practice.
- If you don't have one already, create an Azure Key Vault in your resource group.
- Add a new secret to it named
MyTestSecretwith any value you like (e.g.,ThisIsASecretValue123). - In the Azure portal, navigate to your Key Vault, go to Access control (IAM), and add a role assignment. Assign the Key Vault Secrets User role to your own user account.
- Create a new local .NET 8 Web API project.
- Add the
Azure.Extensions.AspNetCore.Configuration.SecretsandAzure.IdentityNuGet packages. - In
appsettings.json, add your Key Vault's name:{ "KeyVaultName": "your-key-vault-name" } - Modify
Program.csto add theAddAzureKeyVaultconfiguration source, as shown in the example above. - Add a minimal API endpoint that injects
IConfigurationand returns the value ofMyTestSecret. - Open a terminal and log in to Azure with
az login. - Run your application and test the endpoint. It should return the secret value from your Key Vault.
This exercise consolidates all the concepts from today's lesson into a practical, working result.
Conclusion
In this lesson, we made a significant leap forward in securing our application. You learned how to programmatically access secrets from Azure Key Vault, effectively removing them from your application's source code and configuration files.
Key Takeaways:
- Permissions are Key: Your development identity (and later, your application's identity) must be granted RBAC roles like Key Vault Secrets User to read secrets.
- The SDKs: The
Azure.Security.KeyVault.SecretsandAzure.Identitypackages are the essential tools for .NET developers. DefaultAzureCredentialis Your Friend: It provides a seamless authentication experience that works both locally and when deployed to Azure.- Two Primary Patterns:
- Direct Access with
SecretClient: Gives you explicit control over fetching individual secrets. IConfigurationIntegration: The recommended approach for ASP.NET Core, it seamlessly loads all secrets from Key Vault into the familiar configuration system.
- Direct Access with
Next Steps
We've seen how DefaultAzureCredential magically authenticates you as a developer. But how does it work when the application is deployed to Azure with no developer logged in? The answer is Managed Identities.
In the next module, we will dive deep into Managed Identities. You will learn the difference between system-assigned and user-assigned identities and enable one for an App Service, allowing it to authenticate to Key Vault and other Azure services securely and automatically, without any credentials stored in your app's configuration.