KeyVaultReferenceResolver 1.1.0
dotnet add package KeyVaultReferenceResolver --version 1.1.0
NuGet\Install-Package KeyVaultReferenceResolver -Version 1.1.0
<PackageReference Include="KeyVaultReferenceResolver" Version="1.1.0" />
<PackageVersion Include="KeyVaultReferenceResolver" Version="1.1.0" />
<PackageReference Include="KeyVaultReferenceResolver" />
paket add KeyVaultReferenceResolver --version 1.1.0
#r "nuget: KeyVaultReferenceResolver, 1.1.0"
#:package KeyVaultReferenceResolver@1.1.0
#addin nuget:?package=KeyVaultReferenceResolver&version=1.1.0
#tool nuget:?package=KeyVaultReferenceResolver&version=1.1.0
๐ KeyVaultReferenceResolver
Seamlessly resolve Azure Key Vault secrets in your .NET configuration โ using the same format as Azure App Service.
โจ Why KeyVaultReferenceResolver?
When deploying to Azure App Service, you can reference Key Vault secrets directly in your configuration using the @Microsoft.KeyVault(SecretUri=...) syntax. But what about local development? What about running in Docker, Kubernetes, or other environments?
KeyVaultReferenceResolver bridges that gap. Use the exact same configuration files everywhere โ no environment-specific transforms, no code changes, no friction.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ appsettings.json โ
โ โโโโโโโโโโโโโโโโโ โ
โ "ConnectionString": "@Microsoft.KeyVault(SecretUri=https:// โ
โ myvault.vault.azure.net/secrets/db-conn)" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ KeyVaultReferenceResolver โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โข Detects Key Vault references โ
โ โข Authenticates via Azure Identity โ
โ โข Resolves secrets automatically โ
โ โข Caches for performance โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application โ
โ โโโโโโโโโโโโโโโโ โ
โ config["ConnectionString"] โ
โ โ "Server=prod.db;Password=..." โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ Quick Start
Installation
dotnet add package KeyVaultReferenceResolver
Basic Usage
using KeyVaultReferenceResolver;
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddKeyVaultReferenceResolver() // โ Just add this line
.Build();
// That's it! Secrets are resolved automatically.
var connectionString = configuration["ConnectionStrings:Database"];
ASP.NET Core
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddKeyVaultReferenceResolver(options =>
{
// Fail fast in production, be lenient in development
options.ThrowOnResolveFailure = builder.Environment.IsProduction();
});
var app = builder.Build();
๐ Configuration Format
Use the standard Azure App Service Key Vault reference format:
{
"ConnectionStrings": {
"Database": "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/db-connection)",
"Redis": "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/redis-conn)"
},
"ExternalServices": {
"ApiKey": "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/api-key/v1)"
},
"RegularSetting": "This stays as-is"
}
| Format | Example |
|---|---|
| Latest version | https://vault.vault.azure.net/secrets/my-secret |
| Specific version | https://vault.vault.azure.net/secrets/my-secret/abc123def456 |
๐ Authentication
KeyVaultReferenceResolver uses DefaultAzureCredential by default, which automatically works with:
| Environment | Authentication Method |
|---|---|
| Local Development | Azure CLI, Visual Studio, VS Code, PowerShell |
| Azure App Service | Managed Identity |
| Azure VMs | Managed Identity |
| Azure Kubernetes | Workload Identity |
| CI/CD Pipelines | Service Principal (env vars) |
| Docker/Kubernetes | Service Principal or Managed Identity |
Custom Credentials
// Managed Identity (User-Assigned)
builder.AddKeyVaultReferenceResolver(
new ManagedIdentityCredential("client-id-here"));
// Service Principal
builder.AddKeyVaultReferenceResolver(options =>
{
options.Credential = new ClientSecretCredential(
tenantId: "...",
clientId: "...",
clientSecret: "...");
});
// Chained credentials (try multiple in order)
builder.AddKeyVaultReferenceResolver(
new ChainedTokenCredential(
new ManagedIdentityCredential(),
new AzureCliCredential()));
โ๏ธ Configuration Options
builder.AddKeyVaultReferenceResolver(options =>
{
// ๐จ Throw on failure (default: false)
// Set to true in production to fail fast
options.ThrowOnResolveFailure = true;
// โฑ๏ธ Timeout per secret (default: 30 seconds)
options.Timeout = TimeSpan.FromSeconds(60);
// ๐พ Cache resolved secrets (default: true)
// Improves performance, secrets resolved once at startup
options.EnableCaching = true;
// ๐ Custom credential (default: DefaultAzureCredential)
options.Credential = new DefaultAzureCredential();
});
๐ Logging
Get visibility into what's happening:
var loggerFactory = LoggerFactory.Create(builder =>
builder.AddConsole().SetMinimumLevel(LogLevel.Debug));
builder.AddKeyVaultReferenceResolver(
options: new KeyVaultReferenceResolverOptions(),
logger: loggerFactory.CreateLogger("KeyVault"));
Sample output:
info: KeyVault[0] Resolved Key Vault reference: ConnectionStrings:Database
info: KeyVault[0] Resolved Key Vault reference: ExternalServices:ApiKey
info: KeyVault[0] Resolved 2 Key Vault reference(s)
๐งช Testing
Use the built-in MockSecretResolver for unit tests:
[Fact]
public void Configuration_ResolvesSecrets_FromMock()
{
// Arrange
var mockResolver = new MockSecretResolver()
.AddSecret(
"https://myvault.vault.azure.net/secrets/db-conn",
"Server=localhost;Database=TestDb")
.AddSecret(
"https://myvault.vault.azure.net/secrets/api-key",
"test-api-key-12345");
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["Database"] = "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/db-conn)",
["ApiKey"] = "@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/api-key)"
})
.AddKeyVaultReferenceResolver(mockResolver)
.Build();
// Act & Assert
Assert.Equal("Server=localhost;Database=TestDb", configuration["Database"]);
Assert.Equal("test-api-key-12345", configuration["ApiKey"]);
}
MockSecretResolver Features
// Fluent API
var mock = new MockSecretResolver()
.AddSecret("uri1", "value1")
.AddSecret("uri2", "value2");
// Bulk add
mock.AddSecrets(new Dictionary<string, string>
{
["uri3"] = "value3",
["uri4"] = "value4"
});
// Silent mode (returns empty string instead of throwing)
var silentMock = new MockSecretResolver(secrets, throwOnMissing: false);
// Inspection
bool exists = mock.ContainsSecret("uri1");
int count = mock.Count;
mock.Clear();
๐ ๏ธ Utility Methods
using KeyVaultReferenceResolver;
// Check if a value is a Key Vault reference
string value = "@Microsoft.KeyVault(SecretUri=https://...)";
bool isRef = KeyVaultReferenceResolverExtensions.IsKeyVaultReference(value);
// โ true
// Extract the secret URI
string? uri = KeyVaultReferenceResolverExtensions.ExtractSecretUri(value);
// โ "https://..."
๐ Security Best Practices
- Use Managed Identity in Azure โ No secrets to manage
- Enable
ThrowOnResolveFailurein production โ Fail fast if secrets can't be loaded - Use specific secret versions for critical configs โ Prevents unexpected changes
- Grant minimal permissions โ Only
Getpermission on secrets is required - Audit access โ Enable Key Vault logging in Azure
Required Key Vault Permissions
| Permission | Required |
|---|---|
secrets/get |
โ Yes |
secrets/list |
โ No |
secrets/set |
โ No |
๐๏ธ Architecture
KeyVaultReferenceResolver/
โโโ ISecretResolver.cs # Interface for DI/testing
โโโ KeyVaultSecretResolver.cs # Default Azure implementation
โโโ MockSecretResolver.cs # Testing mock
โโโ KeyVaultReferenceResolverExtensions.cs # IConfigurationBuilder extensions
โโโ KeyVaultReferenceResolverOptions.cs # Configuration options
โโโ KeyVaultReferenceResolutionException.cs # Custom exception
๐ Requirements
| Dependency | Version |
|---|---|
| .NET | 8.0+ |
| Azure.Identity | 1.13.1+ |
| Azure.Security.KeyVault.Secrets | 4.7.0+ |
| Microsoft.Extensions.Configuration | 8.0.0+ |
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
<p align="center"> <b>Stop juggling configuration transforms. Start shipping.</b> </p>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Azure.Identity (>= 1.13.1)
- Azure.Security.KeyVault.Secrets (>= 4.7.0)
- Microsoft.Extensions.Configuration (>= 8.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 8.0.2)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.1.0 | 559 | 12/9/2025 |