Deneblab.StashLock.Client
0.2.76
See the version list below for details.
dotnet add package Deneblab.StashLock.Client --version 0.2.76
NuGet\Install-Package Deneblab.StashLock.Client -Version 0.2.76
<PackageReference Include="Deneblab.StashLock.Client" Version="0.2.76" />
<PackageVersion Include="Deneblab.StashLock.Client" Version="0.2.76" />
<PackageReference Include="Deneblab.StashLock.Client" />
paket add Deneblab.StashLock.Client --version 0.2.76
#r "nuget: Deneblab.StashLock.Client, 0.2.76"
#:package Deneblab.StashLock.Client@0.2.76
#addin nuget:?package=Deneblab.StashLock.Client&version=0.2.76
#tool nuget:?package=Deneblab.StashLock.Client&version=0.2.76
Deneblab.StashLock.Client
Async-first .NET secrets management client for StashLock vault.
Installation
dotnet add package Deneblab.StashLock.Client
Two Ways to Use
1. Standalone (VaultKey + SecretsStoreAsync)
Load secrets directly in code — useful for early initialization before the host builder, console apps, or anywhere you need explicit control.
using Deneblab.StashLock.Client;
// From environment variable STASHLOCK_VAULT_KEY
var vaultKey = VaultKey.FromEnvironment();
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
var dbPassword = await store.GetAsync("Database:Password");
var apiKey = await store.GetAsync("ExternalApi:Key");
2. IConfiguration Integration
Plug secrets into the standard .NET configuration pipeline — secrets appear alongside appsettings.json, env vars, etc.
using Deneblab.StashLock.Client.Configuration;
var builder = WebApplication.CreateBuilder(args);
// Remote vault (production)
builder.Configuration.AddStashLockRemote(
box: "myapp",
tag: "prod",
version: "v1");
// Then access secrets via IConfiguration
var app = builder.Build();
var dbConn = app.Configuration["Database:ConnectionString"];
Standalone API
VaultKey — Configure access
// From environment variable STASHLOCK_VAULT_KEY
var vaultKey = VaultKey.FromEnvironment();
// From file
var vaultKey = VaultKey.FromFile("/path/to/vault.key");
// Direct string
var vaultKey = VaultKey.FromString("box.tag.version.password");
Vault key format: box.tag.version.password (4 dot-separated segments)
SecretsStoreAsync — Open and read secrets
// Remote encrypted vault (production)
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
// Remote sealed-box encrypted vault (X25519)
var store = await SecretsStoreAsync.OpenRemoteSealedAsync(
box: "myapp", tag: "prod", version: "v1");
// Local encrypted file (stashlock.enc.*.json)
var store = await SecretsStoreAsync.OpenEncryptedFileAsync("./stashlock.enc.prod.secrets.json");
// Plain JSON file (development)
var store = await SecretsStoreAsync.OpenFileAsync("./secrets.json");
// Auto-discover dev file (looks for dev/secrets/secrets.json)
var store = await SecretsStoreAsync.TryOpenDevFileAsync();
Read secrets
// Single secret
string value = await store.GetAsync("SecretKey");
// Section as dictionary
var dbConfig = await store.GetSectionAsDictionaryAsync("Database");
// Returns: { "Host": "localhost", "Password": "secret", ... }
Early initialization pattern
Load secrets before the host builder is created:
var vaultKey = VaultKey.FromEnvironment();
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
var builder = WebApplication.CreateBuilder(args);
var dbConn = await store.GetAsync("Database:ConnectionString");
builder.Services.AddDbContext<MyContext>(o => o.UseSqlServer(dbConn));
IConfiguration Integration API
Three extension methods on IConfigurationBuilder:
AddStashLockRemote — Remote vault
Fetches encrypted secrets from a StashLock server, decrypts with X25519 private key, and loads into IConfiguration.
builder.Configuration.AddStashLockRemote(
box: "myapp",
tag: "prod",
version: "v1",
privateKeyBase64: null, // falls back to STASHLOCK_PRIVATE_KEY env var
apiUrl: null, // falls back to STASHLOCK_API_URL env var
apiKey: null); // falls back to STASHLOCK_API_KEY env var
AddStashLockFile — Local encrypted file
Reads a stashlock.enc.*.json file, auto-detects SOPS or whole-file encryption, decrypts with X25519 private key.
builder.Configuration.AddStashLockFile(
filePath: "./stashlock.enc.prod.secrets.json",
privateKeyBase64: null); // falls back to STASHLOCK_PRIVATE_KEY env var
AddStashLockDevFile — Plain JSON (development)
Reads an unencrypted JSON file. Nested objects are flattened with colon separators (e.g., Database:Host).
builder.Configuration.AddStashLockDevFile(
filePath: "./dev-secrets.json");
Full IConfiguration example
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
{
builder.Configuration.AddStashLockDevFile("./dev-secrets.json");
}
else
{
builder.Configuration.AddStashLockRemote(
box: "myapp",
tag: "prod",
version: "v1");
}
var app = builder.Build();
// Access secrets like any other configuration source
var dbConn = app.Configuration["Database:ConnectionString"];
var apiKey = app.Configuration["ExternalApi:Key"];
Environment Variables
| Variable | Purpose | Used by |
|---|---|---|
STASHLOCK_VAULT_KEY |
Vault key string (box.tag.version.password) |
Standalone API (VaultKey.FromEnvironment()) |
STASHLOCK_PRIVATE_KEY |
Base64-encoded X25519 private key | IConfiguration (AddStashLockRemote, AddStashLockFile), Sealed-box methods |
STASHLOCK_API_URL |
Vault API base URL | Both (defaults to https://deneblabvault.azurewebsites.net/api/) |
STASHLOCK_API_KEY |
API authentication key (Bearer token) | Both (required if server has auth enabled) |
Error Handling
try
{
var vaultKey = VaultKey.FromEnvironment();
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
}
catch (VaultConfigurationException ex)
{
// Missing or invalid configuration (env var, key format)
}
catch (VaultNotFoundException ex)
{
// Vault entry not found on server
}
catch (DecryptionException ex)
{
// Decryption failed — wrong password or key
}
Development Secrets File
Create a secrets.json in dev/secrets/ under your project root:
{
"Database:ConnectionString": "Server=localhost;Database=dev",
"Database:Password": "dev-password",
"ExternalApi:Key": "dev-api-key"
}
TryOpenDevFileAsync() auto-discovers this file when running in Dev or Test mode.
License
MIT License - see LICENSE file for details
Links
| 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 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. |
-
net8.0
- BouncyCastle.Cryptography (>= 2.6.2)
- Microsoft.Extensions.Configuration (>= 10.0.3)
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.2.79 | 29 | 2/21/2026 |
| 0.2.78 | 32 | 2/21/2026 |
| 0.2.77 | 28 | 2/21/2026 |
| 0.2.76 | 26 | 2/21/2026 |
| 0.2.75 | 25 | 2/21/2026 |
| 0.2.73 | 29 | 2/21/2026 |
| 0.2.68 | 29 | 2/21/2026 |
| 0.2.67 | 25 | 2/21/2026 |
| 0.2.66 | 32 | 2/21/2026 |
| 0.2.65 | 27 | 2/21/2026 |
| 0.2.63 | 32 | 2/21/2026 |
| 0.2.62 | 28 | 2/21/2026 |
| 0.2.61 | 27 | 2/21/2026 |
| 0.2.60 | 25 | 2/21/2026 |
| 0.2.59 | 29 | 2/21/2026 |
| 0.2.58 | 28 | 2/21/2026 |
| 0.2.55 | 30 | 2/21/2026 |
| 0.2.51 | 31 | 2/20/2026 |
| 0.2.47 | 36 | 2/20/2026 |
| 0.1.44 | 36 | 2/20/2026 |