Warning
The Azure Key Vault Emulator should not be used in production environments. It is not a replacement for Azure Key Vault, it just makes developing applications using Azure Key Vault much easier.
- Full Azure SDK Client support; use
SecretClient,KeyClientorCertificateClientas normal. - Destroy all secrets between sessions, or keep a persisted database.
- Works standalone with Docker, easy integration with .NET Aspire.
- TestContainers Module.
- Fully supported in all CI/CD pipelines and DevOps platforms.
You can find sample applications here or you can read the full launch blog post here!
The setup process can be fully automated by using the installation script:
bash <(curl -fsSL https://raw.githubusercontent.com/james-gould/azure-keyvault-emulator/refs/heads/master/docs/setup.sh)
Important
If you're using Windows, use wsl -u root to execute the setup script.
Alternatively you can download a copy of setup.sh and run it locally, or read the long form, manual set up docs.
The script is interactive and will create the necessary SSL certificates, install them to your User trust store and provide the commands to run the container. Once configured, you can start the Emulator with:
docker run -d -p {host-port}:4997 -v {/host/path/to/certs}:/certs -e Persist=true jamesgoulddev/azure-keyvault-emulator:latest
A break down of the command:
| Command | Description | Optional? |
|---|---|---|
-d |
Runs the container in detatched mode. |
âś… |
-p {host-port}:4997 |
Specifies the port to run on. The host port is configurable, but must map to container port 4997. |
âś… |
-v {/host/path/to/certs}:/certs |
Binds the directory containing the SSL PFX and CRT files, required for the Azure SDK. |
❌ |
-e Persist=true |
Instructs the emulator to create an SQLite database, written to your mounted volume/directory alongside the certificate files. |
âś… |
jamesgoulddev/azure-keyvault-emulator:latest |
The container image name and tag. Always use latest. |
❌ |
You can read more about configuration here.
1. Install the AzureKeyVaultEmulator.Aspire.Hosting package into your AppHost project:
dotnet add package AzureKeyVaultEmulator.Aspire.Hosting
var keyVaultServiceName = "keyvault"; // Remember this string, you'll need it to get the vaultUri!
// With existing resource, requires Azure configuration in your AppHost
var keyVault = builder
.AddAzureKeyVault(keyVaultServiceName)
.RunAsEmulator(); // Add this line
// Or directly add the emulator as a resource, no configuration required
var keyVault = builder.AddAzureKeyVaultEmulator(keyVaultServiceName);
var webApi = builder
.AddProject<Projects.MyApi>("api")
.WithReference(keyVault); // reference as normalYou can also toggle on persisted data, which creates an emulator.db loaded at runtime and updated in real-time.
var keyVaultServiceName = "keyvault";
var keyVault = builder
.AddAzureKeyVault(keyVaultServiceName)
.RunAsEmulator(new KeyVaultEmulatorOptions { Persist = true }); // Add this optionRead more about configuration here.
This can be done easily by installing the AzureKeyVaultEmulator.Client package:
dotnet add package AzureKeyVaultEmulator.Client
And then inject your clients:
// Injected by Aspire using the name "keyvault".
var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
// Basic Secrets only implementation
builder.Services.AddAzureKeyVaultEmulator(vaultUri);
// Or configure which clients you need to use
builder.Services.AddAzureKeyVaultEmulator(vaultUri, secrets: true, keys: true, certificates: false);Or if you don't want to introduce a new dependency you can achieve the same behaviour with ClientOptions.
Setting up a SecretClient for example:
// Injected by Aspire using the name "keyvault".
var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
// Allows "localhost" to be used instead of "<vault-name>.vault.azure.net" as the vaultUri
var options = new SecretClientOptions { DisableChallengeResourceVerification = true };
// Inject a SecretClient into your DI container which doesn't validate the VaultUri
builder.Services.AddTransient(s => new SecretClient(new Uri(vaultUri), new DefaultAzureCredential(), options));You can use this code from the client library replacing EmulatedCredential with DefaultAzureCredential.
private SecretClient _secretClient;
public SecretsController(SecretClient secretClient)
{
_secretClient = secretClient;
}
public async Task<string> GetSecretValue(string name)
{
var secret = await _secretClient.GetSecretAsync(name);
return secret.Value;
}Optional, if you're using the AzureKeyVaultEmulator.Client package
Configure your Program.cs to optionally inject the emulated or real Azure Key Vault clients depending on your current execution environment:
var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
if(builder.Environment.IsDevelopment())
builder.Services.AddAzureKeyVaultEmulator(vaultUri, secrets: true, certificates: true, keys: true);
else
builder.Services.AddAzureClients(client =>
{
var asUri = new Uri(vaultUri);
client.AddSecretClient(asUri);
client.AddKeyClient(asUri);
client.AddCertificateClient(asUri);
});There is a readily available TestContainers module too, which fully supports all CI/CD pipelines.
The same testing setup can be used in your local environment and CI/CD pipelines, no need to set flags or configuration.
using AzureKeyVaultEmulator.TestContainers;
// Create container with certificate directory and persistence
await using var container = new AzureKeyVaultEmulatorContainer();
// Start the container
await container.StartAsync();
// Get a AzureSDK KeyClient configured for the container
var keyClient = container.GetKeyClient();
// Get a AzureSDK SecretClient configured for the container
var secretClient = container.GetSecretClient();
// Get a AzureSDK CertificateClient configured for the container
var certificateClient = container.GetCertificateClient();
// Use as normal
var secret = await secretClient.SetSecretAsync("mySecretName", "mySecretValue");You can see more examples here for various test frameworks and scenarios.
The Azure Key Vault Emulator is now stable and ready for public consumption, however maintenance and enhancement work will continue to ensure the longevity of the project. Below you can find previous and upcoming additions to the project, if you'd like to see something added please raise a feature request.
Updates to the Azure Key Vault Emulator API will follow releases announced by Microsoft here.
- Management UI, similar to the Azure Portal UI. (#195)
- Introduction of the full API for Azure Key Vault:
- Secrets
- Keys
- Certificates
- Managed HSM
- Separate NuGet package for introducing an emulated Key Vault into your .NET Aspire projects.
- Separate NuGet package for easy usage of the emulator in client applications.
- Optional vault data persistence and importing for dev environment distribution. (#196)
- Automated environment + Docker setup script, and documentation updated to reflect it.
- TestContainers module. (#158)