DKNet.EfCore.AuditLogs
10.1.27
dotnet add package DKNet.EfCore.AuditLogs --version 10.1.27
NuGet\Install-Package DKNet.EfCore.AuditLogs -Version 10.1.27
<PackageReference Include="DKNet.EfCore.AuditLogs" Version="10.1.27" />
<PackageVersion Include="DKNet.EfCore.AuditLogs" Version="10.1.27" />
<PackageReference Include="DKNet.EfCore.AuditLogs" />
paket add DKNet.EfCore.AuditLogs --version 10.1.27
#r "nuget: DKNet.EfCore.AuditLogs, 10.1.27"
#:package DKNet.EfCore.AuditLogs@10.1.27
#addin nuget:?package=DKNet.EfCore.AuditLogs&version=10.1.27
#tool nuget:?package=DKNet.EfCore.AuditLogs&version=10.1.27
DKNet.EfCore.AuditLogs
A DKNet.EfCore.Hooks-based SaveChanges interceptor that captures a structured, field-level audit trail of entity changes — with automatic redaction of likely-sensitive values — and hands finished batches to your own publisher(s).
Install
dotnet add package DKNet.EfCore.AuditLogs
Features
- Automatic before/after-
SaveChangescapture of Created/Updated/Deleted entities implementingIAuditedProperties, with per-field old/new value diffs. - Built-in redaction of likely-sensitive properties (passwords, tokens, connection strings,
SecureString, …), overridable per-property via[AuditLog]and forced via[SensitiveData]fromDKNet.EfCore.Abstractions. - Pluggable
IAuditLogPublisherextension point — ship audit batches to a database, queue, log sink, or anywhere else; multiple publishers perDbContextare supported. - Configurable scope: audit every entity or only those explicitly marked
[AuditLog], and capture every property or only allow-listed ones. - Optional signed-in-user stamping: register an
ICurrentUserProviderand the hook fillsCreatedBy/UpdatedByfrom the application's current user, independently of the tenant ownership key supplied byDKNet.EfCore.DataAuthorization.
Quick start
using DKNet.EfCore.AuditLogs;
using DKNet.EfCore.Hooks;
// 1. Register the DbContext through the hook-aware overload.
services.AddDbContextWithHook<AppDbContext>((provider, options) =>
options.UseSqlServer(connectionString));
// 2. Register the audit hook plus a publisher, keyed to AppDbContext.
services.AddEfCoreAuditLogs<AppDbContext, MyAuditLogPublisher>();
// 3. Optional: fill CreatedBy/UpdatedBy from the signed-in user.
services.AddCurrentUserProvider<AppDbContext, SignedInUserProvider>();
// 4. Implement the publisher.
public sealed class MyAuditLogPublisher : IAuditLogPublisher
{
public Task PublishAsync(IEnumerable<AuditLogEntry> logs, CancellationToken cancellationToken = default)
{
foreach (var log in logs)
Console.WriteLine($"[{log.Action}] {log.EntityName} by {log.UpdatedBy ?? log.CreatedBy}");
return Task.CompletedTask;
}
}
// 5. Implement the current-user provider, resolving whatever your application already uses to
// represent the caller. Return a stable, non-personal identifier — see "Current user" below.
public sealed class SignedInUserProvider(ICurrentPrincipal principal) : ICurrentUserProvider
{
public string? GetCurrentUser() => principal.SubjectId; // e.g. "sub-8f21c0"
}
AddCurrentUserProvider<TDbContext, TProvider>() attaches the audit hook itself, so step 3 works on its own
when you only want the stamping and no publisher. It never overwrites the behaviour/propertyPolicy a
previous AddEfCoreAuditHook/AddEfCoreAuditLogs call registered, so the two calls can appear in either
order.
Customisation reference
AddEfCoreAuditHook<TDbContext> and AddEfCoreAuditLogs<TDbContext, TPublisher> take the same two optional
arguments. They are fixed at registration time for the whole application — there is no per-save or per-entity
override, and no options class to reconfigure afterwards.
| Option | Type | Default | Effect |
|---|---|---|---|
behaviour |
AuditLogBehaviour |
IncludeAllAuditedEntities |
IncludeAllAuditedEntities audits every IAuditedProperties entity not marked [IgnoreAuditLog]. OnlyAttributedAuditedEntities audits only entities marked [AuditLog] at class level. |
propertyPolicy |
AuditPropertyPolicy |
RedactSensitive |
RedactSensitive captures every non-ignored property, replacing sensitive-looking values with ***REDACTED***. OnlyAttributedProperties captures only properties marked [AuditLog]. |
Attribute-level control comes from DKNet.EfCore.Abstractions:
| Attribute | On | Effect |
|---|---|---|
[IgnoreAuditLog] |
class or property | Excluded unconditionally, whatever the behaviour and policy. |
[AuditLog] |
class | Opts the entity in under OnlyAttributedAuditedEntities. |
[AuditLog] |
property | Forces plaintext past the sensitive-name patterns, and allow-lists it under OnlyAttributedProperties. |
[SensitiveData] |
property | Always redacted, even alongside [AuditLog]. |
The built-in sensitive-name fragments are password, secret, token, apikey, api_key, ssn,
socialsecuritynumber, creditcard, cvv, pin, connectionstring, privatekey, passphrase, accesskey
and salt (case-insensitive substring match), plus any property typed SecureString. The list is not
configurable — use [SensitiveData] to add to it and [AuditLog] to opt out of it per property.
An entity that does not implement IAuditedProperties is skipped before any attribute is inspected.
Current user (CreatedBy / UpdatedBy)
The current-user provider is optional. Register one with
AddCurrentUserProvider<TDbContext, TProvider>() and the hook stamps the audit identity from
ICurrentUserProvider.GetCurrentUser():
CreatedBy/CreatedOnare written once, on insert. A later update never rewrites them, so the original creator survives every subsequent save.UpdatedByfollows the caller of each save — except when a domain method already recorded a modifier for that change set withSetUpdatedBy(...). An explicit modifier always wins over both the current user and the ownership key.GetCurrentUser()returningnullor empty stamps nothing from this package — the save still succeeds; whenDKNet.EfCore.DataAuthorizationis also registered, the ownership-key fallback below applies to that save, so a background job or an unauthenticated request lands the tenant key inCreatedBy/UpdatedBy. With no ownership key either, the audit properties are left as they are.- The ownership-key fallback is decided per save, on the value not the registration.
CreatedBy/UpdatedBycome from theIDataOwnerProviderownership key whenever no current-user value is available for that save — no current-user provider registered, or a registered one that returnednull/empty — and stay unset whenDKNet.EfCore.DataAuthorizationis not in use.
Whatever the provider returns is published unmasked to every registered IAuditLogPublisher — the
redaction rules above cover entity property values, not the audit identity itself. An application subject to a
personal-data rule (GDPR, PDPA) should therefore return a stable, non-personal identifier such as the token
subject id ("sub-8f21c0"), not an email address or any other directly identifying value.
Ownership (OwnedBy) is a separate concern owned by
DKNet.EfCore.DataAuthorization; registering both providers is
supported and each fills only its own properties.
Full documentation: https://github.com/baoduy/DKNet/blob/main/docs/EfCore/DKNet.EfCore.AuditLogs.md
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- DKNet.EfCore.Abstractions (>= 10.1.27)
- DKNet.EfCore.Hooks (>= 10.1.27)
- Microsoft.EntityFrameworkCore (>= 10.0.12)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on DKNet.EfCore.AuditLogs:
| Package | Downloads |
|---|---|
|
DKNet.EfCore.DataAuthorization
DKNet is an enterprise-grade .NET library collection focused on advanced EF Core extensions, dynamic predicate building, and the Specification pattern. It provides production-ready tools for building robust, type-safe, and testable data access layers, including dynamic LINQ support, LinqKit integration. Designed for modern cloud-native applications, DKNet enforces strict code quality, async best practices, and full documentation for all public APIs. Enterprise-grade .NET library suite for modern application development, featuring advanced EF Core extensions (dynamic predicates, specifications, LinqKit), robust Domain-Driven Design (DDD) patterns, and domain event support. DKNet empowers scalable, maintainable, and testable solutions with type-safe validation, async/await, XML documentation, and high code quality standards. Ideal for cloud-native, microservices, and enterprise architectures. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 10.1.27 | 0 | 9/16/2026 |
| 10.1.26 | 0 | 9/16/2026 |
| 10.1.25 | 0 | 9/16/2026 |
| 10.1.24 | 81 | 9/11/2026 |
| 10.1.23 | 80 | 9/11/2026 |
| 10.1.22 | 84 | 9/11/2026 |
| 10.1.21 | 83 | 9/11/2026 |
| 10.1.20 | 88 | 9/9/2026 |
| 10.1.19 | 172 | 9/3/2026 |
| 10.1.18 | 84 | 9/3/2026 |
| 10.1.17 | 92 | 9/3/2026 |
| 10.1.16 | 93 | 9/3/2026 |
| 10.1.15 | 130 | 9/1/2026 |
| 10.1.14 | 82 | 9/1/2026 |
| 10.1.13 | 94 | 8/31/2026 |
| 10.1.12 | 92 | 8/25/2026 |
| 10.1.11 | 102 | 8/24/2026 |
| 10.1.10 | 100 | 8/22/2026 |
| 10.1.9 | 116 | 8/22/2026 |
| 10.1.8 | 101 | 8/21/2026 |