SyntaxCircus.Credentials
0.1.1
dotnet add package SyntaxCircus.Credentials --version 0.1.1
NuGet\Install-Package SyntaxCircus.Credentials -Version 0.1.1
<PackageReference Include="SyntaxCircus.Credentials" Version="0.1.1" />
<PackageVersion Include="SyntaxCircus.Credentials" Version="0.1.1" />
<PackageReference Include="SyntaxCircus.Credentials" />
paket add SyntaxCircus.Credentials --version 0.1.1
#r "nuget: SyntaxCircus.Credentials, 0.1.1"
#:package SyntaxCircus.Credentials@0.1.1
#addin nuget:?package=SyntaxCircus.Credentials&version=0.1.1
#tool nuget:?package=SyntaxCircus.Credentials&version=0.1.1
SyntaxCircus.Credentials
A cross-platform desktop credential vault: Windows Credential Manager, macOS Keychain, Linux secret-tool/libsecret (with an AES-256 encrypted-file fallback when libsecret isn't available), and a factory that picks the right one for the current OS.
No support guaranteed. Published as-is and maintained on a best-effort basis. Issues and PRs are welcome, but there's no SLA — fork it or vendor what you need if that's not enough.
Setup
ICredentialStore store = CredentialStoreFactory.Create(
new ProcessRunner(),
loggerFactory,
allowEncryptedFileFallback: false, // opt-in only — see below
appName: "MyApp");
await store.SetAsync("my-service", "my-account", "secret-value");
string? secret = await store.GetAsync("my-service", "my-account");
Credentials are keyed by a (serviceId, accountId) pair, matching how OS keychains natively model credentials — serviceId is typically your app or the external service the secret belongs to, accountId the specific credential within it.
Platform behavior
- Windows — Windows Credential Manager via
Meziantou.Framework.Win32.CredentialManager. Works from a plainnet10.0TFM — nonet10.0-windowsmulti-targeting required. - macOS — Keychain via the
securityCLI, shelled out through an injectableIProcessRunner(testable without spawning real processes). - Linux —
secret-tool/libsecret via the sameIProcessRunner, if it's onPATH. Falls back toEncryptedFileCredentialStoreautomatically (with a one-time warning logged) on headless systems without a keyring daemon. - Anything else —
CredentialStoreFactory.CreatethrowsPlatformNotSupportedExceptionby default. PassallowEncryptedFileFallback: trueto degrade toEncryptedFileCredentialStoreinstead — off by default because silently falling back to a weaker store is a decision your app should make explicitly, not one this package makes for you.
Encrypted-file fallback
EncryptedFileCredentialStore (AES-256-CBC, PBKDF2 key derivation off a machine-specific value + fixed salt) is usable directly too, not just as the Linux/unrecognized-platform fallback:
var store = new EncryptedFileCredentialStore(EncryptedFileCredentialStore.DefaultPathFor("MyApp"));
This is a last-resort store, not a substitute for a real OS keychain — the key derivation makes the file non-portable as plaintext-equivalent, not cryptographically hardened against an attacker with local account access.
Contributing
Issues and pull requests are welcome:
- Keep changes focused, with a clear description of the behavior change.
- Match the existing code style (see
.editorconfig). - Call out any breaking changes to the public API in your PR description.
License
MIT — see LICENSE.txt.
| 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
- Meziantou.Framework.Win32.CredentialManager (>= 3.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
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.1 | 120 | 8/16/2026 |