ktsu.CredentialCache
1.3.4
Prefix Reserved
dotnet add package ktsu.CredentialCache --version 1.3.4
NuGet\Install-Package ktsu.CredentialCache -Version 1.3.4
<PackageReference Include="ktsu.CredentialCache" Version="1.3.4" />
<PackageVersion Include="ktsu.CredentialCache" Version="1.3.4" />
<PackageReference Include="ktsu.CredentialCache" />
paket add ktsu.CredentialCache --version 1.3.4
#r "nuget: ktsu.CredentialCache, 1.3.4"
#:package ktsu.CredentialCache@1.3.4
#addin nuget:?package=ktsu.CredentialCache&version=1.3.4
#tool nuget:?package=ktsu.CredentialCache&version=1.3.4
ktsu.CredentialCache
A cross-platform credential cache for .NET that stores secrets in the host's native keyring.
Overview
CredentialCache keeps credentials in memory for fast lookup during the lifetime of a process and persists each one through an ICredentialStore whose default implementation delegates to the platform-native secret manager:
| Platform | Backing store | Native API |
|---|---|---|
| Windows | Credential Manager | advapi32 — CredReadW / CredWriteW / CredDeleteW / CredEnumerateW |
| macOS | Keychain Services | Security.framework — SecKeychainAddGenericPassword and friends |
| Linux | freedesktop.org Secret Service | libsecret-1.so.0 — secret_password_store_sync / lookup_sync / clear_sync |
| Other / opt-out | None | InMemoryCredentialStore |
Each persona's credential is stored as its own entry in the OS keyring scoped by a service name — the library never writes a plaintext blob to disk.
Installation
dotnet add package ktsu.CredentialCache
Requires .NET 9 or .NET 10.
Linux runtime prerequisites
The Linux store requires libsecret and a running Secret Service implementation (gnome-keyring, KWallet's secret-service bridge, KeePassXC, …). On Debian/Ubuntu:
sudo apt-get install libsecret-1-0 gnome-keyring
On headless or CI hosts you'll typically need a session bus and an unlocked keyring — see the cross-platform.yml workflow in this repo for the dbus-run-session + gnome-keyring-daemon incantation. If a Secret Service isn't available in your deployment, fall back to InMemoryCredentialStore (or roll your own ICredentialStore).
Quick start
using ktsu.CredentialCache;
using ktsu.CredentialCache.Storage;
using ktsu.Semantics.Strings;
// Pick the platform-native store explicitly...
ICredentialStore store = CredentialStoreFactory.CreateDefault("MyApp");
using CredentialCache cache = new(store);
// ...or just use the singleton, which calls CreateDefault() on first access.
CredentialCache singleton = CredentialCache.Instance;
PersonaGUID persona = CredentialCache.CreatePersonaGUID();
cache.AddOrReplace(persona, new CredentialWithUsernamePassword
{
Username = SemanticString<CredentialUsername>.Create("alice"),
Password = SemanticString<CredentialPassword>.Create("hunter2"),
});
if (cache.TryGet(persona, out Credential? stored)
&& stored is CredentialWithUsernamePassword creds)
{
Console.WriteLine($"Hello, {creds.Username}");
}
cache.Remove(persona);
Pick your own service name
CredentialStoreFactory.CreateDefault(serviceName) scopes entries by a logical service name (defaults to "ktsu.CredentialCache"). If two applications share a host, pass per-app names so their keyring entries don't collide.
Credential types
The library ships with three concrete Credential subclasses:
| Type | Use it for |
|---|---|
CredentialWithNothing |
Sentinel for "no credential required" |
CredentialWithToken |
Opaque bearer or API token |
CredentialWithUsernamePassword |
Classic username + password pair |
Adding your own credential type
Credential is a polymorphic record class round-tripped through System.Text.Json. New subclasses need a [JsonDerivedType] on the base so deserialization can resolve them:
// 1. Add the subclass.
public sealed class CredentialWithCertificate : Credential
{
public string Thumbprint { get; init; } = "";
}
// 2. Register it on the base in Credential.cs.
[JsonDerivedType(typeof(CredentialWithCertificate), nameof(CredentialWithCertificate))]
public abstract class Credential { /* ... */ }
// 3. Optional: register a factory so TryCreate<T> works.
public sealed class CertificateFactory : ICredentialFactory<CredentialWithCertificate>
{
public CredentialWithCertificate Create() => new();
}
cache.RegisterCredentialFactory(new CertificateFactory());
If a subclass uses SemanticString<T> properties, they round-trip through ktsu.RoundTripStringJsonConverter automatically.
Customising the backing store
ICredentialStore is a small CRUD interface (TryLoad / Save / Remove). Bring your own implementation when you need a different backend (HashiCorp Vault, an encrypted file, a test double):
public sealed class MyCustomStore : ICredentialStore { /* ... */ }
ICredentialStore store = new MyCustomStore();
CredentialCache.ConfigureStore(store); // must be called before first Instance access
For unit tests, use the in-memory store and skip the singleton entirely:
using CredentialCache cache = new(new InMemoryCredentialStore());
Enumerating stored personas
ICredentialStore deliberately has no EnumerateKeys method, because macOS Keychain and libsecret require substantially more native marshalling for enumeration than the simple key-value ops. The optional ISearchableCredentialStore interface adds it, and only the Windows and in-memory stores implement it:
if (cache.Store is ISearchableCredentialStore searchable)
{
foreach (PersonaGUID key in searchable.EnumerateKeys())
{
// ...
}
}
else
{
// Track persona GUIDs yourself on macOS / Linux.
}
Platform notes
- Windows Credential Manager caps the credential blob at 2560 bytes (
5 * 512). Tokens larger than that throwCredentialStoreException— split or compress before storing. - macOS uses the user's default login keychain. The first access from an application prompts the user for permission, as with any keychain client.
- Linux requires
libsecret-1plus an active Secret Service. Headless CI agents typically have neither — useInMemoryCredentialStorethere, or set updbus-run-session+gnome-keyring-daemonas thecross-platform.ymlworkflow does. - All native calls happen on the thread the API is invoked from. The library's in-memory cache is thread-safe (
ConcurrentDictionary); the native APIs themselves are documented as thread-safe by their respective platform owners, but blocking calls (especially libsecret) are not cheap — treatSave/Removeas I/O, not as cheap accessors.
API summary
CredentialCache
| Member | Description |
|---|---|
CredentialCache(ICredentialStore store) |
Construct an instance with an explicit store. |
static Instance |
Process-wide singleton (lazy, thread-safe). |
Store |
The backing store passed to the constructor. |
static ConfigureStore(ICredentialStore) |
Override the singleton's store. Must precede first Instance access. |
static ResetSingletonForTesting() |
Dispose the singleton and clear configuration. Tests only. |
static CreatePersonaGUID() |
Allocates a new PersonaGUID. |
TryGet(persona, out cred) |
Memory-cache lookup with fall-through to the backing store. |
AddOrReplace(persona, cred) |
Persists eagerly through the store. |
Remove(persona) |
Deletes from both the in-memory cache and the store. |
RegisterCredentialFactory<T>(factory) |
Optional factory hook used by TryCreate<T>. |
TryCreate<T>(out cred) |
Constructs a credential via a registered factory. |
Dispose() |
Releases in-memory state. The OS store is left untouched. |
ICredentialStore
| Member | Description |
|---|---|
Name |
Diagnostic identifier (e.g. "Windows Credential Manager", "macOS Keychain", "Linux libsecret (Secret Service)", "InMemory"). |
TryLoad(persona, out cred) |
Load a single credential. |
Save(persona, cred) |
Persist or overwrite a single credential. |
Remove(persona) |
Delete a single credential. |
ISearchableCredentialStore : ICredentialStore
| Member | Description |
|---|---|
EnumerateKeys() |
Enumerate every persona key currently persisted (Windows, in-memory). |
Don't dispose the singleton
CredentialCache.Instance returns a process-wide singleton. Calling Dispose() on it (e.g. via using var c = CredentialCache.Instance;) puts the singleton in a disposed state and the next consumer in the process gets ObjectDisposedException. If you need disposal semantics, construct your own instance with new CredentialCache(store).
License
MIT — see LICENSE.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- ktsu.RoundTripStringJsonConverter (>= 1.0.10)
- ktsu.Semantics.Strings (>= 1.0.35)
- Microsoft.SourceLink.AzureRepos.Git (>= 10.0.300)
- Microsoft.SourceLink.GitHub (>= 10.0.300)
- Polyfill (>= 10.7.0)
-
net9.0
- ktsu.RoundTripStringJsonConverter (>= 1.0.10)
- ktsu.Semantics.Strings (>= 1.0.35)
- Microsoft.SourceLink.AzureRepos.Git (>= 10.0.300)
- Microsoft.SourceLink.GitHub (>= 10.0.300)
- Polyfill (>= 10.7.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on ktsu.CredentialCache:
| Package | Downloads |
|---|---|
|
ktsu.ImGuiCredentialPopups
ImGuiCredentialPopups |
|
|
ktsu.GitIntegration
Git Integration |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.4 | 33 | 5/22/2026 |
| 1.3.3 | 115 | 5/18/2026 |
| 1.3.2 | 95 | 5/15/2026 |
| 1.3.1 | 122 | 5/12/2026 |
| 1.3.0 | 109 | 5/12/2026 |
| 1.2.4-pre.16 | 191 | 5/20/2025 |
| 1.2.4-pre.14 | 133 | 5/17/2025 |
| 1.2.4-pre.13 | 180 | 5/16/2025 |
| 1.2.4-pre.12 | 244 | 5/15/2025 |
| 1.2.4-pre.11 | 252 | 5/14/2025 |
| 1.2.4-pre.10 | 253 | 5/13/2025 |
| 1.2.4-pre.9 | 278 | 5/12/2025 |
| 1.2.4-pre.8 | 232 | 5/11/2025 |
| 1.2.4-pre.7 | 154 | 5/10/2025 |
| 1.2.4-pre.6 | 109 | 5/9/2025 |
| 1.2.4-pre.5 | 176 | 5/8/2025 |
| 1.2.4-pre.4 | 168 | 5/7/2025 |
| 1.2.4-pre.3 | 179 | 5/6/2025 |
| 1.2.4-pre.2 | 182 | 5/4/2025 |
| 1.2.4-pre.1 | 177 | 5/4/2025 |
## v1.3.4 (patch)
Changes since v1.3.3:
- Bump Polyfill from 10.6.0 to 10.7.0 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.3.3 (patch)
Changes since v1.3.2:
- Bump Polyfill from 10.5.1 to 10.6.0 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.3.2 (patch)
Changes since v1.3.1:
- Bump MSTest.Sdk from 4.2.2 to 4.2.3 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.3.1 (patch)
Changes since v1.3.0:
- Refresh README for 2.0.0 surface ([@Claude](https://github.com/Claude))
## v1.3.0 (minor)
Changes since v1.2.0:
- Add native-store integration tests + split EnumerateKeys ([@Claude](https://github.com/Claude))
- Pass test project via --project flag ([@Claude](https://github.com/Claude))
- Drop `--logger` from dotnet test in cross-platform workflow ([@Claude](https://github.com/Claude))
- Force CRLF working-tree line endings for .cs files ([@Claude](https://github.com/Claude))
- Rewrite persistence layer to use platform-native credential stores ([@Claude](https://github.com/Claude))
- Add TAGS.md with NuGet package tags ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove legacy build scripts ([@matt-edmondson](https://github.com/matt-edmondson))
- Refactor project structure and update dependencies; enhance test assertions for clarity ([@matt-edmondson](https://github.com/matt-edmondson))
- Refactor CredentialCache to use a dedicated data model and enhance persistence management ([@matt-edmondson](https://github.com/matt-edmondson))
- Update project configuration files, add new workflows, and enhance SDK management ([@matt-edmondson](https://github.com/matt-edmondson))
- Update .editorconfig, .gitignore, .gitattributes, .mailmap, .runsettings, and PSBuild.psm1 for improved configurations and cleanup ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package references in CredentialCache.csproj ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove Directory.Build.props and Directory.Build.targets files; add copyright notices to CredentialCache files. ([@matt-edmondson](https://github.com/matt-edmondson))
- Enhance README with detailed project description, features, installation instructions, and usage examples. Update project SDK references in .csproj files for CredentialCache and its tests. ([@matt-edmondson](https://github.com/matt-edmondson))
- Remove Copilot instructions document ([@matt-edmondson](https://github.com/matt-edmondson))
- Update packages ([@matt-edmondson](https://github.com/matt-edmondson))
- Add LICENSE template ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.2.4-pre.16 (prerelease)
Changes since v1.2.4-pre.15:
- Merge remote-tracking branch 'refs/remotes/origin/main' ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .editorconfig ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitattributes ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitignore ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .mailmap ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .runsettings ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.2.4-pre.15 (prerelease)
Changes since v1.2.4-pre.14:
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .editorconfig ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitattributes ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitignore ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .mailmap ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .runsettings ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.2.4-pre.14 (prerelease)
Changes since v1.2.4-pre.13:
## v1.2.4-pre.13 (prerelease)
Changes since v1.2.4-pre.12:
## v1.2.4-pre.12 (prerelease)
Changes since v1.2.4-pre.11:
## v1.2.4-pre.11 (prerelease)
Changes since v1.2.4-pre.10:
## v1.2.4-pre.10 (prerelease)
Changes since v1.2.4-pre.9:
## v1.2.4-pre.9 (prerelease)
Changes since v1.2.4-pre.8:
## v1.2.4-pre.8 (prerelease)
Changes since v1.2.4-pre.7:
## v1.2.4-pre.7 (prerelease)
Changes since v1.2.4-pre.6:
## v1.2.4-pre.6 (prerelease)
Changes since v1.2.4-pre.5:
## v1.2.4-pre.5 (prerelease)
Changes since v1.2.4-pre.4:
## v1.2.4-pre.4 (prerelease)
Changes since v1.2.4-pre.3:
## v1.2.4-pre.3 (prerelease)
Changes since v1.2.4-pre.2:
## v1.2.4-pre.2 (prerelease)
Changes since v1.2.4-pre.1:
## v1.2.4-pre.1 (prerelease)
Changes since v1.2.3:
- Sync scripts\PSBuild.psm1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.2.3 (patch)
Changes since v1.2.2:
- Remove Directory.Build.props and Directory.Build.targets files; add copyright notices to CredentialCache files. ([@matt-edmondson](https://github.com/matt-edmondson))
- Enhance README with detailed project description, features, installation instructions, and usage examples. Update project SDK references in .csproj files for CredentialCache and its tests. ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.2.3-pre.1 (prerelease)
No significant changes detected since v1.2.3.
## v1.2.2 (patch)
Changes since v1.2.1:
- Remove Copilot instructions document ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.2.2-pre.1 (prerelease)
No significant changes detected since v1.2.2.
## v1.2.1 (patch)
Changes since v1.2.0:
- Update packages ([@matt-edmondson](https://github.com/matt-edmondson))
- Add LICENSE template ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.2.1-pre.3 (prerelease)
Changes since v1.2.1-pre.2:
- Sync scripts\make-version.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\make-changelog.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.2.1-pre.2 (prerelease)
Changes since v1.2.1-pre.1:
- Sync scripts\make-version.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\make-changelog.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .editorconfig ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .gitignore ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.2.1-pre.1 (prerelease)
No significant changes detected since v1.2.1.
## v1.2.0 (minor)
Changes since v1.1.0:
- Apply new editorconfig ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.1.1-pre.1 (prerelease)
Changes since v1.1.0:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.1.0 (minor)
Changes since v1.0.0:
- Make Create method public in ICredentialFactory<T> ([@matt-edmondson](https://github.com/matt-edmondson))
- Add mailmap ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.58 (prerelease)
Changes since v1.0.0-alpha.57:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-alpha.57 (prerelease)
Changes since v1.0.0-alpha.56:
- Sync icon.png ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.56 (prerelease)
Changes since v1.0.0-alpha.55:
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.55 (prerelease)
Changes since v1.0.0-alpha.54:
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.54 (prerelease)
Changes since v1.0.0-alpha.53:
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.53 (prerelease)
Changes since v1.0.0-alpha.52:
- Replace LICENSE file with LICENSE.md and update copyright information ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.52 (prerelease)
Changes since v1.0.0-alpha.51:
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.51 (prerelease)
Changes since v1.0.0-alpha.50:
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync icon.png ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.50 (prerelease)
Changes since v1.0.0-alpha.49:
- Bump the ktsu group with 2 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-alpha.49 (prerelease)
Changes since v1.0.0-alpha.48:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-alpha.48 (prerelease)
Changes since v1.0.0-alpha.47:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-alpha.47 (prerelease)
Changes since v1.0.0-alpha.46:
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.46 (prerelease)
Changes since v1.0.0-alpha.45:
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.45 (prerelease)
Changes since v1.0.0-alpha.44:
## v1.0.0-alpha.44 (prerelease)
Changes since v1.0.0-alpha.43:
## v1.0.0-alpha.43 (prerelease)
Changes since v1.0.0-alpha.42:
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.42 (prerelease)
Changes since v1.0.0-alpha.41:
## v1.0.0-alpha.41 (prerelease)
Changes since v1.0.0-alpha.40:
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync Directory.Build.props ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
- Sync Directory.Build.targets ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-alpha.40 (prerelease)
Changes since v1.0.0-alpha.39:
- Update VERSION to 1.0.0-alpha.40 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.39 (prerelease)
Changes since v1.0.0-alpha.38:
- Update VERSION to 1.0.0-alpha.39 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.38 (prerelease)
Changes since v1.0.0-alpha.37:
- Update VERSION to 1.0.0-alpha.38 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.37 (prerelease)
Changes since v1.0.0-alpha.36:
- Update VERSION to 1.0.0-alpha.37 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.36 (prerelease)
Changes since v1.0.0-alpha.35:
- Update VERSION to 1.0.0-alpha.36 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.35 (prerelease)
Changes since v1.0.0-alpha.34:
- Update VERSION to 1.0.0-alpha.35 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.34 (prerelease)
Changes since v1.0.0-alpha.33:
- Update VERSION to 1.0.0-alpha.34 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.33 (prerelease)
Changes since v1.0.0-alpha.32:
- Update VERSION to 1.0.0-alpha.33 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.32 (prerelease)
Changes since v1.0.0-alpha.31:
- Update VERSION to 1.0.0-alpha.32 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.31 (prerelease)
Changes since v1.0.0-alpha.30:
- Update VERSION to 1.0.0-alpha.31 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.30 (prerelease)
Changes since v1.0.0-alpha.29:
- Update VERSION to 1.0.0-alpha.30 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.29 (prerelease)
Changes since v1.0.0-alpha.28:
- Update VERSION to 1.0.0-alpha.29 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update ktsu.AppDataStorage and ktsu.StrongPaths package references to latest versions ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.28 (prerelease)
Changes since v1.0.0-alpha.27:
- Update VERSION to 1.0.0-alpha.28 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update ktsu.StrongPaths package reference to version 1.1.30 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.27 (prerelease)
Changes since v1.0.0-alpha.26:
- Update VERSION to 1.0.0-alpha.27 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package references to latest versions ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.26 (prerelease)
Changes since v1.0.0-alpha.25:
- Update VERSION to 1.0.0-alpha.26 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.25 (prerelease)
Changes since v1.0.0-alpha.24:
- Update VERSION to 1.0.0-alpha.25 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.24 (prerelease)
Changes since v1.0.0-alpha.23:
- Update VERSION to 1.0.0-alpha.24 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.23 (prerelease)
Changes since v1.0.0-alpha.22:
- Update VERSION to 1.0.0-alpha.23 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.22 (prerelease)
Changes since v1.0.0-alpha.21:
- Update VERSION to 1.0.0-alpha.22 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.21 (prerelease)
Changes since v1.0.0-alpha.20:
- Update VERSION to 1.0.0-alpha.21 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.20 (prerelease)
Changes since v1.0.0-alpha.19:
- Update VERSION to 1.0.0-alpha.20 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.19 (prerelease)
Changes since v1.0.0-alpha.18:
- Update VERSION to 1.0.0-alpha.19 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.18 (prerelease)
Changes since v1.0.0-alpha.17:
- Update VERSION to 1.0.0-alpha.18 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.17 (prerelease)
Changes since v1.0.0-alpha.16:
- Update VERSION to 1.0.0-alpha.17 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.16 (prerelease)
Changes since v1.0.0-alpha.15:
- Update VERSION to 1.0.0-alpha.16 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.15 (prerelease)
Changes since v1.0.0-alpha.14:
- Update VERSION to 1.0.0-alpha.15 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.14 (prerelease)
Changes since v1.0.0-alpha.13:
- Update VERSION to 1.0.0-alpha.14 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.13 (prerelease)
Changes since v1.0.0-alpha.12:
- Update VERSION to 1.0.0-alpha.13 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.12 (prerelease)
Changes since v1.0.0-alpha.11:
- Update VERSION to 1.0.0-alpha.12 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.11 (prerelease)
Changes since v1.0.0-alpha.10:
- Update VERSION to 1.0.0-alpha.11 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.10 (prerelease)
Changes since v1.0.0-alpha.9:
- Update VERSION to 1.0.0-alpha.10 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.9 (prerelease)
Changes since v1.0.0-alpha.8:
- Update VERSION to 1.0.0-alpha.9 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.8 (prerelease)
Changes since v1.0.0-alpha.7:
- Update VERSION to 1.0.0-alpha.8 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.7 (prerelease)
Changes since v1.0.0-alpha.6:
- Update VERSION to 1.0.0-alpha.7 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.6 (prerelease)
Changes since v1.0.0-alpha.5:
- Update VERSION to 1.0.0-alpha.6 ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.5 (prerelease)
Changes since v1.0.0-alpha.4:
- Update VERSION to 1.0.0-alpha.5 ([@matt-edmondson](https://github.com/matt-edmondson))
- Renames to remove references to git ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.4 (prerelease)
Changes since v1.0.0-alpha.3:
- Update VERSION to 1.0.0-alpha.4 ([@matt-edmondson](https://github.com/matt-edmondson))
- Add a way to register credential factories ([@matt-edmondson](https://github.com/matt-edmondson))
- Add credential factories ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.3 (prerelease)
Changes since v1.0.0-alpha.1:
- Update VERSION to 1.0.0-alpha.3 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-alpha.1 (prerelease)
No significant changes detected since v1.0.0.
## v1.0.0
No significant changes detected since v1.0.0-pre.78.
## v1.0.0-pre.78 (prerelease)
Changes since v1.0.0-pre.77:
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-pre.77 (prerelease)
Changes since v1.0.0-pre.76:
## v1.0.0-pre.76 (prerelease)
Changes since v1.0.0-pre.75:
## v1.0.0-pre.75 (prerelease)
Changes since v1.0.0-pre.74:
- Bump MSTest from 3.7.2 to 3.7.3 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-pre.74 (prerelease)
Changes since v1.0.0-pre.73:
## v1.0.0-pre.73 (prerelease)
Changes since v1.0.0-pre.72:
## v1.0.0-pre.72 (prerelease)
Changes since v1.0.0-pre.71:
- Bump MSTest from 3.7.1 to 3.7.2 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-pre.71 (prerelease)
Changes since v1.0.0-pre.70:
- Bump coverlet.collector from 6.0.3 to 6.0.4 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-pre.70 (prerelease)
Changes since v1.0.0-pre.69:
## v1.0.0-pre.69 (prerelease)
Changes since v1.0.0-pre.68:
## v1.0.0-pre.68 (prerelease)
Changes since v1.0.0-pre.67:
- Bump MSTest from 3.7.0 to 3.7.1 ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-pre.67 (prerelease)
Changes since v1.0.0-pre.66:
## v1.0.0-pre.66 (prerelease)
Changes since v1.0.0-pre.65:
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\make-version.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync scripts\make-changelog.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-pre.65 (prerelease)
Changes since v1.0.0-pre.64:
## v1.0.0-pre.64 (prerelease)
Changes since v1.0.0-pre.63:
- Sync .github\workflows\dotnet.yml ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-pre.63 (prerelease)
Changes since v1.0.0-pre.62:
## v1.0.0-pre.62 (prerelease)
Changes since v1.0.0-pre.61:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
- Sync scripts\make-version.ps1 ([@ktsu[bot]](https://github.com/ktsu[bot]))
- Sync .mailmap ([@ktsu[bot]](https://github.com/ktsu[bot]))
## v1.0.0-pre.61 (prerelease)
Changes since v1.0.0-pre.60:
- Add mailmap ([@matt-edmondson](https://github.com/matt-edmondson))
- Add automation scripts for metadata and version management ([@matt-edmondson](https://github.com/matt-edmondson))
## v1.0.0-pre.60 (prerelease)
Changes since v1.0.0-pre.59:
- Bump the ktsu group with 3 updates ([@dependabot[bot]](https://github.com/dependabot[bot]))
- Bump coverlet.collector from 6.0.2 to 6.0.3 ([@dependabot[bot]](https://github.com/dependabot[bot]))
- Bump ktsu.StrongStrings from 1.2.25 to 1.2.26 in the ktsu group ([@dependabot[bot]](https://github.com/dependabot[bot]))
## v1.0.0-pre.59 (prerelease)
- Normalize paths and add JsonSerializer property ([@matt-edmondson](https://github.com/matt-edmondson))
- Update Directory.Build files with path normalization ([@matt-edmondson](https://github.com/matt-edmondson))
- Enhance CredentialCacheTests with new test methods ([@matt-edmondson](https://github.com/matt-edmondson))
- Refactor PersonaGUID and CredentialCache classes ([@matt-edmondson](https://github.com/matt-edmondson))
- Update project rules and add explicit analyzer rules ([@matt-edmondson](https://github.com/matt-edmondson))
- Reorganize and reformat copilot-instructions.md ([@matt-edmondson](https://github.com/matt-edmondson))
- Update build files with new properties and path normalization ([@matt-edmondson](https://github.com/matt-edmondson))
- Add CredentialCache test project and initial test cases ([@matt-edmondson](https://github.com/matt-edmondson))
- Enhance credential management and add documentation ([@matt-edmondson](https://github.com/matt-edmondson))
- Add Additional Best Practices to copilot-instructions.md ([@matt-edmondson](https://github.com/matt-edmondson))
- Add comprehensive project guidelines in copilot-instructions.md ([@matt-edmondson](https://github.com/matt-edmondson))
- Renamed metadata files ([@matt-edmondson](https://github.com/matt-edmondson))
- Replace LICENSE file with LICENSE.md and update copyright information ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.40 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.39 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.38 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.37 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.36 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.35 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.34 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.33 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.32 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.31 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.30 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.29 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update ktsu.AppDataStorage and ktsu.StrongPaths package references to latest versions ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.28 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update ktsu.StrongPaths package reference to version 1.1.30 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.27 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update package references to latest versions ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.26 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.25 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.24 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.23 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.22 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.21 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.20 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.19 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.18 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.17 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.16 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.15 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.14 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.13 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.12 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.11 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.10 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.9 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.8 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.7 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.6 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.5 ([@matt-edmondson](https://github.com/matt-edmondson))
- Renames to remove references to git ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.4 ([@matt-edmondson](https://github.com/matt-edmondson))
- Add a way to register credential factories ([@matt-edmondson](https://github.com/matt-edmondson))
- Add credential factories ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.3 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION to 1.0.0-alpha.1 ([@matt-edmondson](https://github.com/matt-edmondson))
- Update VERSION ([@matt-edmondson](https://github.com/matt-edmondson))
- Initial commit ([@matt-edmondson](https://github.com/matt-edmondson))