diff --git a/src/ZB.MOM.WW.MxGateway.Server/Diagnostics/GatewayLogRedactorSeam.cs b/src/ZB.MOM.WW.MxGateway.Server/Diagnostics/GatewayLogRedactorSeam.cs new file mode 100644 index 0000000..0beab89 --- /dev/null +++ b/src/ZB.MOM.WW.MxGateway.Server/Diagnostics/GatewayLogRedactorSeam.cs @@ -0,0 +1,28 @@ +using ZB.MOM.WW.Telemetry.Serilog; + +namespace ZB.MOM.WW.MxGateway.Server.Diagnostics; + +/// +/// Adapts the static to the shared seam +/// so the telemetry RedactionEnricher masks API-key/credential material on every log event. +/// +public sealed class GatewayLogRedactorSeam : ILogRedactor +{ + private static readonly string[] IdentityKeys = ["ClientIdentity", "authorization", "Authorization"]; + + /// + /// Masks API-key/credential material in known identity-bearing log properties. + /// + /// The log event property dictionary to redact in place. + public void Redact(IDictionary properties) + { + ArgumentNullException.ThrowIfNull(properties); + foreach (var key in IdentityKeys) + { + if (properties.TryGetValue(key, out var value) && value is string s) + { + properties[key] = GatewayLogRedactor.RedactClientIdentity(s); + } + } + } +} diff --git a/src/ZB.MOM.WW.MxGateway.Server/GatewayApplication.cs b/src/ZB.MOM.WW.MxGateway.Server/GatewayApplication.cs index 4ff780f..621e630 100644 --- a/src/ZB.MOM.WW.MxGateway.Server/GatewayApplication.cs +++ b/src/ZB.MOM.WW.MxGateway.Server/GatewayApplication.cs @@ -73,6 +73,7 @@ public static class GatewayApplication failureStatus: null, tags: new[] { ZbHealthTags.Ready }); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/src/ZB.MOM.WW.MxGateway.Tests/Diagnostics/GatewayLogRedactorSeamTests.cs b/src/ZB.MOM.WW.MxGateway.Tests/Diagnostics/GatewayLogRedactorSeamTests.cs new file mode 100644 index 0000000..494808e --- /dev/null +++ b/src/ZB.MOM.WW.MxGateway.Tests/Diagnostics/GatewayLogRedactorSeamTests.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using ZB.MOM.WW.MxGateway.Server.Diagnostics; +using Xunit; + +public class GatewayLogRedactorSeamTests +{ + [Fact] + public void Redact_MasksApiKeyInClientIdentity() + { + var redactor = new GatewayLogRedactorSeam(); + var props = new Dictionary { ["ClientIdentity"] = "Bearer mxgw_operator01_super-secret" }; + redactor.Redact(props); + Assert.Equal("Bearer mxgw_operator01_[redacted]", props["ClientIdentity"]); + } +}