Cross.PepperVault
1.0.0
dotnet add package Cross.PepperVault --version 1.0.0
NuGet\Install-Package Cross.PepperVault -Version 1.0.0
<PackageReference Include="Cross.PepperVault" Version="1.0.0" />
<PackageVersion Include="Cross.PepperVault" Version="1.0.0" />
<PackageReference Include="Cross.PepperVault" />
paket add Cross.PepperVault --version 1.0.0
#r "nuget: Cross.PepperVault, 1.0.0"
#:package Cross.PepperVault@1.0.0
#addin nuget:?package=Cross.PepperVault&version=1.0.0
#tool nuget:?package=Cross.PepperVault&version=1.0.0
Cross.PepperVault
A set of .NET libraries for configurable loading of pepper values (secret strings used to harden password hashes and similar use cases), with support for multiple versions, a TTL cache, reload, and FluentValidation of options at startup. The core defines the IPepperVaultProvider contract and shared infrastructure; data sources live in separate NuGet packages.
Features
- Pepper versions — version dictionary, active current version, rotation without application downtime.
- Cache and TTL — providers built on
PepperProviderBasecache loads and refresh on timeout and when options change viaIOptionsMonitor. - Configuration —
Peppersection, binding viaAddPepperOptions,ValidateOnStart(), and composite FluentValidation validators. - Providers — environment, file, Azure Key Vault, AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault, and more; reference only what you need.
- Extensibility — plug in your own source: inherit
PepperProviderBaseand registerIPepperVaultProviderin DI.
Target frameworks
All projects target netstandard2.1 and net6.0 through net10.0 (see .csproj).
Packages
Registry
Per-package NuGet download and latest-version badges. Issues: the core package row shows the repo-wide open-issue count; each provider row shows the count for a GitHub search scoped to this repository and the full NuGet package id (there are no per-package labels in this repo).
Cross.PepperVault
Core package: shared options model, validation wiring, and the provider abstraction. It exposes IPepperVaultProvider (current version, version dictionary, TryGet, ReloadAsync) and the caching base class PepperProviderBase, which uses a TTL from IOptionsMonitor<TimeSpan> (typically from PepperOptions<T>.Ttl through OptionsMonitorProxyForTtl<T>), a semaphore around reloads, and refresh when data was never loaded or the TTL elapsed.
PepperOptions<TProviderOptions> binds under the configuration section Pepper: Provider (discriminator string), Ttl, and ProviderOptions (provider-specific payload). AddPepperOptions<TProviderOptions, TProviderOptionsValidator> registers PepperBaseValidator<T> plus your provider validator, CompositeFluentOptionsValidatorAdapter as IValidateOptions<>, binds Pepper, and enables ValidateOnStart() so invalid configuration fails at startup. Reference this package in every app that uses any provider.
Cross.PepperVault.Env
Configuration-bound provider: peppers are supplied directly from configuration (appsettings, env vars, etc.) under Pepper:ProviderOptions. EnvPepperProvider reads Current and Peppers on each load; there are no outbound secret-store calls. EnvProviderOptions holds Current (active short version) and Peppers (Dictionary<short, string>). Runtime validation ensures the map is non-empty and that Current maps to a non-whitespace pepper.
Use a conventional Pepper.Provider value such as Env (not fixed by EnvProviderOptionsValidator; PepperBaseValidator still requires Provider to be non-empty). Register AddPepperOptions<EnvProviderOptions, EnvProviderOptionsValidator> and EnvPepperProvider as IPepperVaultProvider.
Cross.PepperVault.EnvJson
Reads one JSON document from a process environment variable. Default variable name is AUTH_PEPPERS_JSON; override with ProviderOptions.JsonKey. The JSON root must contain current (number) and peppers (object: version keys as strings, values as pepper strings). current must exist in peppers.
EnvJsonProviderOptionsValidator requires a non-empty JsonKey. There is no required literal for Pepper.Provider in this package—choose a clear string in your config and docs. Use AddPepperOptions<EnvJsonProviderOptions, EnvJsonProviderOptionsValidator> and EnvJsonPepperProvider.
Shared JSON shape (EnvJson, FileJson, single-secret cloud providers, Vault KV JSON)
{
"current": 3,
"peppers": {
"1": "pepper-for-v1",
"2": "pepper-for-v2",
"3": "pepper-for-v3"
}
}
Property names current and peppers are lowercase in the payload, as expected by the built-in parsers.
Cross.PepperVault.FileJson
Loads the same JSON from a local file. ProviderOptions.Path must be an absolute path (FluentValidation enforces this). Set Pepper.Provider to FileJson (case-insensitive). The file is read on each provider reload. Register AddPepperOptions<FileJsonProviderOptions, FileJsonProviderOptionsValidator> and FileJsonPepperProvider.
Cross.PepperVault.AzureKvJson
Fetches one Key Vault secret whose string value is the JSON blob (current + peppers). ProviderOptions: VaultUri (HTTPS absolute URI to https://{vault}.vault.azure.net/), SecretName, optional AzureCredential — omit → DefaultAzureCredential; managed: / managed:{clientId} → managed identity.
Pepper.Provider must be AzureKvJson. Uses SecretClient. Register AddPepperOptions<AzureKvJsonProviderOptions, AzureKvJsonProviderOptionsValidator> and AzureKvJsonPepperProvider.
Cross.PepperVault.AzureKvVersioned
Uses multiple versions of the same secret name. Each enabled version should carry a tag (default name pepperVersion, configurable via TagName) with the pepper version number. The provider builds version → secret value and sets current to the maximum tagged version among enabled entries. Untagged or unreadable versions are skipped.
Pepper.Provider must be AzureKvVersions. Register AddPepperOptions<AzureKvVersionsProviderOptions, AzureKvVersionsProviderOptionsValidator> and AzureKvVersionedPepperProvider.
Cross.PepperVault.AwsSecretsJson
Loads one AWS Secrets Manager secret (SecretId as name or ARN); payload must be the shared JSON. Register IAmazonSecretsManager in DI yourself (region/credentials per your deployment).
Pepper.Provider must be AwsJson (NuGet package id remains Cross.PepperVault.AwsSecretsJson). Register AddPepperOptions<AwsSecretsJsonProviderOptions, AwsSecretsJsonProviderOptionsValidator> and AwsSecretsJsonPepperProvider.
Cross.PepperVault.GcpSecretManagerJson
Reads SecretName formatted as projects/{projectId}/secrets/{secretId}, always version latest. Inject SecretManagerServiceClient with appropriate GCP credentials.
Pepper.Provider must be GcpJson. Register AddPepperOptions<GcpSecretManagerJsonProviderOptions, GcpSecretManagerJsonProviderOptionsValidator> and GcpSecretManagerJsonPepperProvider.
Cross.PepperVault.HcvKv2Json
HashiCorp Vault KV v2 via VaultSharp (token authentication). ProviderOptions: VaultUri, Token, Mount (engine mount), Path (secret path). Secret data is serialized to JSON and parsed as a root object with current and peppers.
Pepper.Provider must be HcvKv2Json. Register AddPepperOptions<HcvKv2JsonProviderOptions, HcvKv2JsonProviderOptionsValidator> and HcvKv2JsonPepperProvider.
Target frameworks and version lines
Target frameworks: libraries target netstandard2.1 and .NET 6 through .NET 10. Keep Cross.PepperVault and your provider packages on compatible NuGet versions (same release line); pin versions in production.
Package Manager Console
# Package Manager Console (Visual Studio) — install core + any providers you need
Install-Package Cross.PepperVault
Install-Package Cross.PepperVault.Env
Install-Package Cross.PepperVault.EnvJson
Install-Package Cross.PepperVault.FileJson
Install-Package Cross.PepperVault.AzureKvJson
Install-Package Cross.PepperVault.AzureKvVersioned
Install-Package Cross.PepperVault.AwsSecretsJson
Install-Package Cross.PepperVault.GcpSecretManagerJson
Install-Package Cross.PepperVault.HcvKv2Json
Register AddPepperOptions (with your provider options and validator types) and IPepperVaultProvider in DI — see Quick start below.
Quick start
- Add NuGet packages (example: core + Env):
dotnet add package Cross.PepperVault
dotnet add package Cross.PepperVault.Env
- Register options and the provider:
services.AddPepperOptions<EnvProviderOptions, EnvProviderOptionsValidator>(configuration);
services.AddSingleton<IPepperVaultProvider, EnvPepperProvider>();
- Sample configuration for Env:
{
"Pepper": {
"Provider": "Env",
"Ttl": "00:10:00",
"ProviderOptions": {
"Current": 1,
"Peppers": {
"1": "your-secret-pepper-v1",
"2": "your-secret-pepper-v2"
}
}
}
}
For each provider, set Pepper.Provider to the literal expected by that package’s validator (e.g. FileJson, AzureKvJson, AwsJson, GcpJson, AzureKvVersions, HcvKv2Json) or your chosen string where no literal is enforced (Env, EnvJson). Shape ProviderOptions to match that provider’s options type.
Build
dotnet build Cross.PepperVault.slnx -c Release
Packaging: config.nuspec in each project directory (after a Release build).
Unit tests
Tests follow the Given_When_Then naming convention:
- Given — context / preconditions.
- When — the action under test.
- Then — the expected outcome.
Example: Given_EmptyProvider_When_Validate_Then_Fails.
Tests live in the Cross.PepperVault.Tests project (Options, Providers, Extensions, and related folders).
See also
- LICENSE — license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. 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 is compatible. 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 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 is compatible. 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. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | 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.1
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net10.0
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.5)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.5)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 10.0.5)
-
net6.0
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net7.0
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net8.0
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 8.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 8.0.0)
-
net9.0
- FluentValidation (>= 11.8.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 9.0.14)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.14)
- Microsoft.Extensions.Options.ConfigurationExtensions (>= 9.0.14)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on Cross.PepperVault:
| Package | Downloads |
|---|---|
|
Cross.PepperVault.Env
Провайдер pepper из переменных окружения (Cross.PepperVault.Env). |
|
|
Cross.PepperVault.EnvJson
Провайдер pepper из JSON в переменной окружения (Cross.PepperVault.EnvJson). |
|
|
Cross.PepperVault.GcpSecretManagerJson
Провайдер pepper из Google Cloud Secret Manager (JSON) — Cross.PepperVault.GcpSecretManagerJson. |
|
|
Cross.PepperVault.HcvKv2Json
Провайдер pepper из HashiCorp Vault KV v2 (JSON) через VaultSharp — Cross.PepperVault.HcvKv2Json. |
|
|
Cross.PepperVault.AwsSecretsJson
Провайдер pepper из AWS Secrets Manager (JSON) — Cross.PepperVault.AwsSecretsJson. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 531 | 4/9/2026 |
| 1.0.0-dev.11 | 57 | 4/9/2026 |
| 1.0.0-dev.10 | 55 | 4/9/2026 |
| 1.0.0-dev.9 | 58 | 4/9/2026 |
| 1.0.0-dev.8 | 61 | 4/9/2026 |
Cross.PepperVault: ядро библиотеки pepper-провайдеров.