Skip to content

Configuration Reference

RzR edited this page Apr 20, 2026 · 1 revision

Configuration Reference

Every configurable option lives under AuditTrailOptions, which you set up inside AddAuditTrail(options => { ... }). This page documents all of them.


AuditTrailOptions

The root configuration object. You get it in the AddAuditTrail callback.

builder.Services.AddAuditTrail(options =>
{
    // EF Core settings
    options.EfCore.Intercept<AppDbContext>();

    // Storage settings
    options.Storage.UseSqlServer(connectionString);

    // GDPR settings
    options.Gdpr.ForEntity<Customer>(e => { ... });

    // Global entity exclusions
    options.Exclude<HealthCheckResult>();
    options.Exclude<TempData>();

    // Custom resolvers
    options.UseUserResolver<MyUserResolver>();
    options.UseSourceResolver<MySourceResolver>();
});

Properties and methods

Member Type Description
EfCore EfCoreAuditOptions EF Core interception settings
Storage StorageOptions Storage backend connection and behavior
Gdpr GdprOptions GDPR field-level policies
GlobalExclusions ICollection<Type> Entity types excluded from auditing everywhere
Exclude<TEntity>() fluent Adds a type to global exclusions
UseUserResolver<T>() fluent Registers a custom IAuditUserResolver implementation
UseSourceResolver<T>() fluent Registers a custom IAuditSourceResolver implementation

EfCoreAuditOptions

Controls which DbContext types get intercepted and whether read auditing is turned on.

options.EfCore
    .Intercept<AppDbContext>()
    .Intercept<SecondDbContext>()   // multiple contexts supported
    .IncludeReads()                 // log SELECT queries
    .IncludeReadProperties()        // also capture which columns were queried
Method What it does
Intercept<TContext>() Registers a DbContext type for audit interception. You can call this multiple times for different contexts.
IncludeReads() Turns on read (SELECT) auditing. Off by default.
IncludeReadProperties() When read auditing is on, also captures the column names that appeared in the SELECT clause.
Property Type Default Description
ContextTypes IList<Type> empty (internal) Registered DbContext types
IncludeReadsEnabled bool false Whether read auditing is active
IncludeReadPropertiesEnabled bool false Whether to capture read property names

StorageOptions

Tells the library where to put audit records.

// SQL Server
options.Storage.UseSqlServer("Server=.;Database=Audit;...");

// PostgreSQL
options.Storage.UsePostgreSql("Host=localhost;Database=audit;...");

// MongoDB (needs both connection string and database name)
options.Storage.UseMongoDb("mongodb://localhost:27017", "audit_db");

// File
options.Storage.UseFile("/var/audit-logs");
Property Type Default Description
ConnectionString string null Database connection string (SQL Server, PostgreSQL, MongoDB)
DatabaseName string null MongoDB database name
FilePath string null Directory path for JSON file storage
Schema string "audit" Database schema for SQL Server / PostgreSQL tables
RetentionDays int? null If set, records older than this many days can be purged
Method What it does
UseSqlServer(string connStr) Sets ConnectionString for SQL Server
UsePostgreSql(string connStr) Sets ConnectionString for PostgreSQL
UseMongoDb(string connStr, string dbName) Sets ConnectionString and DatabaseName for MongoDB
UseFile(string dirPath) Sets FilePath for file-based storage
WithRetention(int days) Sets RetentionDays. Pair with AddAuditRetentionService() for automatic background purge.

GdprOptions

Where you define field-level GDPR transformation rules. See the full GDPR Compliance page for detailed examples.

options.Gdpr.ForEntity<Customer>(entity =>
{
    // Storage rules (before write)
    entity.ExcludeOnStorage(c => c.CreditCard);
    entity.MaskOnStorage(c => c.Email);
    entity.AnonymizeOnStorage(c => c.FullName);
    entity.HashOnStorage(c => c.Ssn);
    entity.TransformOnStorage(c => c.Phone, val => $"+***-***-{val[^4..]}");

    // Retrieval rules (on read, role/claim gated)
    entity.MaskOnRetrieval(c => c.Email, access => access.AllowRoles("Admin"));
    entity.AnonymizeOnRetrieval(c => c.Phone, access => access.AllowClaim("gdpr", "full"));
});

ForEntity<T>() takes a lambda that receives an EntityGdprPolicyBuilder<T>. The T constraint is class, IAuditable - you can only set GDPR rules for auditable entities.

EntityGdprPolicyBuilder methods

Storage (irreversible, applied before persistence):

Method Result
ExcludeOnStorage(field) Property removed from audit entry entirely
MaskOnStorage(field) "alice@mail.com" -> "a***m"
AnonymizeOnStorage(field) Replaced with "[ANONYMIZED]"
HashOnStorage(field) SHA-256 hex digest (64 characters)
TransformOnStorage(field, Func<string,string>) Your custom transformation function

Retrieval (dynamic, applied when querying):

Method Result
MaskOnRetrieval(field, accessConfig?) Masks unless caller has matching role/claim
AnonymizeOnRetrieval(field, accessConfig?) Anonymizes unless caller has matching role/claim

GdprAccessBuilder

Used inside retrieval rule configuration to define who bypasses the masking:

entity.MaskOnRetrieval(c => c.Email, access =>
{
    access.AllowRoles("Admin", "Auditor");
    access.AllowClaim("gdpr", "full");
});
Method Description
AllowRoles(params string[]) Users with any of these roles see the raw value
AllowClaim(string type, string value) Users with this specific claim see the raw value

Access evaluation is OR-based. Any single matching role or claim grants access.


Connection strings in appsettings.json

A typical setup with separate databases for app data and audit data:

{
  "ConnectionStrings": {
    "AppDb": "Server=.;Database=MyApp;Trusted_Connection=true;",
    "AuditDb": "Server=.;Database=MyApp_Audit;Trusted_Connection=true;"
  }
}

For MongoDB, you also need the database name in a separate config key:

{
  "ConnectionStrings": {
    "AuditDb": "mongodb://localhost:27017"
  },
  "DatabaseNames": {
    "AuditDb": "audit_db"
  }
}

Clone this wiki locally