Azure Key Vault Emulator

repository·master·Indexed 43 days ago

https://github.com/james-gould/azure-keyvault-emulator

A development tool that mimics Azure Key Vault behavior locally, allowing developers to use standard Azure SDK clients like SecretClient, KeyClient, and CertificateClient without Azure costs or internet connectivity. Supports deployment via Docker and .NET Aspire, including a TestContainers module for automated testing and tools for managing required SSL certificates.

Tokens
10.8K
Snippets
31
Records
41
Agent score
55%

What's inside Azure Key Vault Emulator

  1. Certificate naming and password requirements

    master

    Due to current limitations in the Emulator, you cannot define custom names or passwords for the SSL certificates. You must adhere to the following constraints:

    • Certificate Name: Must be emulator.
    • Password: Must be emulator (specifically when generating emulator.pfx).
    • Files: You must generate both emulator.pfx (with password emulator) and emulator.crt.
  2. Why HTTPS is required for the Emulator

    master
    The Azure Client SDK enforces HTTPS (and thus requires valid SSL certificates) when checking the vaultUri. If certificates are not installed and trusted, connections from the SDK to the Emulator will timeout and throw an UntrustedRoot exception. Using plain HTTP is not a viable workaround for the Azure SDK.
  3. How SSL certificates are handled by the emulator

    master

    The Azure SDK requires a trusted SSL connection. By default, the module automates the following:

    1. Generation: Creates the required SSL certificates.
    2. Installation: Installs them to the User store as a Trusted Root CA.
      • Windows: You will be prompted to confirm the installation on the first run. This requires administration rights.
    3. Storage: Stores certificates in the host machine's local user area for reuse.

    Storage Locations:

    • Windows: C:/Users/{name}/keyvaultemulator/certs/
    • Unix: /usr/local/keyvaultemulator/certs/

    Manual Certificate Provisioning: If you disable automatic generation, you must provide certificates with these constraints:

    • Filename: emulator.pfx (and emulator.crt for *NIX hosts).
    • Password: Must be exactly emulator.
  4. Use the Emulator in client applications

    master

    To consume the emulator in your application, you can either use the helper library or configure the standard Azure SDK clients manually.

    Install the client package:

    dotnet add package AzureKeyVaultEmulator.Client

    Then inject the clients in your Program.cs. The library automatically retrieves the vaultUri from your connection strings (e.g., the one provided by Aspire).

    var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
    
    // Basic implementation (Secrets only)
    builder.Services.AddAzureKeyVaultEmulator(vaultUri);
    
    // Or specify required services
    builder.Services.AddAzureKeyVaultEmulator(vaultUri, secrets: true, keys: true, certificates: false);

    Option 2: Manual Configuration (No extra dependency)

    If you prefer not to add the client library, you must manually configure ClientOptions to allow the use of localhost instead of a valid Azure domain.

    var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
    
    // Disable verification to allow emulated URIs
    var options = new SecretClientOptions { DisableChallengeResourceVerification = true };
    
    builder.Services.AddTransient(s => new SecretClient(
        new Uri(vaultUri), 
        new DefaultAzureCredential(), 
        options));
    dotnet add package AzureKeyVaultEmulator.Client
    
    // In Program.cs
    var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
    builder.Services.AddAzureKeyVaultEmulator(vaultUri, secrets: true, keys: true, certificates: true);
  5. Configure AzureKeyVaultEmulatorContainer for CI/CD environments

    master

    In CI/CD environments like GitHub Actions, it is recommended to provide a specific path for certificate storage to ensure a clean, ephemeral environment. You can pass a path (such as the system's temporary directory) to the AzureKeyVaultEmulatorContainer constructor. The container will automatically generate the necessary certificates in that directory.

    using AzureKeyVaultEmulator.TestContainers;
    
    // Use system temp directory for CI/CD environments
    var certificatesPath = Path.GetTempPath();
    await using var container = new AzureKeyVaultEmulatorContainer(certificatesPath);
    
    // The container will automatically generate certificates in the temp directory
    await container.StartAsync();
    
    // Get an official AzureSDK SecretClient
    var client = container.GetSecretClient();
    
    // Use as normal
    var secret = await client.SetSecretAsync("ApiKey", "12345");
  6. Configure the Azure Key Vault Emulator client

    master

    To use the emulator, you must provide the vaultUri.

    • If using .NET Aspire: The URI is automatically populated in your appsettings.json under ConnectionStrings using the resource name (e.g., keyvault).
    • If using Docker directly: The default vault URI is https://localhost:4997.

    Use AddAzureKeyVaultEmulator to register the clients. By default, only SecretClient is registered. You can enable KeyClient and CertificateClient by passing boolean flags.

    // Injected by Aspire using the name "keyvault".
    var vaultUri = builder.Configuration.GetConnectionString("keyvault") ?? string.Empty;
    
    // Basic Secrets only implementation
    builder.Services.AddAzureKeyVaultEmulator(vaultUri);
    
    // Enabling specific client types
    builder.Services.AddAzureKeyVaultEmulator(vaultUri, secrets: true, keys: true, certificates: false);
  7. Configure Azure Key Vault Emulator with .NET Aspire

    master

    When using .NET Aspire, the AzureKeyVaultEmulator.Aspire.Hosting library handles SSL certificate creation and installation automatically. On the first run, you will be prompted to install a localhost certificate; click Yes to install it to your local user trusted authority store.

    To customize the emulator behavior, you can provide a configuration section (e.g., via User Secrets) or pass a KeyVaultEmulatorOptions object to the RunAsEmulator method.

    // Using a configuration section from User Secrets
    var keyVault = builder
        .AddAzureKeyVault("myLocalKeyVault")
        .RunAsEmulator(configSectionName: "KeyVaultEmulator");
    
    // OR passing options directly as an object
    var keyVault = builder
        .AddAzureKeyVault(AspireConstants.EmulatorServiceName)
        .RunAsEmulator(new KeyVaultEmulatorOptions
        {
            Persist = true,
            Port = 4997,
            LocalCertificatePath = "C:/Users/MyName/keyvaultemulator/certs",
            LoadCertificatesIntoTrustStore = false,
            ShouldGenerateCertificates = false,
            Lifetime = ContainerLifetime.Persistent,
            ForceCleanupOnShutdown = false,
            UseDotnetDevCerts = false
        });
  8. Use the AzureKeyVaultEmulatorContainer for basic usage

    master

    The AzureKeyVaultEmulatorContainer class allows you to spin up an instance of the Azure Key Vault Emulator using TestContainers. You can start the container and then retrieve pre-configured Azure SDK clients (KeyClient, SecretClient, or CertificateClient) that are automatically pointed to the emulator instance.

    To use it, instantiate the container, call await container.StartAsync(), and then use one of the Get...Client() methods to obtain a client for your application logic.

    using AzureKeyVaultEmulator.TestContainers;
    
    // Create container with certificate directory and persistence
    await using var container = new AzureKeyVaultEmulatorContainer();
    
    // Start the container
    await container.StartAsync();
    
    // Get configured AzureSDK clients
    var keyClient = container.GetKeyClient();
    var secretClient = container.GetSecretClient();
    var certificateClient = container.GetCertificateClient();
    
    // Use as normal
    var secret = await secretClient.SetSecretAsync("mySecretName", "mySecretValue");
  9. Authenticate with DefaultAzureCredential in Aspire

    master

    If your application uses Azure.Identity.DefaultAzureCredential, you can automate the credential wiring in your AppHost using WithAzureKeyVaultEmulatorCredentials. This automatically handles credentials, tenant, and authority.

    AppHost Configuration

    var keyVault = builder.AddAzureKeyVaultEmulator("keyvault");
    
    builder.AddProject<Projects.MyApi>("api")
        .WithAzureKeyVaultEmulatorCredentials(keyVault)
        .WithReference(keyVault);

    Consumer (Client) Configuration

    On the client side, you must adjust your DefaultAzureCredentialOptions and ClientOptions to allow local/emulated connections:

    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        DisableInstanceDiscovery = true,
    });
    
    builder.Services.AddSingleton(_ => new SecretClient(
        new Uri(vaultUri),
        credential,
        new SecretClientOptions { DisableChallengeResourceVerification = true }));
    // AppHost
    var keyVault = builder.AddAzureKeyVaultEmulator("keyvault");
    builder.AddProject<Projects.MyApi>("api")
        .WithAzureKeyVaultEmulatorCredentials(keyVault)
        .WithReference(keyVault);
    
    // Client
    var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
    {
        DisableInstanceDiscovery = true,
    });
    
    builder.Services.AddSingleton(_ => new SecretClient(
        new Uri(vaultUri),
        credential,
        new SecretClientOptions { DisableChallengeResourceVerification = true }));
  10. Automate certificate creation with the setup script

    master

    The easiest way to set up the required HTTPS and trusted SSL certificates for the Azure Key Vault Emulator is to use the provided installation script. This automates the generation and installation process.

    Important for Windows users: You must execute this script using Git Bash or wsl -u root to ensure it runs correctly.

    bash <(curl -fsSL https://raw.githubusercontent.com/james-gould/azure-keyvault-emulator/refs/heads/master/docs/setup.sh)
  11. Integrate the Emulator with .NET Aspire

    master

    To use the emulator within a .NET Aspire application, follow these steps:

    1. Install the Hosting Package

    Add the AzureKeyVaultEmulator.Aspire.Hosting package to your AppHost project:

    dotnet add package AzureKeyVaultEmulator.Aspire.Hosting

    2. Configure the Resource in AppHost

    You can either override an existing Azure Key Vault resource or add the emulator directly:

    // Option A: Override an existing resource
    var keyVault = builder.AddAzureKeyVault("keyvault").RunAsEmulator();
    
    // Option B: Add directly (no Azure config required)
    var keyVault = builder.AddAzureKeyVaultEmulator("keyvault");
    
    // Reference it in your projects
    var webApi = builder.AddProject<Projects.MyApi>("api").WithReference(keyVault);

    3. Enable Data Persistence (Optional)

    To keep secrets, keys, and certificates between runs, enable Persist. Note: When using Persist, you MUST specify a fixed Port because Aspire's default random port assignment will break the vault URI baked into the persisted database.

    var keyVault = builder
        .AddAzureKeyVault("keyvault")
        .RunAsEmulator(new KeyVaultEmulatorOptions { Persist = true, Port = 4997 });
    dotnet add package AzureKeyVaultEmulator.Aspire.Hosting
    
    // In AppHost
    var keyVault = builder.AddAzureKeyVaultEmulator("keyvault");
    builder.AddProject<Projects.MyApi>("api").WithReference(keyVault);