refactor(acl): delete the LDAP data-plane authenticator and its tests (#520)
Stage 2b. LdapOpcUaUserAuthenticator was left registered nowhere by stage 2a; this removes it, its three test files, and the config surface that existed only to serve it. Deleted: LdapOpcUaUserAuthenticator, LdapOpcUaUserAuthenticatorTests, LdapAuthResilienceTests, LdapGlauthOutageLiveTests (19 tests). Also removed four Security:Ldap keys — AuthTimeoutMs, MaxConcurrentAuthentications, OutageFailureThreshold, OutageCooldownSeconds — plus their validator rules and binding/validator test coverage. Verified first that the ONLY consumers were the deleted class and the validator rules asserting them; none appear in any checked-in appsettings. Leaving them would have created exactly the dead-config surface #521/#524/#525 were filed to clear up. Worth stating why that resilience machinery does not need relocating rather than just deleting. It existed because the OPC UA SDK raises impersonation SYNCHRONOUSLY under a SessionManager-wide event lock, so a hung LDAP bind there serialized every session activation server-wide — Anonymous and X509 included. Key verification is one indexed lookup plus one HMAC with no network I/O, so the hazard the wall-clock bound, concurrency cap and outage circuit guarded against no longer exists on that path. LDAP now runs only on AdminUI login, an ordinary async request path where a slow directory affects the one request making it. ConnectionTimeoutMs is RETAINED: it is projected into the shared library and is not authenticator-specific. Docs corrected rather than left to rot: - CLAUDE.md's "LDAP Authentication" section described the deleted file as the data-plane authenticator. Rewritten, including a warning not to "restore" it on seeing the LDAP wiring that AdminUI legitimately still needs. - infra/README §5b (the GLAuth outage live gate) marked RETIRED with the reason, rather than silently dropped — the harness GLAuth is still used by OTOPCUA_HARNESS_USE_LDAP=1 and is unaffected. - docs/security.md's five-key resilience table cut to the one surviving key, and a new API-key identity section added. Historical archreview/ records are left as-is; they are dated accounts. Host.IntegrationTests 211 tests (was 230, i.e. exactly the 19 removed) with the same 3 pre-existing failures verified against clean master. Host 37, Security 89. Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
This commit is contained in:
@@ -48,17 +48,12 @@ public sealed class LdapOptionsValidator : OptionsValidatorBase<LdapOptions>
|
||||
!(options.Transport == LdapTransport.None && !options.AllowInsecure),
|
||||
"LDAP transport is None (plaintext) but AllowInsecure is false — set Transport to Ldaps/StartTls or set AllowInsecure for dev.");
|
||||
|
||||
// S2 resilience knobs — a non-positive timeout / concurrency bound would silently disable the
|
||||
// wall-clock/concurrency protection the OPC UA data-plane authenticator relies on, so fail fast.
|
||||
// A non-positive connect/search timeout would leave the shared library unbounded against a hung
|
||||
// directory, so fail fast. The other four S2 knobs validated here (AuthTimeoutMs,
|
||||
// MaxConcurrentAuthentications, OutageFailureThreshold, OutageCooldownSeconds) went with
|
||||
// LdapOpcUaUserAuthenticator in #520 — they guarded an LDAP bind running inline on OPC UA
|
||||
// session activation, and no remaining LDAP consumer runs on that path.
|
||||
builder.RequireThat(options.ConnectionTimeoutMs > 0,
|
||||
"Ldap:ConnectionTimeoutMs must be > 0.");
|
||||
builder.RequireThat(options.AuthTimeoutMs > 0,
|
||||
"Ldap:AuthTimeoutMs must be > 0.");
|
||||
builder.RequireThat(options.MaxConcurrentAuthentications > 0,
|
||||
"Ldap:MaxConcurrentAuthentications must be > 0.");
|
||||
// An open circuit with no cooldown would re-probe LDAP on every call — pointless. Only enforce
|
||||
// a positive cooldown when the circuit is actually enabled (OutageFailureThreshold > 0; 0 disables).
|
||||
builder.RequireThat(options.OutageFailureThreshold <= 0 || options.OutageCooldownSeconds > 0,
|
||||
"Ldap:OutageCooldownSeconds must be > 0 when Ldap:OutageFailureThreshold > 0 (0 disables the circuit).");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user