fix(security): wrap the ConfigDb key store on admin nodes + registration guard

This commit is contained in:
Joseph Doherty
2026-08-20 09:45:08 -04:00
parent 6048257dfe
commit 39a10a277a
7 changed files with 100 additions and 9 deletions
@@ -67,9 +67,20 @@ public static class DataPlaneAuthRegistration
// NOT from IClusterRoleInfo: that depends on the ActorSystem, and the same options-not-services
// rule is what keeps the redundancy-singleton registration in Program.cs from recursing into
// ActorSystem construction. Null on a node with no cluster-{ClusterId} role ⇒ no filter.
services.AddSingleton<IApiKeyStore>(sp => new ConfigDbApiKeyStore(
sp.GetRequiredService<IDbContextFactory<OtOpcUaConfigDbContext>>(),
ConfigDbApiKeyStore.ResolveClusterId(sp.GetRequiredService<IOptions<AkkaClusterOptions>>().Value)));
//
// arch-review 03/S18 — and it is WRAPPED. The lookup runs inline in the SDK's synchronous
// impersonation callback, under a SessionManager-wide lock, with CancellationToken.None: an
// unanswered ConfigDb query therefore stalls every session activation in the server. The
// decorator adds the deadline that bounds that, plus a short TTL that turns a burst of
// activations into one round trip. It cannot admit anything the inner store did not.
services.AddSingleton<IApiKeyStore>(sp => new BoundedApiKeyStore(
new ConfigDbApiKeyStore(
sp.GetRequiredService<IDbContextFactory<OtOpcUaConfigDbContext>>(),
ConfigDbApiKeyStore.ResolveClusterId(
sp.GetRequiredService<IOptions<AkkaClusterOptions>>().Value)),
sp.GetRequiredService<IOptions<ApiKeyOptions>>(),
sp.GetRequiredService<ILoggerFactory>().CreateLogger<BoundedApiKeyStore>(),
sp.GetRequiredService<TimeProvider>()));
services.AddSingleton<IOpcUaUserAuthenticator, ApiKeyOpcUaUserAuthenticator>();
// Minting surface for the AdminUI. Same node condition as the store above: both need a ConfigDb.