SecretBlast 1.0.3
dotnet add package SecretBlast --version 1.0.3
NuGet\Install-Package SecretBlast -Version 1.0.3
<PackageReference Include="SecretBlast" Version="1.0.3" />
<PackageVersion Include="SecretBlast" Version="1.0.3" />
<PackageReference Include="SecretBlast" />
paket add SecretBlast --version 1.0.3
#r "nuget: SecretBlast, 1.0.3"
#:package SecretBlast@1.0.3
#addin nuget:?package=SecretBlast&version=1.0.3
#tool nuget:?package=SecretBlast&version=1.0.3
SecretBlast ๐
![]()
SecretBlast is a cross-platform encrypted secrets vault for .NET. It deliberately does not use OS-provided secret stores (DPAPI / Keychain / libsecret / kwallet). The vault is a plain directory of files, encrypted with a master password, portable between machines, and safe to track in Git.
โ Status: 1.0 โ Argon2id + AES-256-GCM, 149 tests across the build / tamper / malformed / concurrency / KAT surfaces, CI matrix green on Linux / Windows / macOS. See DESIGN.md for the format spec and threat model.
โจ Features
- ๐น Cross-platform โ the same vault file works on Windows, macOS, Linux
- ๐น No OS keychain โ portable, not bound to any user account
- ๐น Git-friendly โ one file per secret, meaningful diffs, selective sharing
- ๐น Auditable format โ versioned, inspectable ciphertext records
- ๐น Argon2id password-derived master key, with upgradable work factors
- ๐น AES-256-GCM per-secret encryption with AAD binding
- ๐น Auto-lock on idle; derived key is zeroed from memory on lock / dispose
๐ฆ Installation
dotnet add package SecretBlast
Or install from the NuGet Gallery.
๐ Quick Example (target API)
using SecretBlast;
// Create a new vault
using (var vault = SecretVault.Create("/path/to/my-vault", "correct horse battery staple"))
{
await vault.SetAsync("azure-prod-sql", "Server=...;");
await vault.SetAsync("github-token", "ghp_...");
} // auto-locks on Dispose
// Re-open later
using var reopened = SecretVault.Open("/path/to/my-vault");
await reopened.UnlockAsync("correct horse battery staple");
var conn = await reopened.GetAsync("azure-prod-sql");
var names = await reopened.ListAsync(); // ["azure-prod-sql", "github-token"]
๐ Why not the OS keychain?
Each OS-native option has real limitations:
- Portability โ DPAPI secrets don't leave a Windows account.
Keychain items don't leave a macOS user. A SecretBlast vault is
rsync-able. - Shared machines โ DPAPI / Keychain bind to the OS account. SecretBlast binds to a password, so any user on any machine with the right password can open the vault and no one else can.
- Auditability โ opaque OS blobs vs. an inspectable, versioned ciphertext file format.
- Team sharing โ a Git-tracked vault directory lets a team share environment secrets without a central secrets service.
๐ Vault Layout
my-vault/
vault.json # header (plaintext): vault-id, kdf params, salt
secrets/
azure-prod-sql.secret
github-token.secret
Each .secret file is a small JSON record with version, nonce,
ciphertext, tag, and updatedUtc. Writes are atomic (*.secret.tmp โ rename).
Secret names are plaintext (the filename); secret values are always ciphertext. If hiding the names themselves is required, that's a future feature (encrypted index file + format version bump).
๐ Crypto
- KDF: Argon2id โ defaults
m=64 MiB, t=3, p=1. Parameters live invault.jsonso they can be raised per-vault without a format bump. - Symmetric: AES-256-GCM, fresh 12-byte nonce per write, 16-byte tag.
- AAD:
vaultId || secretNameโ swapping a*.secretfile in from another vault fails authentication loudly. - Versioning: a
versionfield in every on-disk record so algorithms can rotate without a flag day.
Full threat model (defended / not defended) and format spec in DESIGN.md.
๐งช Unlock Model
- Master password prompt on first access; derived key cached in process memory.
- Configurable idle auto-lock โ default 15 minutes. Also locks on
Dispose. - No "remember me" to disk. Not to disk, not to another process, not to the OS keychain.
CryptographicOperations.ZeroMemory(key)on lock โ best-effort, but the right thing to do.
๐ API Surface
namespace SecretBlast;
public interface ISecretVault : IDisposable
{
bool IsLocked { get; }
Task UnlockAsync(string masterPassword, CancellationToken ct = default);
void Lock();
Task<string> GetAsync (string name, CancellationToken ct = default);
Task SetAsync (string name, string value, CancellationToken ct = default);
Task DeleteAsync(string name, CancellationToken ct = default);
Task<IReadOnlyList<string>> ListAsync (CancellationToken ct = default);
event EventHandler? Locked;
}
public static class SecretVault
{
public static ISecretVault Create(string path, string masterPassword, VaultOptions? options = null);
public static ISecretVault Open (string path, VaultOptions? options = null);
}
Exceptions: SecretBlastException (base), VaultLockedException,
InvalidMasterPasswordException, SecretNotFoundException,
VaultAlreadyExistsException.
๐ฆ Why SecretBlast?
- One NuGet, one concern โ crypto for secrets, nothing else.
- No OS dependency, no cloud dependency, no network calls.
- Small, auditable surface. No code paths hidden behind platform branches.
- Plays nicely with DI containers; lives happily behind your own interfaces.
๐ค AI assistants
This assembly carries the Blast.PrimaryFacade convention: an
[AssemblyMetadata("Blast.PrimaryFacade", "...")] attribute names the
canonical front-door type(s) of the package, so AI helpers (e.g.
TaskBlaster's script assistant) can identify the entry points without
scanning every public type.
For SecretBlast the front door is:
| Type | Purpose |
|---|---|
SecretBlast.SecretVault |
The encrypted vault: Open, Create, UnlockAsync, Get / Set / Delete. |
Read it back from a loaded assembly via reflection:
var facade = typeof(SecretBlast.SecretVault).Assembly
.GetCustomAttributes<AssemblyMetadataAttribute>()
.FirstOrDefault(a => a.Key == "Blast.PrimaryFacade")?.Value;
The value is a hint for tooling; consumers don't need to read it.
๐ License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- Konscious.Security.Cryptography.Argon2 (>= 1.3.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.