In this article, let’s create a .NET console application to create and retrieve secrets from Azure Key Vault using .NET Client Library. Azure Key Vault is a Azure cloud service which provides secure storage and retrieval of various secrets. Secrets can be passwords, encryption keys, certificates for the applications and services, etc. After this exercise one will be able to create and retrieve secrets using .NET Client Library along with creation of Azure key vault resource using Azure CLI and assignment of role to Microsoft Entra (Azure AD) user name.
Following tasks are performed:
Create Azure Key Vault resources using Azure CLI.
Assign role to Microsoft Entra (Azure AD) user name using Azure CLI.
Create and retrieve secrets using .NET Client Library.
Sign in to Azure and run application.
Clean up resources.
Create Azure Key Vault resource using Azure CLI
Initial task is to create and make ready Azure Key Vault resources using Azure CLI (Azure Cloud Shell) for further usage. Click Cloud Shell button on the menu bar at the top right side of the Azure portal. It will launch an interactive shell which can be used to run the steps outlined in this article. Select a Bash environment. To use code editor In cloud shell toolbar go to Settings menu and than select Go to Classic version.
Create resource group
Resource group is logical container used to hold related resources. It includes resources which required to manage as a group. Key Vault belongs to a resource group. az group create command used to create a group.
az group create \
--name myResourceGroup2 \
--location eastus2
eastus2 is location code instead of it one can use their nearest region location.
Create Azure Key Vault resource
Once resource group is created next task is to create a Azure Key Vault resource that will be used in next section. az keyvault create command is used to create a Azure key value resource. It will take few minutes to complete the process.
az keyvault create \
--name myKeyVaultName2\
--resource-group myResourceGroup2\
--location eastus2 \
Assign role to Microsoft Entra (Azure AD) user name
It is important to assign roles to Microsoft Entra (Azure AD) user name. Roles will define what access and permissions a user has within an organization’s Microsoft cloud environment. Roles determine what resources and actions a user can perform. One by one perform below steps in Azure CLI.
Retrieve userPrincipalName
First, retrieve userPrincipalName from account as mentioned in following command. It retrieves the information about currently authenticated user including their UPN and represents that who the role will be assigned to.
userPrincipal2=$(az rest
--method GET
--url https://graph.microsoft.com/v1.0/me \
--headers 'Content-Type=application/json' \
--query userPrincipalName
--output tsv)
Retrieve resource ID
Second, get the resource ID of key vault using below command. This will be used in next step to set the scope for role assignment. Resource ID sets scope for role assignment to specific key vault.
resourceID2=$(az keyvault show \
--resource-group myResourceGroup2 \
--name myKeyVaultName2 \
--query id \
--output tsv)
Create and assign Key Vault Secrets Officer role
Finally, let's create and assign key vault secrets officer role using az role assignment create command. It will give permissions to manage next routines. userPrincipal and resourceID variables are created in first and second steps as above which are used in this command to retrieve actual value at command execution time.
az role assignment create \
--assignee $userPrincipal2\
--role "Key Vault Secrets Officer" \
--scope $resourceID2
Key Vault Secrets Officer role: It is to be assigned to Microsoft Entra user before create and retrieve secret. It gives permissions to create, retrieve and delete secrets to user account i.e. it allows to create and read actions.
Key Vault Secrets User role: It allows to read action only.
Now, required basic resources are deployed and ready to use. So, let's create a .NET console app.
Create and retrieve secrets using .NET Client Library
Let’s set-up the .NET console application to create and retrieve the secrets from Azure Key Vault using .NET Client Library. Perform the following steps one by one in to Cloud Shell to achieve this.
.NET Project Setup
Set up a console project to add and fetch secrets using .NET Client Library.
mkdir keyvault2
cd keyvault2
dotnet new console
dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets
Starter code
Add the below starter code into the project and replace template code in Program.cs file by using editor in Cloud Shell.
code Program.cs
using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
// Replace KEYVAULT-NAME with actual Key Vault name
string keyVaultUrl = "https://KEYVAULT-NAME.vault.azure.net/";
// CREATE - CLIENT
// CREATE - MENU OPTIONS
// LIST - SECRETS
// CREATE - SECRET
Complete code
Add following code one by one at mentioned commented section to complete the application. Let’s update the code for commented lines for specific operations one by one as described to create client, add menu options, list out secrets, and add secretes to key vault.
Create Client - First create an instance of SecretClient class to add and fetch secrets using it. This class is main starting point to perform all the operations against Key Vault. Locate // CREATE CLIENT comment, then add following code directly beneath comment. KEYVAULT-NAME will be actual key value. DefaultAzureCredentialOptions configures authentication options. SecretClient creates Key Vault client
// CREATE - CLIENT
// Configure authentication options to connect with Azure Key Vault
DefaultAzureCredentialOptions defaultAzureCredentialOptions = new()
{
ExcludeEnvironmentCredential = true,
ExcludeManagedIdentityCredential = true
};
// Create Key Vault client through URL and authentication credentials
var secretClient = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential(defaultAzureCredentialOptions));
// CREATE - MENU OPTIONS
// Run application continues until user enters 3 to exit
while (true)
{
// Display options
Console.Clear();
Console.WriteLine("\n ..... Options .....");
Console.WriteLine("......................");
Console.WriteLine("1. List of Secrets");
Console.WriteLine("2. Create New Secret");
Console.WriteLine("3. Exit");
Console.WriteLine("......................");
Console.Write("Enter an option (1, 2, or 3): ");
// Read user option
string? inputOption = Console.ReadLine()?.Trim();
// Check user option to exit application
if (inputOption == "3")
{
Console.WriteLine("Exiting from application. Press any key to continue!");
Console.ReadLine();
break;
}
// Process user option
switch (inputOption)
{
case "1":
//call method to list out all secrets
await ListOfSecrets(secretClient);
break;
case "2":
//call method to create a new secret
await CreateNewSecret(secretClient);
break;
default:
//invalid option selection message
Console.WriteLine("Invalid option. Please enter 1, 2, or 3. Press any key to continue!");
Console.ReadLine();
break;
}
}
// LIST - SECRETS
async Task ListOfSecrets(SecretClient client)
{
try
{
Console.Clear();
Console.WriteLine("Listing of secrets in Key Vault");
Console.WriteLine("......................");
// Get all secret properties in Key Vault
bool secretExists = false;
var secretProperties = client.GetPropertiesOfSecretsAsync();
// Iterate with each secret property to get all secret information
await foreach (var secretProperty in secretProperties)
{
secretExists = true;
try
{
// Retrieve actual secret value and metadata
var secret = await client.GetSecretAsync(secretProperty.Name);
// Print secret details
Console.WriteLine($"Name is {secret.Value.Name}");
Console.WriteLine($"Value is {secret.Value.Value}");
Console.WriteLine($"Created on {secret.Value.Properties.CreatedOn}");
Console.WriteLine("......................");
}
catch (Exception ex)// Secrets exception handling
{
Console.WriteLine($"Error message '{secretProperty.Name}': {ex.Message}");
Console.WriteLine("......................");
}
}
// Print if no any secret exists
if (!secretExists)
{
Console.WriteLine("No any secret exists.");
}
}
catch (Exception ex)// General exception handling
{
Console.WriteLine($"Error message {ex.Message}");
}
Console.WriteLine("Press any key to continue!");
Console.ReadLine();
}
// CREATE - SECRET
async Task CreateNewSecret(SecretClient client)
{
try
{
Console.Clear();
Console.WriteLine("\nCreate new secret");
// Get secret name
Console.Write("Enter secret name: ");
string? secretName = Console.ReadLine()?.Trim();
// Get secret value
Console.Write("Enter secret value: ");
string? secretValue = Console.ReadLine()?.Trim();
// Check secret name and value for empty
if (string.IsNullOrEmpty(secretName) || string.IsNullOrEmpty(secretValue))
{
Console.WriteLine("Secret name or value couldn't be blank. Press any key to continue!");
Console.ReadLine();
return;
}
// Create a new secret using name and value
var secret = new KeyVaultSecret(secretName, secretValue);
// Store secret in Azure Key Vault
await client.SetSecretAsync(secret);
Console.WriteLine($"Secret '{secretName}' created successfully. Press any key to continue!");
Console.ReadLine();
}
catch (Exception ex)// Secrets exception handling
{
Console.WriteLine($"Error message {ex.Message}");
}
}
Sign into Azure and Run application
Now, application is ready to run. One by one execute the following commands in Azure CLI to run an application and perform the mentioned steps to verify the result outcomes.
az login
dotnet run
Clean up resources
Once finished the exercise it’s recommended to delete cloud resources are being created to avoid the unnecessary resource usage and any future costs. Deleting a resource group will delete all resources contained within it. Perform following steps one by one in to Azure Portal to achieve this:
Navigate to resource group which is being created here and view it’s contents.
Delete resource group selection from the toolbar.
Choose resource group name and then follow next directions to delete resource group and all the resources it contains.
One can also clean up resources using Azure CLI as following:
Delete role assignment - az role assignment delete command is used to remove role assignment.
az role assignment delete \
--role "Key Vault Secrets Officer" \
--scope $resourceID2
Delete key vault - az keyvault delete command is used to remove keyvault.
az keyvault delete \
--name myKeyVaultName2 \
--resource-group myResourceGroup2
Delete resource group - az group delete command is used to remove resource group and it's referenced items.
az group delete \
--name myResourceGroup2
Summary
Here, a complete process flow is described to create and retrieve secrets from Azure Key Vault using .NET Client Library. "Key Vault Secrets Officer" role is assigned to Microsoft Entra (Azure AD) user name. .NET project is created to create and retrieve the secrets using .NET Client Library DSK. Finally, resources are cleaned up. Here by with this article a complete code of Program.cs file is attached. Following it the list of key commands and classes/objects used in this article:
Commands
Create resource group: az group create
Create Azure Key Vault resource: az keyvault create
Create and assign Key Vault Secrets Officer role: az role assignment create
Create .NET console application: dotnet new console
Add packages: dotnet add package
Delete role assignment: az role assignment delete
Delete Key Vault: az keyvault delete
Delete resource group: az group delete
Classes or Objects
Configure authentication options: DefaultAzureCredentialOptions
Create Key Vault client: SecretClient
Get all secret properties in Key Vault: GetPropertiesOfSecretsAsync
Retrieve actual secret value and metadata: GetSecretAsync
Create a new secret using name and value: KeyVaultSecret
Store secret in Azure Key Vault: SetSecretAsync