feat(gateway): thread ClientCorrelationId into constraint-denial audit (§1.2)
This commit is contained in:
@@ -69,7 +69,7 @@ public sealed class ConstraintEnforcerTests
|
||||
CancellationToken.None);
|
||||
Assert.NotNull(failure);
|
||||
|
||||
await enforcer.RecordDenialAsync(identity, "Write", "42", failure, CancellationToken.None);
|
||||
await enforcer.RecordDenialAsync(identity, "Write", "42", failure, correlationId: null, CancellationToken.None);
|
||||
|
||||
AuditEvent auditEvent = Assert.Single(auditWriter.Events);
|
||||
Assert.Equal("operator01", auditEvent.Actor);
|
||||
@@ -83,6 +83,43 @@ public sealed class ConstraintEnforcerTests
|
||||
Assert.Null(auditEvent.CorrelationId);
|
||||
}
|
||||
|
||||
/// <summary>A denial carrying a parseable correlation id stores it on the audit record.</summary>
|
||||
[Fact]
|
||||
public async Task RecordDenialAsync_WithGuidCorrelationId_StoresCorrelationId()
|
||||
{
|
||||
ConstraintEnforcer enforcer = CreateEnforcer(out FakeAuditWriter auditWriter);
|
||||
Guid correlationId = Guid.NewGuid();
|
||||
|
||||
await enforcer.RecordDenialAsync(
|
||||
identity: null,
|
||||
"Read",
|
||||
"Secret.Tag",
|
||||
new ConstraintFailure("read_scope", "Tag is outside the API key read scope."),
|
||||
correlationId.ToString(),
|
||||
CancellationToken.None);
|
||||
|
||||
AuditEvent auditEvent = Assert.Single(auditWriter.Events);
|
||||
Assert.Equal(correlationId, auditEvent.CorrelationId);
|
||||
}
|
||||
|
||||
/// <summary>A denial with a non-GUID correlation id leaves the audit correlation id null.</summary>
|
||||
[Fact]
|
||||
public async Task RecordDenialAsync_WithNonGuidCorrelationId_LeavesCorrelationIdNull()
|
||||
{
|
||||
ConstraintEnforcer enforcer = CreateEnforcer(out FakeAuditWriter auditWriter);
|
||||
|
||||
await enforcer.RecordDenialAsync(
|
||||
identity: null,
|
||||
"Read",
|
||||
"Secret.Tag",
|
||||
new ConstraintFailure("read_scope", "Tag is outside the API key read scope."),
|
||||
"cli-xyz",
|
||||
CancellationToken.None);
|
||||
|
||||
AuditEvent auditEvent = Assert.Single(auditWriter.Events);
|
||||
Assert.Null(auditEvent.CorrelationId);
|
||||
}
|
||||
|
||||
/// <summary>A denial with no identity records the canonical "anonymous" actor.</summary>
|
||||
[Fact]
|
||||
public async Task RecordDenialAsync_WithoutIdentity_UsesAnonymousActor()
|
||||
@@ -94,6 +131,7 @@ public sealed class ConstraintEnforcerTests
|
||||
"Read",
|
||||
"Secret.Tag",
|
||||
new ConstraintFailure("read_scope", "Tag is outside the API key read scope."),
|
||||
correlationId: null,
|
||||
CancellationToken.None);
|
||||
|
||||
AuditEvent auditEvent = Assert.Single(auditWriter.Events);
|
||||
|
||||
Reference in New Issue
Block a user