.NET SDK
Connect .NET applications to SikkerKey with a machine identity, then read, export, cache, and monitor permitted secrets.
The SikkerKey .NET SDK gives .NET applications secure, read-only access to secrets in your vault. Each client uses a machine identity, so the application can retrieve only the secrets and projects that machine is permitted to access.
#Requirements
.NET 8 or later
A SikkerKey vault
A machine identity with access to the secrets your application needs
Network operations are asynchronous and return Task values. Await them from application services, background workers, and request handlers.
#Install the SDK
dotnet add package SikkerKeyTo install the version covered by this page:
dotnet add package SikkerKey --version 1.3.0#Read your first secret
using SikkerKey;
using var sikkerKey = SikkerKeyClient.Create("vault_...");
var apiKey = await sikkerKey.GetSecretAsync("sk_...");
// Pass apiKey directly to the client or service that needs it.Do not print secret values or include them in application logs.
#Choose a machine identity
Use a standard machine for persistent services and workstations. Use an ephemeral machine for short-lived workloads that should keep their identity only in memory.
Use a standard machine
// Select a registered vault.
using var byVault = SikkerKeyClient.Create("vault_...");
// Load a specific identity file.
using var byPath = SikkerKeyClient.Create(
"/etc/sikkerkey/vaults/vault_.../identity.json");
// Use SIKKERKEY_IDENTITY or select the only registered vault.
using var automatically = SikkerKeyClient.Create();Automatic selection checks SIKKERKEY_IDENTITY first. If it is not set, the SDK selects the identity when exactly one vault is registered under ~/.sikkerkey/vaults/. Select a vault explicitly when several identities are available.
Set SIKKERKEY_HOME when the application uses a different protected identity directory:
export SIKKERKEY_HOME=/var/lib/sikkerkeyUse an ephemeral machine
using var sikkerKey = await SikkerKeyClient.BootstrapInMemoryAsync(
Environment.GetEnvironmentVariable("SIKKERKEY_VAULT_ID")!,
Environment.GetEnvironmentVariable("SIKKERKEY_ENROLLMENT_TOKEN")!,
hostname: "checkout-worker",
name: "Checkout worker");
var apiKey = await sikkerKey.GetSecretAsync("sk_...");BootstrapInMemoryAsync generates an Ed25519 key pair in memory, registers the ephemeral machine, and returns a ready client. It writes no identity or private key to disk, and the private key disappears when the process exits.
The machine follows the access, hostname rules, use limit, and lifetime configured on the enrollment token. The hostname defaults to HOSTNAME and then to serverless. A name pattern configured on the token takes precedence over the requested name.
Keep enrollment tokens in protected runtime configuration and set the machine lifetime and token use limit for the workload's duration and expected concurrency.
#Read secrets
Read a standard secret
var apiKey = await sikkerKey.GetSecretAsync("sk_...");Read a structured secret
var database = await sikkerKey.GetFieldsAsync("sk_...");
var host = database["host"];
var username = database["username"];
var password = database["password"];Read one field directly with:
var password = await sikkerKey.GetFieldAsync(
"sk_...",
"password");GetFieldsAsync returns a Dictionary<string, string>. A non-structured value produces SecretStructureException; a missing field produces FieldNotFoundException with the available field names.
#Discover and export secrets
var secrets = await sikkerKey.ListSecretsAsync();
var projectSecrets = await sikkerKey.ListSecretsByProjectAsync("proj_...");
foreach (var secret in secrets)
Console.WriteLine($"{secret.Id}: {secret.Name}");Each SecretListItem includes the secret ID and name, with optional project and structured-field metadata. Listing returns metadata, not secret values.
Export application configuration
var allConfiguration = await sikkerKey.ExportAsync();
var projectConfiguration = await sikkerKey.ExportAsync("proj_...");Export returns a Dictionary<string, string> in one request. Names use uppercase environment-variable format, and structured secrets are flattened into entries such as DATABASE_HOST and DATABASE_PASSWORD.
#Enable encrypted fallback
using var sikkerKey = SikkerKeyClient
.Create("vault_...")
.EnableCache(new CacheOptions
{
MaxAge = TimeSpan.FromHours(1),
OnFallback = (secretId, cachedAt) =>
logger.LogWarning(
"Using cached value for {SecretId} from epoch {CachedAt}",
secretId,
cachedAt)
});Encrypted fallback is opt-in. Successful reads are encrypted locally with AES-256-GCM using a key derived from the machine identity and vault. Omit MaxAge for no automatic expiry. OnFallback runs only when the SDK serves a cached value.
Fallback is limited to network failures, timeouts, and temporary gateway or service availability responses. Authentication failures, denied access, missing secrets, rate limits, and other authoritative responses are returned to the application.
Cache entries are bound to the machine, vault, secret, and creation time. The format is compatible with SikkerKey CLI and the other SikkerKey SDKs. Use it with a persistent, protected identity directory.
#Monitor secrets for changes
sikkerKey.Watch("sk_...", change =>
{
switch (change.Status)
{
case WatchStatus.Changed:
ReloadClient(change.Value, change.Fields);
break;
case WatchStatus.Deleted:
logger.LogWarning("Secret {SecretId} was deleted", change.SecretId);
break;
case WatchStatus.AccessDenied:
logger.LogWarning("Access to {SecretId} was removed", change.SecretId);
break;
case WatchStatus.Error:
logger.LogError("Secret update failed: {Error}", change.Error);
break;
}
});The SDK checks watched secrets on a background task every 15 seconds by default. Changed events include the current value and parsed fields when the secret is structured. Deleted and inaccessible secrets are removed from the watch list, and a failed poll is tried again during the next interval.
Callbacks execute as part of the polling task, so hand slow or blocking work to your application's queue or background service.
sikkerKey.SetPollInterval(30); // seconds; minimum 10
sikkerKey.Unwatch("sk_...");
sikkerKey.Close();Close stops monitoring while leaving the client available for reads. Dispose releases the HTTP client and polling resources completely; prefer using for the client lifetime.
#Work with vaults and inspect the client
var vaultIds = SikkerKeyClient.ListVaults();
using var production = SikkerKeyClient.Create("vault_...");
using var staging = SikkerKeyClient.Create("vault_...");Create a separate client for each vault. The active identity is available through MachineId, MachineName, VaultId, and ApiUrl for application diagnostics.
#Handle errors
try
{
var value = await sikkerKey.GetSecretAsync("sk_...");
}
catch (NotFoundException)
{
HandleMissingSecret();
}
catch (AccessDeniedException)
{
HandleRemovedAccess();
}
catch (AuthenticationException)
{
HandleAuthenticationFailure();
}
catch (RateLimitedException)
{
ScheduleLaterRetry();
}
catch (ApiException error)
{
RecordServiceError(error.HttpStatus);
}
catch (ConfigurationException)
{
HandleIdentityConfiguration();
}All SDK exceptions extend SikkerKeyException. Typed exceptions cover configuration, authentication, access, missing resources, conflicts, rate limits, temporary service availability, invalid structured data, and missing fields. Network failures and timeouts use ApiException with HttpStatus == 0.
Retries and timeout
Authenticated requests retry network failures, timeouts, and HTTP 429 or 503 responses up to three times, waiting 1, 2, and 4 seconds. Every attempt uses a fresh timestamp and nonce. The shared HTTP client has a 15-second timeout.
#Method reference
Task | Method |
|---|---|
Connect with a registered identity |
|
Create an ephemeral identity |
|
Read a standard secret |
|
Read structured fields |
|
List secrets |
|
Export configuration |
|
Enable encrypted fallback |
|
Monitor a secret |
|
Stop monitoring |
|
List local vaults |
|
Release the client |
|
#Source code and license
The .NET SDK is open source under the MIT License. Review the source, report an issue, or contribute through the SikkerKeyOfficial GitHub organization.