To access an Azure Key Vault secret from your code, you must register your key vault as an application.
The steps are:
- Create the key vault
- Register the application with Azure Active Directory
- Add a Client Secret to the App Registration
- Add an Access Policy to the Key Vault
- Set Environment Variables
- Write the code
Create the key vault
First, you need to create a Key Vault in which to store your secrets. For instructions on how to create a Key Vault, see this article.
Register the application with Azure Active Directory
After creating a Key Vault, register the Key Vault with Azure Active Directory.
This article shows how to do this.
For our purposes, the most important pieces of information from the Application Registration are the Application ID, which is sometimes called the Client ID.
You can find this on the Azure Active Directory "App registrations" blade. Search for your App Registration by name, as shown in Fig. 1.
Record the Display name, the Application (client) ID) and the Directory (tenant) ID. You will need these later.
Add a Client Secret to the App Registration
Next, you will need to create a Client Secret within your Application Registration.
Within the App Registration, click the [Certificates & secrets] button (Fig. 2) to open the "Certificates & secrets" blade, as shown in Fig. 3
To create a Client Secret, select the "Client secrets" tab and click the [New client secret] button (Fig. 4) to open the "Add a client secret" dialogue, as shown in Fig. 5.
At the "Description" field, enter a description of the secret (e.g., for which application are we generating a secret).
At the "Expires" dropdown, select how soon this secret will expire, requiring you to generate a new one.
When you finish completing the dialogue, click the [Add] button (Fig. 6) to return to the Application Registration" page, as shown in Fig. 7.
Your newly created secret will display in the list on the "Client secrets" tab. Copy and save the "Value" column. After you navigate away from this page, you will no longer be able to view the Value.
Add an Access Policy to the Key Vault
An Access Policy tells Azure which users, applications, and services have access to Azure Key Vault and what actions they can take on the information stored in Key Vault. After you have registered the application, you will need to create an Access Policy in Azure Key Vault, providing the Application Registration access to the key vault.
To add an Azure Key Vault Access Policy, navigate to the Azure Portal, log in, and open the Azure Key Vault, as shown in Fig. 2.
Click the [Access policies] button (Fig. 3) in the left menu to display the "Access Policies" blade, as shown in Fig. 4.
Click the [Add Access Policy] button (Fig. 5) to display the "Add access policy" dialogue, as shown in Fig. 6.
This dialogue provides a number of templates which preselect permissions to access and manage keys, secrets, and certificates in this Azure Key Vault. If you like, you can select one of these, as shown in Fig. 7.
Alternatively, you can specify each permission explicitly for keys, secrets, and certificates in this key vault. Fig. 8 shows how to select all permissions for managing secrets, which I will do for this demo.
When you have selected all the desired permissions, click the [Add] button (Fig. 8) to return to the "Add access policy" dialogue.
The next step is to give these permissions to the Application Registration. Click the link next to "Select principal" to open the "Principal" dialogue, as shown in Fig. 9.
Search for the Application Registration by display name, select the Registration from the list, as shown in Fig. 10 and click the [Select] button to close the "Principal" dialogue and return to the "Add Access Policy" dialogue, as shown in Fig. 11.
Finally, click the [Save] button (Fig. 12) to close the "Principal" dialogue and return to the "Access Policies" blade, as shown in Fig. 13. You will lose your changes if you fail to click the [Save] button before navigating
Set Environment Variables
The sample application below uses the DefaultAzureCredential class to authenticate the user. This class pulls information from the following environment variables:
- AZURE_CLIENT_ID (from App Registration "Overview" blade)
- AZURE_CLIENT_SECRET (from App Registration "Certificates & secrets" blade, "Value" field)
- AZURE_TENANT_ID (from App Registration "Overview" blade)
The values for each of these fields were acquired in the steps above.
Write the code
In a .NET Core application, the following NuGet packages assist you when working with Azure Key Vault.
- Azure.Security.KeyVault.Secret
- Azure.Identity
Create a new Console Application in Visual Studio and install the Azure.Security.KeyVault.Secrets and Azure.Identity NuGet packages.
As stated above, we can use the DefaultAzureCredential class to represent the principal used to make calls to our Azure Key Vault and the information (AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID) are stored in environment variables.
We create a DefaultAzureCredential object with the following code:
var credentials = new DefaultAzureCredential();
Then, we use this object to create a SecretClient object, as in the code below.
secretClient = new SecretClient(new Uri(keyVaultUri), credentials);
The SecretClient object provides methods to access and manage our Key Vault secrets.
For instance, we can get information about all the secrets in our Key
The following code retrieves information on all secrets in the Key Vault and lists the name, value, and content type of each
Console.WriteLine("All Secrets:"); var allSecrets = secretClient.GetPropertiesOfSecrets(); foreach (var secret in allSecrets) { var secretValue = secretClient.GetSecret(secret.Name); Console.WriteLine($"{secret.Name} | {secretValue.Value.Value} | {secretValue.Value.Properties.ContentType}"); } Console.WriteLine();
Other SecretClient methods allow us to get, set, or delete a Secret, as shown in the following code snippets:
await secretClient.SetSecretAsync(setSecretName, setSecretValue); var secret = secretClient.GetSecret(setSecretName); var operation = secretClient.StartDeleteSecret(deleteSecretName);
By default, Azure Key Vault supports soft delete, meaning that a deleted object can be retrieved for a given period after deletion (90 days, by default).
To permanently delete a secret prior to this, we can issue a purge command after the soft delete has completed. We can determine when the soft delete has completed by querying the Boolean DeleteSecretOperation.HasCompleted property.
if (operation.HasCompleted)
{
secretClient.PurgeDeletedSecret(purgeSecretName);
}
Below is the full code of a .NET Core Console application
using Azure.Identity; using Azure.Security.KeyVault.Secrets; using System; using System.Threading; using System.Threading.Tasks; namespace testKeyVaultConsoleApp { internal class Program { const string KEYVALUTNAME = "dgtestkeyvault"; // Set this to the name of your key vault static string keyVaultUri = $"https://{KEYVALUTNAME}.vault.azure.net"; static SecretClient secretClient = null; static async Task Main(string[] args) { var credentials = new DefaultAzureCredential(); secretClient = new SecretClient(new Uri(KEYVAULTURI), credentials); ListAllSecrets(); Console.Write("Input the Secret name to set (ENTER to skip):"); var setSecretName = Console.ReadLine(); if (setSecretName != "") { Console.Write("Input the Secret value to set:"); var setSecretValue = Console.ReadLine(); Console.WriteLine("Setting secret..."); await secretClient.SetSecretAsync(setSecretName, setSecretValue); Console.WriteLine($"Secret {setSecretName} set to {setSecretValue}!"); // Set content type var secret = secretClient.GetSecret(setSecretName); secret.Value.Properties.ContentType = "Demo Type"; secretClient.UpdateSecretProperties(secret.Value.Properties); } Console.Write("Input a Secret Name to soft delete (ENTER to skip):"); var deleteSecretName = Console.ReadLine(); if (deleteSecretName != "") { var operation = secretClient.StartDeleteSecret(deleteSecretName); Console.Write($"Deleting secret {deleteSecretName}..."); while (!operation.HasCompleted) { Thread.Sleep(1000); Console.Write($"."); operation.UpdateStatus(); } Console.WriteLine(); Console.WriteLine($"Secret {deleteSecretName} deleted!"); } Console.Write("Input a Secret Name to permanently delete (ENTER to skip):"); var purgeSecretName = Console.ReadLine(); if (purgeSecretName != "") { var operation = secretClient.StartDeleteSecret(purgeSecretName); Console.Write($"Soft deleting secret {purgeSecretName}..."); while (!operation.HasCompleted) { Thread.Sleep(1000); Console.Write($"."); operation.UpdateStatus(); } Console.WriteLine(); Console.WriteLine($"Secret {purgeSecretName} deleted!"); secretClient.PurgeDeletedSecret(purgeSecretName); Console.WriteLine($"Secret {purgeSecretName} purged!"); } ListAllSecrets(); Console.WriteLine(); Console.WriteLine("Done!"); } private static void ListAllSecrets() { Console.WriteLine("All Secrets:"); var allSecrets = secretClient.GetPropertiesOfSecrets(); foreach (var secret in allSecrets) { var secretValue = secretClient.GetSecret(secret.Name); Console.WriteLine($"{secret.Name} | {secretValue.Value.Value} | {secretValue.Value.Properties.ContentType}"); } Console.WriteLine(); } } }
You can find the code here.
NOTE: Visual Studio reads Environment Variables on launch, so it may be necessary to restart Visual Studio after you set the environment variables.
Conclusion
In this article, you learned how to create a Key Vault and manage its secrets from a .NET Console application.