Vault.Extension.Configuration
0.4.2
dotnet add package Vault.Extension.Configuration --version 0.4.2
NuGet\Install-Package Vault.Extension.Configuration -Version 0.4.2
<PackageReference Include="Vault.Extension.Configuration" Version="0.4.2" />
<PackageVersion Include="Vault.Extension.Configuration" Version="0.4.2" />
<PackageReference Include="Vault.Extension.Configuration" />
paket add Vault.Extension.Configuration --version 0.4.2
#r "nuget: Vault.Extension.Configuration, 0.4.2"
#:package Vault.Extension.Configuration@0.4.2
#addin nuget:?package=Vault.Extension.Configuration&version=0.4.2
#tool nuget:?package=Vault.Extension.Configuration&version=0.4.2
Vault.Extension.Configuration
A configuration extension for Microsoft.Extensions.Configuration that integrates with HashiCorp Vault using VaultSharp
Features
- 🔐 Multiple authentication methods: Local token, AWS IAM, or custom authentication
- ⚙️ Seamless integration with
Microsoft.Extensions.ConfigurationandIOptions<T> - 🔄 Immediate secret loading into configuration after build
- ✅ Fluent validation for configuration options
- 🏗️ Full dependency injection support with
IOptions,IOptionsSnapshot, andIOptionsMonitor - 🔌 Direct Vault access via
IVaultService
Installation
dotnet add package Vault.Extension.Configuration
Prerequisites
- .NET 8.0 or later
- Access to a HashiCorp Vault server
- Appropriate authentication credentials (token, AWS IAM role, or custom method)
Quick Start
Step 1: Configure Vault in your application
using Vault.Extentions;
using Vault.Options;
using Vault.Enum;
var builder = WebApplication.CreateBuilder(args);
// Register VaultService and load secrets immediately into configuration
builder.Services.AddVault(
builder.Configuration,
new VaultOptions
{
AuthenticationType = VaultAuthenticationType.Local,
Configuration = new VaultLocalConfiguration
{
VaultUrl = "https://vault.example.com",
MountPoint = "secret",
TokenFilePath = "~/.vault-token"
}
},
environment: "production");
var app = builder.Build();
// Secrets are already loaded and available - no additional initialization required!
app.Run();
Step 2: Use secrets in your application
You can access Vault secrets in three different ways:
Usage Examples
1. Using IConfiguration
Secrets are automatically loaded into the configuration system and can be accessed like any other configuration value:
public class MyController : ControllerBase
{
private readonly IConfiguration _configuration;
public MyController(IConfiguration configuration)
{
_configuration = configuration;
}
public IActionResult GetSecret()
{
// Access secrets directly from configuration
var dbPassword = _configuration["Database:Password"];
var apiKey = _configuration["ApiSettings:ApiKey"];
return Ok(new { hasPassword = !string.IsNullOrEmpty(dbPassword) });
}
}
2. Using IOptions Pattern
Bind Vault secrets to strongly-typed configuration classes:
// Define your configuration class
public class DatabaseSettings
{
public string ConnectionString { get; set; }
public string Password { get; set; }
public int Timeout { get; set; }
}
// In Program.cs
builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("Database"));
// Use in your services with IOptions (singleton-like behavior)
public class DatabaseService
{
private readonly DatabaseSettings _settings;
public DatabaseService(IOptions<DatabaseSettings> options)
{
_settings = options.Value;
}
public void Connect()
{
var connectionString = $"{_settings.ConnectionString};Password={_settings.Password}";
// Use connection string
}
}
// Use in your scoped services with IOptionsSnapshot (refreshed per scope/request)
public class ScopedDatabaseService
{
private readonly DatabaseSettings _settings;
public ScopedDatabaseService(IOptionsSnapshot<DatabaseSettings> optionsSnapshot)
{
_settings = optionsSnapshot.Value;
}
public void Connect()
{
var connectionString = $"{_settings.ConnectionString};Password={_settings.Password}";
// Use connection string - fresh value for each HTTP request
}
}
// Use IOptionsMonitor for real-time change notifications
public class MonitoredDatabaseService
{
private readonly IDisposable? _changeListener;
public MonitoredDatabaseService(IOptionsMonitor<DatabaseSettings> optionsMonitor)
{
// Get current value
var currentSettings = optionsMonitor.CurrentValue;
// Listen for changes
_changeListener = optionsMonitor.OnChange((newSettings, name) =>
{
Console.WriteLine("Database settings changed!");
});
}
}
3. Using IVaultService Directly
For dynamic secret retrieval at runtime:
using Vault.Abstractions;
public class SecretManager
{
private readonly IVaultService _vaultService;
public SecretManager(IVaultService vaultService)
{
_vaultService = vaultService;
}
// Get a single secret value
public async Task<string?> GetDatabasePasswordAsync()
{
var password = await _vaultService.GetSecretValueAsync("production", "Database:Password");
return password?.ToString();
}
// Get all secrets for an environment
public async Task<Dictionary<string, object>> GetAllSecretsAsync()
{
return await _vaultService.GetSecretsAsync("production");
}
// Get nested secret using dot notation
public async Task<string?> GetNestedSecretAsync()
{
var value = await _vaultService.GetNestedSecretValueAsync("production", "Api.Settings.Key");
return value?.ToString();
}
// List all available environments
public async Task<IEnumerable<string>> GetEnvironmentsAsync()
{
return await _vaultService.ListEnvironmentsAsync();
}
}
Authentication Methods
Local Token Authentication
Best for development environments:
var vaultOptions = new VaultOptions
{
AuthenticationType = VaultAuthenticationType.Local,
Configuration = new VaultLocalConfiguration
{
VaultUrl = "https://vault.example.com",
MountPoint = "secret",
TokenFilePath = "~/.vault-token",
IgnoreSslErrors = false // Set to true only in development
}
};
builder.Services.AddVault(builder.Configuration, vaultOptions, environment: "development");
AWS IAM Authentication
Ideal for production on AWS infrastructure:
var vaultOptions = new VaultOptions
{
AuthenticationType = VaultAuthenticationType.AWS_IAM,
Configuration = new VaultAwsConfiguration
{
VaultUrl = "https://vault.example.com",
MountPoint = "secret",
Environment = "production",
AwsAuthMountPoint = "aws",
AwsIamRoleName = "my-app-role" // Optional
}
};
builder.Services.AddVault(builder.Configuration, vaultOptions, environment: "production");
Custom Authentication
For AppRole, LDAP, UserPass, Kubernetes, etc.:
using VaultSharp.V1.AuthMethods.AppRole;
var vaultOptions = new VaultOptions
{
AuthenticationType = VaultAuthenticationType.Custom,
Configuration = new VaultDefaultConfiguration
{
VaultUrl = "https://vault.example.com",
MountPoint = "secret"
},
CustomAuthMethodInfo = new AppRoleAuthMethodInfo("my-role-id", "my-secret-id")
};
builder.Services.AddVault(builder.Configuration, vaultOptions, environment: "production");
Configuration Reference
VaultOptions
| Property | Type | Description |
|---|---|---|
IsActivated |
bool |
Enable/disable Vault integration (default: true) |
AuthenticationType |
VaultAuthenticationType |
Authentication method: Local, AWS_IAM, or Custom |
Configuration |
VaultDefaultConfiguration |
Base configuration (use specific subclass based on auth type) |
CustomAuthMethodInfo |
IAuthMethodInfo |
Custom authentication info (only for Custom type) |
VaultLocalConfiguration
| Property | Type | Description |
|---|---|---|
VaultUrl |
string |
Vault server URL (e.g., https://vault.example.com) |
MountPoint |
string |
Secret engine mount point (e.g., secret) |
TokenFilePath |
string |
Path to token file (supports environment variables like ~/.vault-token) |
IgnoreSslErrors |
bool |
Ignore SSL certificate errors (default: false, use only in development) |
VaultAwsConfiguration
| Property | Type | Description |
|---|---|---|
VaultUrl |
string |
Vault server URL |
MountPoint |
string |
Secret engine mount point |
Environment |
string |
Environment name (used for default role naming) |
AwsAuthMountPoint |
string |
AWS auth method mount point (default: "aws") |
AwsIamRoleName |
string |
AWS IAM role name (optional, defaults to {MountPoint}-{Environment}-role) |
IgnoreSslErrors |
bool |
Ignore SSL certificate errors |
IVaultService Methods
| Method | Description |
|---|---|
ListEnvironmentsAsync() |
Lists all available environments in the Vault |
GetSecretsAsync(string environment) |
Retrieves all secrets for a given environment |
GetSecretValueAsync(string environment, string key) |
Gets a specific secret value by key |
GetNestedSecretValueAsync(string environment, string path) |
Gets a nested secret using dot notation (e.g., "Level1.Level2.Key") |
Complete Example
Here's a complete example showing all three usage patterns:
using Vault.Extentions;
using Vault.Options;
using Vault.Enum;
using Vault.Abstractions;
var builder = WebApplication.CreateBuilder(args);
// 1. Configure Vault - secrets are loaded immediately into configuration
builder.Services.AddVault(
builder.Configuration,
new VaultOptions
{
AuthenticationType = VaultAuthenticationType.AWS_IAM,
Configuration = new VaultAwsConfiguration
{
VaultUrl = "https://vault.example.com",
MountPoint = "myapp",
Environment = "production"
}
},
environment: "production");
// 2. Register strongly-typed configuration
public class AppSettings
{
public string ApiKey { get; set; }
public string DatabasePassword { get; set; }
}
builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("AppSettings"));
// 3. Register your services
builder.Services.AddScoped<MyService>();
var app = builder.Build();
// No additional initialization required - secrets are already available!
app.MapGet("/config", (IConfiguration config) =>
new { apiKey = config["AppSettings:ApiKey"] });
app.MapGet("/options", (IOptions<AppSettings> options) =>
new { settings = options.Value });
app.MapGet("/vault", async (IVaultService vault) =>
await vault.GetSecretsAsync("production"));
app.Run();
Best Practices
- Environment-specific configuration: Use different Vault environments for development, staging, and production
- Secret naming: Use hierarchical naming with colons (e.g.,
Database:Password,Api:Settings:Key) - Error handling: Always handle cases where secrets might not exist
- SSL certificates: Never set
IgnoreSslErrors = truein production - Token security: Store Vault tokens securely and rotate them regularly
- IVaultService usage: Use
IVaultServicefor dynamic secret retrieval,IConfiguration/IOptionsfor startup configuration - Choose the right Options pattern:
- IOptions<T>: Use for singleton services or when you need consistent values throughout the application lifetime
- IOptionsSnapshot<T>: Use for scoped services (e.g., per HTTP request) to get fresh values each scope
- IOptionsMonitor<T>: Use when you need to react to configuration changes at runtime
Troubleshooting
Secrets not loading
Ensure the AddVault method is called with builder.Configuration (the configuration builder, not the built configuration):
// Correct - pass the configuration builder
builder.Services.AddVault(
builder.Configuration, // IConfigurationBuilder
vaultOptions,
environment: "production");
Authentication errors
- Local: Verify token file exists and has valid permissions
- AWS IAM: Ensure IAM role is properly configured and the application has AWS credentials
- Custom: Verify the custom auth method credentials are valid
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
See CONTRIBUTING.md for guidelines.
Template Information
<details> <summary>Click to expand template documentation</summary>
This project is based on Library.Template.
Build Features
- Auto-versioning via Nerdbank.GitVersioning
- Static analyzers: Code Analysis and StyleCop
- Read-only source tree (builds to top-level bin/obj folders)
- Builds with a "pinned" .NET SDK for reproducible builds
- Testing on Windows, Linux and macOS
Maintaining your repo based on this template
git fetch
git checkout origin/main
.\tools\MergeFrom-Template.ps1
# resolve any conflicts, then commit the merge commit.
git push origin -u HEAD
</details>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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 is compatible. 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. |
-
net10.0
- AWSSDK.Core (>= 4.0.3.4)
- AWSSDK.SecurityToken (>= 4.0.5.1)
- VaultSharp (>= 1.17.5.1)
-
net8.0
- AWSSDK.Core (>= 4.0.3.4)
- AWSSDK.SecurityToken (>= 4.0.5.1)
- VaultSharp (>= 1.17.5.1)
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 |
|---|---|---|
| 0.4.2 | 114 | 1/20/2026 |
| 0.3.7 | 100 | 1/19/2026 |
| 0.3.3 | 109 | 1/9/2026 |
| 0.3.1 | 110 | 1/7/2026 |
| 0.2.2 | 182 | 12/22/2025 |
| 0.2.1-beta | 179 | 12/22/2025 |
| 0.1.3 | 175 | 12/22/2025 |
| 0.1.1-beta | 175 | 12/22/2025 |
| 0.0.8-g7f68ca5f0e | 177 | 12/22/2025 |
| 0.0.0 | 177 | 12/22/2025 |