Cerbi.Governance.Core
2.2.33
See the version list below for details.
dotnet add package Cerbi.Governance.Core --version 2.2.33
NuGet\Install-Package Cerbi.Governance.Core -Version 2.2.33
<PackageReference Include="Cerbi.Governance.Core" Version="2.2.33" />
<PackageVersion Include="Cerbi.Governance.Core" Version="2.2.33" />
<PackageReference Include="Cerbi.Governance.Core" />
paket add Cerbi.Governance.Core --version 2.2.33
#r "nuget: Cerbi.Governance.Core, 2.2.33"
#:package Cerbi.Governance.Core@2.2.33
#addin nuget:?package=Cerbi.Governance.Core&version=2.2.33
#tool nuget:?package=Cerbi.Governance.Core&version=2.2.33
Cerbi.Governance.Core
v2.2.0 — The canonical governance engine for the CerbiShield logger ecosystem.
Cerbi.Governance.Core provides compile-time and runtime governance enforcement for structured logging across .NET applications. It is used by all CerbiShield logger plugins (CerbiStream, Serilog, MEL, NLog) and the CerbiShield Dashboard to define, validate, and score governance profiles.
Why Canonical Profile
Prior to v2.2.0, the codebase maintained two incompatible profile models:
| Model | Used By | FieldSeverities Type | Issues |
|---|---|---|---|
LogProfile (legacy) |
Runtime loggers, GovernanceConfigLoader |
Dict<string, string> |
No type safety, no metadata, no Dashboard compatibility |
Profile (canonical) |
Dashboard, GovernanceValidator, GovernanceRuntime |
Dict<string, SeverityLevel> |
Strongly-typed enums, flat schema, Dashboard JSON format |
This dual-model problem meant:
- Dashboard rule templates produced
ProfileJSON that loggers couldn't read - Runtime loggers used
LogProfileJSON that the Dashboard couldn't render - Two serialization formats, two validation paths, two sets of bugs
v2.2.0 eliminates the legacy model. The entire stack — Dashboard → GovernanceApi → GovernanceRuntime → Governance.Core → Logger plugins — now uses a single canonical Profile object. One JSON format. One validation path. One source of truth.
Key Features
Profile— Single canonical governance profile model with strongly-typed enumsSeverityLevelenum:Info,Warn,Error,ForbiddenFieldTypeenum:String,Int,Decimal,Guid,DateTime,Bool,Object,ArrayProfileStatusenum:Draft,PublishedEncryptionModeenum:None,Base64,AES
SensitiveFieldCatalog— Built-in sensitive field detection with 11 high-confidence patterns (zero-config PII protection)GovernanceConfigLoader— Static loader that reads canonical Profile JSON from file, with FileSystemWatcher hot-reloadGovernanceHelper— Runtime validation of log entries against loaded Profile (required fields, disallowed fields, field types, enum constraints, encryption, scoring) plus built-in sensitive field detectionGovernanceValidator— Structural validation of Profile definitions (name, appName, version, required properties)ScoringSettings— Configurable scoring weights by severity, plugin weights, scoring version- Roslyn Helpers —
ExtractLoggedFieldsfor compile-time field analysis fromDictionary<string, object>expressions
🛡️ Built-in Sensitive Field Detection (SensitiveFieldCatalog)
Value from day zero — even without configuring any governance profile, CerbiStream and all Cerbi logger plugins automatically detect and warn about common sensitive fields in your logs. Install, log, and immediately get governance feedback.
How It Works
SensitiveFieldCatalog provides a static, pre-cached catalog of 11 high-confidence sensitive field patterns. These are loaded at class initialization (static readonly) with zero per-request allocation. When a log entry contains a field matching one of these patterns, the governance engine flags it — no profile configuration required.
Built-in Patterns
| Pattern | Default Action | Why It Matters |
|---|---|---|
password |
Block | Credential leakage |
secret |
Block | Secret/key exposure |
accesstoken |
Block | OAuth token leakage |
refreshtoken |
Block | Long-lived token exposure |
authtoken |
Block | Authentication credential |
bearertoken |
Block | Bearer auth exposure |
apikey |
Block | API key leakage |
connectionstring |
Block | Database credential exposure |
privatekey |
Block | Cryptographic key leakage |
ssn |
Block | PII — Social Security Number |
creditcard |
Block | PCI — Credit card data |
Field Name Matching
Field names are normalized before matching:
- Lowercased
- Hyphens (
-) and underscores (_) stripped
This means AccessToken, access_token, access-token, and ACCESSTOKEN all match the accesstoken pattern.
Short patterns (≤ 5 characters) require exact match after normalization to prevent false positives. Longer patterns use contains matching.
SensitiveFieldEntry & SensitiveFieldAction
public readonly struct SensitiveFieldEntry
{
public string Pattern { get; } // e.g., "password"
public SensitiveFieldAction DefaultAction { get; } // Block, Redact, Warn, etc.
public string Category { get; } // e.g., "Credential", "PII", "PCI"
public string Description { get; } // Human-readable explanation
}
public enum SensitiveFieldAction
{
Allow, // Explicitly permitted
Block, // Reject the log entry
Redact, // Replace value with ***REDACTED***
Warn, // Allow but flag as violation
Default // Use profile-level default
}
Customer Overrides
Profile-level configuration always takes precedence over built-in defaults. If a customer explicitly lists a field in their FieldSeverities, DisallowedFields, or Encryption config, the built-in catalog defers to their setting.
// Customer profile says "password" is Info severity (allowed for debugging)
// → Built-in Block action is overridden by customer's explicit decision
SensitiveFieldAction action = SensitiveFieldCatalog.GetEffectiveAction(
"password",
profileOverrides: profile.SensitiveFieldOverrides);
// Returns Allow (customer override wins)
Zero-Config Experience
// Install CerbiStream, log with a password field — get instant governance feedback
builder.Logging.AddCerbiStream();
logger.LogInformation("User login {password} {userId}", "secret123", "u-123");
// → GovernanceViolation: "password" matched built-in sensitive field pattern
// → No profile needed. Works out of the box.
Quickstart: Using GovernanceConfigLoader
using Cerbi.Governance;
using Cerbi.Governance.Core.Models;
// Load a canonical governance profile from a JSON file
GovernanceConfigLoader.SetGovernanceFilePath("cerbi_governance.json");
// Access the currently loaded profile
Profile? profile = GovernanceConfigLoader.CurrentProfile;
if (profile != null)
{
Console.WriteLine($"Profile: {profile.Name} (app: {profile.AppName})");
Console.WriteLine($"Version: {profile.Version}, Status: {profile.Status}");
Console.WriteLine($"Required fields: {profile.RequiredFields?.Count ?? 0}");
Console.WriteLine($"Disallowed fields: {profile.DisallowedFields?.Count ?? 0}");
Console.WriteLine($"Scoring enabled: {profile.Scoring?.Enabled ?? false}");
}
Validating a Log Entry
var logData = new Dictionary<string, object>
{
{ "requestId", Guid.NewGuid() },
{ "userId", "u-12345" },
{ "timestamp", DateTime.UtcNow }
};
bool isValid = GovernanceHelper.TryValidate("my-profile", logData, out var errors, out var score);
if (!isValid)
{
foreach (var error in errors)
Console.WriteLine($" Violation: {error}");
Console.WriteLine($" Score penalty: {score}");
}
Canonical Profile JSON
All governance profiles use this flat JSON schema — the same format produced by the CerbiShield Dashboard rule editor and consumed by all runtime loggers:
{
"name": "PII Protection",
"appName": "my-service",
"version": "1.0.0",
"status": "Published",
"metadata": {
"description": "Prevents PII leakage in application logs",
"owner": "security-team",
"createdAt": "2025-01-15T00:00:00Z"
},
"tags": ["pii", "compliance", "hipaa"],
"allowRelax": false,
"requiredFields": ["requestId", "timestamp", "correlationId"],
"disallowedFields": ["ssn", "creditCardNumber", "password"],
"fieldSeverities": {
"requestId": "Error",
"userId": "Warn",
"ssn": "Forbidden",
"debugInfo": "Info"
},
"fieldTypes": {
"requestId": "Guid",
"userId": "String",
"timestamp": "DateTime",
"retryCount": "Int",
"amount": "Decimal",
"isAdmin": "Bool"
},
"enums": {
"environment": ["dev", "staging", "production"],
"logLevel": ["Debug", "Info", "Warning", "Error", "Critical"]
},
"encryption": {
"mode": "AES",
"encryptedFields": ["ssn", "email"]
},
"scoring": {
"enabled": true,
"weightsBySeverity": {
"Error": 5.0,
"Warn": 1.0,
"Info": 0.1
},
"pluginWeights": {},
"version": "1.0.0"
}
}
Architecture
┌─────────────────────────────────────────────────────────┐
│ CerbiShield Dashboard (Next.js) │
│ → Creates/edits Profile JSON via rule editor │
│ → Reads Profile from GovernanceStore API │
└────────────────────────┬────────────────────────────────┘
│ canonical Profile JSON
┌────────────────────────▼────────────────────────────────┐
│ Cerbi.GovernanceRuntime (v2.0.0) │
│ → Loads Profile via FileGovernanceSource │
│ → Validates at runtime via CompiledProfile.Build │
│ → Falls through to SensitiveFieldCatalog for │
│ unmatched fields (zero-config PII detection) │
└────────────────────────┬────────────────────────────────┘
│ uses
┌────────────────────────▼────────────────────────────────┐
│ Cerbi.Governance.Core (v2.2.0) ← YOU ARE HERE │
│ → GovernanceConfigLoader: loads Profile from JSON file │
│ → GovernanceHelper: validates log data against Profile │
│ → SensitiveFieldCatalog: 11 built-in PII patterns │
│ → GovernanceValidator: validates Profile structure │
│ → Models: Profile, SeverityLevel, FieldType, etc. │
└────────────────────────┬────────────────────────────────┘
│ consumed by
┌────────────────────────▼────────────────────────────────┐
│ Logger Plugins │
│ → CerbiStream, Serilog, MEL, NLog │
│ → Load Profile → validate logs → ship scoring events │
│ → Built-in sensitive field detection works even │
│ without a Profile configured │
└─────────────────────────────────────────────────────────┘
Comparison: Core vs Runtime vs Validator
| Concern | Cerbi.Governance.Core |
Cerbi.GovernanceRuntime |
GovernanceValidator |
|---|---|---|---|
| Scope | Shared models + helpers + sensitive field catalog | Runtime validation engine | Profile structure check |
| Profile model | Profile (canonical) |
Profile (canonical) |
Profile (canonical) |
| Loading | GovernanceConfigLoader (file-based) |
FileGovernanceSource (file-based) |
N/A (accepts Profile) |
| Validation | GovernanceHelper.TryValidate |
CompiledProfile.Validate |
GovernanceValidator.Validate |
| Sensitive Fields | SensitiveFieldCatalog (11 patterns) |
Falls through to catalog for unmatched fields | N/A |
| Scoring | Weighted scoring via ScoringSettings |
Full scoring pipeline | N/A |
| Roslyn | ExtractLoggedFields helper |
N/A | N/A |
| Used by | All logger plugins, GovernanceRuntime | Logger plugins at runtime | Dashboard, GovernanceApi |
Profile Model Reference
public class Profile
{
public string? Name { get; set; }
public string? AppName { get; set; }
public string? Version { get; set; }
public ProfileStatus Status { get; set; } // Draft | Published
public ProfileMetadata? Metadata { get; set; }
public List<string>? Tags { get; set; }
public bool AllowRelax { get; set; }
public List<string>? AllowedTopics { get; set; }
public List<string>? RequiredFields { get; set; }
public List<string>? DisallowedFields { get; set; }
public Dictionary<string, SeverityLevel>? FieldSeverities { get; set; } // Info|Warn|Error|Forbidden
public Dictionary<string, FieldType>? FieldTypes { get; set; } // String|Int|Decimal|Guid|DateTime|Bool|Object|Array
public Dictionary<string, List<string>>? Enums { get; set; }
public Encryption? Encryption { get; set; }
public ScoringSettings? Scoring { get; set; }
}
Breaking Changes in v2.2.0
GovernanceConfigLoader.CurrentProfileis nowProfile?(was accessed viaTryGetProfilewithLogProfile)GovernanceConfigLoader.SetCurrentProfileForTest(Profile)— parameter changed fromLogProfiletoProfileGovernanceHelper.TryValidateusesProfile.FieldSeveritiesasDict<string, SeverityLevel>(wasDict<string, string>)GovernanceHelper.TryValidateusesProfile.FieldTypesasDict<string, FieldType>(wasDict<string, string>)GovernanceHelper.TryValidateusesProfile.Enums(wasFieldEnumsin legacy)- Removed:
TryGetProfile,GetAllowedLevels,GovernanceModefromGovernanceConfigLoader - Legacy models
LogProfileandCerbiGovernancestill exist in the codebase but are no longer used by ConfigLoader, Helper, or Validator - Added:
SensitiveFieldCatalogfor built-in PII detection (non-breaking — additive feature) - Added:
GovernanceHelper.CheckBuiltInSensitiveFields()called automatically during validation
Installation
dotnet add package Cerbi.Governance.Core --version 2.2.0
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CerbiShield.Contracts (>= 1.2.1)
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
-
net8.0
- CerbiShield.Contracts (>= 1.2.1)
- Microsoft.CodeAnalysis.CSharp (>= 4.14.0)
NuGet packages (7)
Showing the top 5 NuGet packages that depend on Cerbi.Governance.Core:
| Package | Downloads |
|---|---|
|
CerbiStream
CerbiStream.Logging - Secure, Scalable, and Standardized Logging for Modern Applications. |
|
|
CerbiStream.GovernanceAnalyzer
Roslyn analyzer to enforce structured logging governance for CerbiStream apps. Ensures consistency, traceability, and compliance with score shipping support. |
|
|
Cerbi.MEL.Governance
Real-time governance enforcement for Microsoft.Extensions.Logging (MEL) using the Cerbi validation engine. |
|
|
Cerbi.Governance.Runtime
Real-time governance enforcement for CerbiStream and other structured loggers. Uses canonical Dashboard Profile model. |
|
|
Cerbi.Serilog.GovernanceAnalyzer
Serilog governance analyzer plugin: runtime validation, filtering, enrichment, live reload, correlation, relaxed diagnostics, and high-throughput score shipping with ArrayPool optimizations. Supports .NET 8.0+ and .NET 10.0. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.2.34 | 41 | 4/13/2026 |
| 2.2.33 | 228 | 4/2/2026 |
| 2.2.29 | 290 | 3/17/2026 |
| 2.0.28 | 88 | 3/17/2026 |
| 2.0.27 | 79 | 3/17/2026 |
| 2.0.26 | 82 | 3/17/2026 |
| 2.0.25 | 80 | 3/17/2026 |
| 2.0.24 | 89 | 3/17/2026 |
| 2.0.22 | 287 | 3/1/2026 |
| 2.0.20 | 92 | 2/26/2026 |
| 1.0.16 | 116 | 2/23/2026 |
| 1.0.15 | 1,093 | 12/19/2025 |
| 1.0.13 | 212 | 12/5/2025 |
| 1.0.12 | 212 | 11/24/2025 |
| 1.0.11 | 250 | 11/22/2025 |
| 1.0.10 | 267 | 11/22/2025 |
| 1.0.9 | 209 | 11/15/2025 |
| 1.0.8 | 226 | 10/30/2025 |
| 1.0.7 | 210 | 10/30/2025 |
| 1.0.6 | 214 | 10/30/2025 |