2858e42e80
Claude-Session: https://claude.ai/code/session_016J6isfcgqy4SB2RK3ZvFvT
65 lines
2.5 KiB
C#
65 lines
2.5 KiB
C#
using ZB.MOM.WW.Telemetry.Serilog;
|
|
|
|
namespace ZB.MOM.WW.MxGateway.Server.Diagnostics;
|
|
|
|
/// <summary>
|
|
/// Adapts the static <see cref="GatewayLogRedactor"/> to the shared <see cref="ILogRedactor"/> seam
|
|
/// so the telemetry RedactionEnricher masks API-key/credential material on every log event.
|
|
/// </summary>
|
|
public sealed class GatewayLogRedactorSeam : ILogRedactor
|
|
{
|
|
private static readonly string[] IdentityKeys = ["ClientIdentity", "authorization", "Authorization"];
|
|
|
|
/// <summary>Property name carrying the MXAccess command method, which gates value redaction.</summary>
|
|
private const string CommandMethodProperty = "CommandMethod";
|
|
|
|
/// <summary>Property name carrying a command payload value that may bear credentials.</summary>
|
|
private const string CommandValueProperty = "CommandValue";
|
|
|
|
/// <summary>
|
|
/// Masks API-key/credential material in known identity-bearing log properties, and any
|
|
/// command payload value.
|
|
/// </summary>
|
|
/// <param name="properties">The log event property dictionary to redact in place.</param>
|
|
public void Redact(IDictionary<string, object?> 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);
|
|
}
|
|
}
|
|
|
|
RedactCommandValue(properties);
|
|
|
|
foreach (string key in properties.Keys.ToList())
|
|
{
|
|
if (key.Contains("password", StringComparison.OrdinalIgnoreCase) && properties[key] is not null)
|
|
{
|
|
properties[key] = GatewayLogRedactor.RedactedValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Masks a command payload value. Value logging is off here — the seam exposes no opt-in — so
|
|
/// every non-null value is masked, credential-bearing command or not.
|
|
/// </summary>
|
|
/// <param name="properties">The log event property dictionary to redact in place.</param>
|
|
private static void RedactCommandValue(IDictionary<string, object?> properties)
|
|
{
|
|
if (!properties.TryGetValue(CommandValueProperty, out object? value) || value is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
string? commandMethod = properties.TryGetValue(CommandMethodProperty, out object? method)
|
|
? method as string
|
|
: null;
|
|
|
|
properties[CommandValueProperty] = GatewayLogRedactor.RedactCommandValue(commandMethod, value);
|
|
}
|
|
}
|