Deneblab.StashLock.Client 0.1.23

dotnet add package Deneblab.StashLock.Client --version 0.1.23
                    
NuGet\Install-Package Deneblab.StashLock.Client -Version 0.1.23
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Deneblab.StashLock.Client" Version="0.1.23" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Deneblab.StashLock.Client" Version="0.1.23" />
                    
Directory.Packages.props
<PackageReference Include="Deneblab.StashLock.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Deneblab.StashLock.Client --version 0.1.23
                    
#r "nuget: Deneblab.StashLock.Client, 0.1.23"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Deneblab.StashLock.Client@0.1.23
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Deneblab.StashLock.Client&version=0.1.23
                    
Install as a Cake Addin
#tool nuget:?package=Deneblab.StashLock.Client&version=0.1.23
                    
Install as a Cake Tool

Deneblab.StashLock.Client

Async-first secrets management client for StashLock vault with simplified 2-part API design.

Features

  • 2-Part API Design: Clean separation between VaultKey configuration and SecretsStore opening
  • Multiple Secret Sources: Remote encrypted vaults, local dev files, environment variables
  • Async-First: Modern async/await patterns throughout
  • Zero Dependencies: No external package dependencies
  • Early Initialization: Load secrets before host builder setup
  • Auto-Discovery: Automatic dev secrets file detection

Installation

dotnet add package Deneblab.StashLock.Client

Quick Start

Production: Remote Encrypted Vault

using Deneblab.StashLock.Client;
using Deneblab.StashLock.Client.Configuration;

// Set environment variable
// STASHLOCK_VAULT_KEY=mybox.prod.v1.secretpassword

// Get vault key from environment
var vaultKey = VaultKey.FromEnvironment();

// Open remote encrypted secrets store
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);

// Retrieve secrets
var dbPassword = await store.GetAsync("Database:Password");
var apiKey = await store.GetAsync("ExternalApi:Key");

Development: Plain JSON File

// Auto-discover dev secrets file
var store = await SecretsStoreAsync.TryOpenDevFileAsync();

if (store == null)
{
    // Fallback: explicit file path
    store = await SecretsStoreAsync.OpenFileAsync("./dev-secrets.json");
}

var secret = await store.GetAsync("MySecret");

Early Initialization Pattern

// Load secrets BEFORE host builder
var simpleEnv = SimpleEnv.Detect();
var vaultKey = VaultKey.FromEnvironment();
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);

// Now create host builder
var builder = WebApplication.CreateBuilder(args);

// Configure with loaded secrets
var dbConnection = await store.GetAsync("Database:ConnectionString");
builder.Services.AddDbContext<MyContext>(options =>
    options.UseSqlServer(dbConnection));

API Overview

Part 1: VaultKey Configuration

Get vault keys from different sources:

// 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");

Part 2: SecretsStore Opening

Open secrets stores from different storage backends:

// Remote encrypted vault (production)
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);

// Plain JSON file (development)
var store = await SecretsStoreAsync.OpenFileAsync("./secrets.json");

// Auto-discover dev file
var store = await SecretsStoreAsync.TryOpenDevFileAsync();

Retrieve Secrets

// Get single secret
string value = await store.GetAsync("SecretKey");

// Get section as dictionary
var dbConfig = await store.GetSectionAsDictionaryAsync("Database");
// Returns: { "Host": "localhost", "Password": "secret", ... }

Environment Variables

Variable Purpose Required
STASHLOCK_VAULT_KEY Vault key or file path Yes (for remote)
STASHLOCK_API_URL Vault API base URL No (has default)
STASHLOCK_API_KEY API authentication key No

Vault Key Format

Vault keys use the format: box.tag.version.password

  • box: Vault box name (e.g., myapp, production)
  • tag: Environment tag (e.g., prod, staging, dev)
  • version: Version identifier (e.g., v1, v2, 2024-01)
  • password: Secret password for encryption

Example: myapp.prod.v1.secret123

Development Secrets File

Create a secrets.json file in your dev directory:

{
  "Database:ConnectionString": "Server=localhost;Database=dev",
  "Database:Password": "dev-password",
  "ExternalApi:Key": "dev-api-key",
  "ExternalApi:Url": "https://api-dev.example.com"
}

The client will auto-discover this file when running in Dev or Test mode.

Error Handling

try
{
    var vaultKey = VaultKey.FromEnvironment();
    var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
}
catch (VaultConfigurationException ex)
{
    Console.WriteLine($"Configuration error: {ex.Message}");
}
catch (VaultNotFoundException ex)
{
    Console.WriteLine($"Vault not found: {ex.VaultKey}");
}
catch (DecryptionException ex)
{
    Console.WriteLine("Decryption failed - check password");
}

Migration from Old API

Old API (SecretsStoreFactoryAsync)

var factory = new SecretsStoreFactoryAsync();
var store = await factory.TryCreateFromAllAsync(
    vaultKeyPlainText: "box.tag.version.password"
);
var secret = store.Get("MySecret"); // Sync

New API (2-Part Design)

var vaultKey = VaultKey.FromString("box.tag.version.password");
var store = await SecretsStoreAsync.OpenRemoteAsync(vaultKey);
var secret = await store.GetAsync("MySecret"); // Async

License

MIT License - see LICENSE file for details

Repository

https://github.com/deneblab/stashlock

Support

For issues and questions, please visit: https://github.com/deneblab/stashlock/issues

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

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.1.23 130 11/28/2025
0.1.22 196 10/2/2025
0.1.21 187 10/2/2025
0.1.20 185 10/2/2025