feat(audit): persist OPC UA certificate-trust decisions to the central audit log (ScadaBridge#43)

New AuditChannel.Security with AuditKind.CertTrust / CertTrustRemove (appended, ordinals stable).
Both central entry points - the management actor handlers and the Central UI CertManagementService -
write a best-effort ICentralAuditWriter row after the site outcome is known (Delivered when all
reachable site nodes acked, Failed otherwise, incl. relay timeouts), naming actor, site, thumbprint
and connection. Shared builder: CertTrustAuditEvents.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-11-09 15:17:03 -05:00
parent f98369a786
commit f5eed5e8fd
10 changed files with 322 additions and 22 deletions
@@ -13,7 +13,7 @@ public class AuditEnumTests
[Fact]
public void AuditChannel_HasExactlyExpectedMembers()
{
var expected = new[] { "ApiOutbound", "DbOutbound", "Notification", "ApiInbound", "SecuredWrite", "Cluster", "ScriptTrace" };
var expected = new[] { "ApiOutbound", "DbOutbound", "Notification", "ApiInbound", "SecuredWrite", "Cluster", "ScriptTrace", "Security" };
var actual = Enum.GetValues(typeof(AuditChannel))
.Cast<AuditChannel>()
.Select(x => x.ToString())
@@ -23,9 +23,9 @@ public class AuditEnumTests
Assert.Equal(expected, actual);
}
/// <summary>Verifies that audit kind has exactly twenty two expected members.</summary>
/// <summary>Verifies that audit kind has exactly twenty four expected members.</summary>
[Fact]
public void AuditKind_HasExactlyTwentyTwoExpectedMembers()
public void AuditKind_HasExactlyTwentyFourExpectedMembers()
{
var expected = new[]
{
@@ -37,13 +37,14 @@ public class AuditEnumTests
"ReconciliationAbandoned",
"ManualFailover",
"RouteCall", "ScriptRun", "AttributeWrite", "AttributeWait", "ScriptLog",
"CertTrust", "CertTrustRemove",
};
var actual = Enum.GetValues(typeof(AuditKind))
.Cast<AuditKind>()
.Select(x => x.ToString())
.ToArray();
Assert.Equal(22, actual.Length);
Assert.Equal(24, actual.Length);
Assert.Equal(expected, actual);
}