AuthServer
Production Readiness: Signing Keys
Understand automatic SqlOS signing-key protection and make it durable for production.
You do not need to configure signing-key storage while developing with SqlOS. AddSqlOS enables the built-in, cross-platform protection automatically.
Review this page when preparing a production deployment, especially when deploying containers, replacing hosts, or running more than one token-issuing instance.
Every access token issued by SqlOS has a digital signature. APIs trust that signature as proof that the token really came from your SqlOS server and was not changed afterward.
The private signing key is therefore more powerful than a user password. Someone who steals it can mint convincing tokens for arbitrary users without completing login, MFA, or session checks. That is why storing the private key as plaintext beside normal application data is a P0 security issue: a read-only database leak becomes a complete token-issuer compromise.
SqlOS now stores only the public key and an opaque encrypted reference in SQL Server. The private key is never persisted there as plaintext.
ASP.NET Core Data Protection is a cross-platform .NET facility for encrypting application secrets. A key ring is its small, automatically managed set of encryption keys.
Think of it as the key to a lockbox:
This protection stays inside the ASP.NET Core application and does not make a network request. In the default development and single-host path, ASP.NET Core manages it locally. Its application discriminator isolates applications that use the same machine-level key directory, so one application cannot open another application's signing-key references.
This is the default and requires no signing-key code:
builder.AddSqlOS<AppDbContext>(
db => db.UseSqlServer(connectionString));ASP.NET Core selects its normal key repository for the current platform and host. Windows, Linux, and macOS use the same SqlOS code path. Separate applications are isolated, and an unreadable or lost key fails closed instead of silently replacing the active signing key.
This is the intended experience for development, evaluation, and a normal single-host application.
Before production, confirm that the host's Data Protection storage survives application restarts and machine replacement. An ephemeral container filesystem does not satisfy that requirement.
Use a durable filesystem path when the default host storage is ephemeral. Use the same protected path and application name for every replica when multiple instances issue tokens:
using Microsoft.AspNetCore.DataProtection;
var keyRingPath = builder.Configuration["SqlOS:DataProtection:KeyRingPath"]
?? throw new InvalidOperationException(
"Configure durable Data Protection storage for this production deployment.");
builder.Services.AddDataProtection()
.SetApplicationName("Acme.Identity")
.PersistKeysToFileSystem(new DirectoryInfo(keyRingPath));
builder.AddSqlOS<AppDbContext>(
db => db.UseSqlServer(connectionString));The path can be a protected local volume for one host or a shared filesystem for replicas.
Production responsibilities:
SetApplicationName value.SqlOS refuses token issuance when the active signing key cannot be opened. It does not silently create a replacement, because one replica rotating around a missing key can split the deployment and invalidate tokens unpredictably.
Creation and rotation are serialized in SQL Server. SqlOS verifies that protected private material matches the stored public key, keeps retired public keys in JWKS for the configured grace window, and prevents cleanup from deleting material still referenced by an active key. Each replica performs a single-flight refresh when it encounters an unknown kid; refreshes across distinct identifiers are rate-limited and retained negative identifiers are bounded. An unavailable database leaves the unknown token rejected against the last known key set.
Treat the database and the Data Protection key ring as one recovery set. Losing either one is an availability incident. Stealing both is a signing-key compromise.
Both supported approaches are covered by executable tests:
SqlOSCryptoServiceTests;AuthServerSigningKeyResilienceIntegrationTests.The SQL integration suite also verifies lost-ring failure, concurrent startup and rotation, database-only compromise, JWKS grace behavior, signing-key lifecycle invariants, and corrupted internal references through test-only fault injection.