|
1 | 1 | # ByteGuard.SecurityLogger  |
2 | 2 |
|
3 | | -`ByteGuard.SecurityLogger` brings the [OWASP Logging Vocabulary](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Vocabulary_Cheat_Sheet.html) to .NET by exposing a set of strongly-typed `ILogger` extension methods for common security and audit events. |
| 3 | +`ByteGuard.SecurityLogger` is a lightweight `ILogger` wrapper that brings the [OWASP Logging Vocabulary](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Vocabulary_Cheat_Sheet.html) to .NET by exposing a set of strongly-typed `ILogger` methods for common security and audit events. |
4 | 4 |
|
5 | 5 | Instead of ad-hoc log messages like `"login ok"` or `"unauthorized"`, you log standardized, structured events (e.g. `authn_login_success`, `authz_fail`) with consistent property names. This makes your security logs easier to search, alert on, correlate, and reason about, regardless of whether you send logs to Serilog, NLog, Application Insights, Elasticsearch, or something else. |
| 6 | + |
| 7 | +This package is **provider-agnostic**: it logs through `Microsoft.Extensions.Logging` so you can keep using your existing logging stack (Serilog, NLog, Application Insights, Seq, etc.) via normal logging providers. |
| 8 | + |
| 9 | +## Features |
| 10 | + |
| 11 | +- ✅ OWASP-aligned security event vocabulary |
| 12 | +- ✅ Structured logging via `ILogger` scopes/properties |
| 13 | +- ✅ Works with any `Microsoft.Extensions.ILogger` provider (_NLog, Serilog, etc._) |
| 14 | + |
| 15 | +## Getting Started |
| 16 | + |
| 17 | +### Installation |
| 18 | + |
| 19 | +This package is published and installed via [NuGet](https://www.nuget.org/packages/ByteGuard.SecurityLogger). |
| 20 | + |
| 21 | +Reference the package in your project: |
| 22 | + |
| 23 | +```bash |
| 24 | +dotnet add package ByteGuard.SecurityLogger |
| 25 | +``` |
| 26 | + |
| 27 | +## Usage |
| 28 | + |
| 29 | +Instantiate a new `SecurityLogger` instance using either the constructor or the `ILogger` extensions: `AsSecurityLogger()`. |
| 30 | + |
| 31 | +```csharp |
| 32 | +ILogger logger = /* resolve or create ILogger */ |
| 33 | + |
| 34 | +var configuration = new SecurityLoggerConfiguration |
| 35 | +{ |
| 36 | + AppId = "MyApp" |
| 37 | +} |
| 38 | + |
| 39 | +// Using constructor |
| 40 | +var securityLogger = new SecurityLogger(logger, configuration); |
| 41 | + |
| 42 | +// Using ILogger extensions |
| 43 | +var securityLogger = logger.AsSecurityLogger(configuration); |
| 44 | +``` |
| 45 | + |
| 46 | +Log your security events: |
| 47 | + |
| 48 | +```csharp |
| 49 | +var user = //... |
| 50 | +
|
| 51 | +securityLogger.AuthnLoginSuccess( |
| 52 | + "User {UserId} successfully logged in.", |
| 53 | + userId: user.Id, |
| 54 | + args: user.Id |
| 55 | +) |
| 56 | +``` |
| 57 | + |
| 58 | +## API Design |
| 59 | + |
| 60 | +`ByteGuard.SecurityLogger` implements the **full OWASP Logging Vocabulary**: every event type defined by OWASP exists as a corresponding method on `SecurityLogger`. |
| 61 | + |
| 62 | +### One method per event (plus an overload with metadata) |
| 63 | + |
| 64 | +For each OWASP event type, `SecurityLogger` exposes two overloads: |
| 65 | + |
| 66 | +1. A minimal overload for logging the event with just the event label parameters. |
| 67 | + |
| 68 | +```csharp |
| 69 | +securityLogger.Log{event}( |
| 70 | + string message, |
| 71 | + /* event label arguments (varies by event) */, |
| 72 | + params object?[] args |
| 73 | +) |
| 74 | +``` |
| 75 | + |
| 76 | +2. An overload that additionally accepts a `SecurityEventMetadata` object for richer, OWASP-recommended context (_client IP, hostname, request URI, etc._). |
| 77 | + |
| 78 | +```csharp |
| 79 | +securityLogger.Log{event}( |
| 80 | + string message, |
| 81 | + /* event label arguments (varies by event) */, |
| 82 | + SecurityEventMetadata metadata, |
| 83 | + params object?[] args |
| 84 | +) |
| 85 | +``` |
| 86 | + |
| 87 | +### Parameter order (always the same) |
| 88 | + |
| 89 | +| Parameter | Description | |
| 90 | +| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 91 | +| `message` | The human readable log message (_typically a message template_) | |
| 92 | +| Event label arguments | These are the values required to form the OWASP event label, e.g.: `authn_login_success:{userId}` and `authz_fail:{userId,resource}` (_depending on the even type_). These are all nullable and will not be present in the label if provided as `null`. | |
| 93 | +| `metadata` | Additional structured context recommended by OWASP (source IP, host, request URI, etc.) (_Only in the metadata method overload_) | |
| 94 | +| `args` | The message template arguments from the 1st parameters | |
| 95 | + |
| 96 | +### Example |
| 97 | + |
| 98 | +If an event label requires a `userId`, the call becomes: |
| 99 | + |
| 100 | +```csharp |
| 101 | +// Providing user ID produces label: authn_login_success:userOne |
| 102 | +var userId = "userOne"; |
| 103 | +securityLogger.LogAuthnLoginSuccess( |
| 104 | + "User {UserId} logged in successfully from {Ip}", // Message template |
| 105 | + userId, // Label parameters |
| 106 | + userId, ip); // Template args |
| 107 | +
|
| 108 | +// Without providing user ID produces label: authn_login_success |
| 109 | +securityLogger.LogAuthnLoginSuccess( |
| 110 | + "User {UserId} logged in successfully from {Ip}", // Message template |
| 111 | + null, // Label parameters |
| 112 | + userId, ip); // Template args |
| 113 | +``` |
| 114 | + |
| 115 | +If you want to add OWASP-style context, use the metadata overload: |
| 116 | + |
| 117 | +```csharp |
| 118 | +securityLogger.LogAuthnLoginSuccess( |
| 119 | + "User {UserId} logged in successfully from {Ip}", // Message template |
| 120 | + userId, // Label parameters |
| 121 | + new SecurityEventMetadata // Event metadata |
| 122 | + { |
| 123 | + SourceIp = ip, |
| 124 | + Hostname = host, |
| 125 | + RequestUri = requestUri |
| 126 | + }, |
| 127 | + userId, ip); // Template args |
| 128 | +``` |
| 129 | + |
| 130 | +> ℹ️ **Note:** The exact label arguments vary per event type, based on the OWASP Logging Vocabulary definition. |
| 131 | +
|
| 132 | +## Configuration |
| 133 | + |
| 134 | +The `SecurityLogger` supports the following configurations: |
| 135 | + |
| 136 | +| Configuration | Required | Default | Description | |
| 137 | +| ------------------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | |
| 138 | +| `AppId` | Yes | N/A | Application identifier added to the log message, to ensure logs are easy to find for the given application | |
| 139 | +| `DisableSourceIpLogging` | No | `true` | Whether to log the `SourceIp` if provided (_logging user IP address may be useful for detection and response, but may be considered personally identifiable information when combined with other data and subject to regulation or deletion requests_) | |
| 140 | + |
| 141 | +## Supported events |
| 142 | + |
| 143 | +All supported events can be seen in the [WIKI](https://github.com/ByteGuard-HQ/byteguard-security-logger/wiki/Supported-events) |
| 144 | + |
| 145 | +## License |
| 146 | + |
| 147 | +_ByteGuard.SecurityLogger is Copyright © ByteGuard Contributors - Provided under the MIT license._ |
0 commit comments