Innovabit.DotNet.Interceptors.Audit.Abstractions 2.0.117

dotnet add package Innovabit.DotNet.Interceptors.Audit.Abstractions --version 2.0.117
                    
NuGet\Install-Package Innovabit.DotNet.Interceptors.Audit.Abstractions -Version 2.0.117
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Innovabit.DotNet.Interceptors.Audit.Abstractions" Version="2.0.117" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Innovabit.DotNet.Interceptors.Audit.Abstractions" Version="2.0.117" />
                    
Directory.Packages.props
<PackageReference Include="Innovabit.DotNet.Interceptors.Audit.Abstractions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Innovabit.DotNet.Interceptors.Audit.Abstractions --version 2.0.117
                    
#r "nuget: Innovabit.DotNet.Interceptors.Audit.Abstractions, 2.0.117"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Innovabit.DotNet.Interceptors.Audit.Abstractions@2.0.117
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Innovabit.DotNet.Interceptors.Audit.Abstractions&version=2.0.117
                    
Install as a Cake Addin
#tool nuget:?package=Innovabit.DotNet.Interceptors.Audit.Abstractions&version=2.0.117
                    
Install as a Cake Tool

Innovabit.DotNet.Interceptors.Audit.Abstractions

Business audit trails for Innovabit.DotNet.Interceptors via an [Audited] attribute. This is the provider-agnostic base: it ships the interceptor, the attribute, the AuditEntry shape and the IAuditSink abstraction. Pick a sink — or write one — to decide where entries are kept:

  • Innovabit.DotNet.Interceptors.Audit.EntityFrameworkCore — one row per entry, in your database.

Audit is not logging

Logging ([Log]) Auditing ([Audited])
Who is it for You, debugging Compliance, an investigation, a customer dispute
Lifetime Days or weeks Years
Written when it fails Usually Always — an attempt is a fact worth keeping
Carries the acting user No Yes
Where it goes A log sink A durable store you can query

Put [Audited] on the handful of operations someone might one day have to answer for, not on everything.

Usage

services
    .AddInterceptors()
    .AddEntityFrameworkCoreAudit<BillingDbContext>()     // or .AddAuditSink<MyOwnSink>()
    .UseAuditSubjectAccessor<HttpAuditSubjectAccessor>();

services.AddScopedWithInterception<IRefundService, RefundService>();
public class RefundService : IRefundService
{
    [Audited(Action = "order.refunded", Category = "finance")]
    public Task<Refund> RefundAsync(string orderId, decimal amount, [AuditIgnore] string internalNote)
    { ... }
}

[Audited]

Property Meaning
Action Business name of what happened. Defaults to TypeName.MethodName.
Category Optional grouping — a bounded context, a regulation, a subsystem.
IncludeArguments Record the arguments. Defaults to true.
IncludeResult Record the returned value. Defaults to false — results are large and the trail cares about the action.

Parameters marked [AuditIgnore] are recorded as ***, and CancellationToken parameters are left out entirely. [AuditIgnore] keeps a parameter out of the audit trail specifically; the cross-cutting [Sensitive] and [Mask] from the core package keep it out of every record the suite writes — logs, spans and exception notifications included — and are applied here as well.

Sensitive members inside an argument

The default IAuditSerializer honours [Sensitive] and [Mask] on the properties and fields of whatever it writes out, so the rules keep working once a value stops being an argument and becomes an object inside one:

public class Customer
{
    public string Name { get; set; }
    [Sensitive] public string Email { get; set; }
    [Mask(ShowLast = 4)] public string CardNumber { get; set; }
}

[Audited(Action = "order.placed")]
public Task PlaceAsync(Order order) { ... }

The stored row keeps {"Name":"Ada Lovelace","Email":"***","CardNumber":"************1111"}, through nested objects and collections alike, while the method itself still receives the real object. A serializer of your own opts in with one line — see RedactionJsonModifier in the core package.

When serialization fails outright, the entry records <unserializable: Type.Name> rather than ToString(): a record's generated ToString prints every property, marked ones included, which would turn a serialization failure into exactly the leak the attributes exist to prevent. The redaction is deliberate: an entry that silently dropped an argument would be indistinguishable from one where it was never passed, which is exactly the ambiguity an audit exists to remove.

What an entry carries

AuditEntry holds the action and category, the type and method, the arguments, the outcome (Succeeded, plus ExceptionType/ExceptionMessage on failure), OccurredAt and Duration, the Subject, and a CorrelationId taken from the ambient Activity — so an entry lines up with the trace of the request that produced it.

Who did it

Only your application knows where the current user lives, so IAuditSubjectAccessor is the one thing you have to supply. The default reads Thread.CurrentPrincipal, which ASP.NET Core does not set — a web application registers its own:

public sealed class HttpAuditSubjectAccessor(IHttpContextAccessor accessor) : IAuditSubjectAccessor
{
    public string? GetSubject() => accessor.HttpContext?.User.Identity?.Name;
}

services.AddInterceptors().UseAuditSubjectAccessor<HttpAuditSubjectAccessor>();

An accessor that throws leaves Subject empty rather than failing the operation.

Ordering

The interceptor runs at InterceptorOrders.Audit (50) — just inside logging, outside validation. That is what makes rejected attempts show up in the trail: a call turned away by validation, authorization or a business rule is still recorded, because "who tried to do what" is half of what an audit is for.

A failing sink never fails the call

Whatever a sink throws is swallowed. An audit trail that takes the business operation down with it when the audit store hiccups is worse than one with a gap — so a sink that cannot afford to lose entries should do its own durable buffering rather than rely on the exception surfacing.

Writing a sink

public sealed class FileAuditSink(IAuditSerializer serializer) : IAuditSink
{
    public ValueTask WriteAsync(AuditEntry entry, CancellationToken cancellationToken = default) { ... }
    public void Write(AuditEntry entry) { ... }
}

services.AddInterceptors().AddAuditSink<FileAuditSink>();

Register as many as you like — every sink gets every entry.

License

MIT

Product 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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Innovabit.DotNet.Interceptors.Audit.Abstractions:

Package Downloads
Innovabit.DotNet.Interceptors.Audit.EntityFrameworkCore

Entity Framework Core sink for interceptor-based audit trails.

Innovabit.DotNet.Interceptors.All

Meta-package: every interceptor concern in the suite (logging, validation, caching, notifications, telemetry, audit, authorization, rate limiting, coordination, feature gates, transactions, retry/timeout/circuit breaker/fallback) in one reference. Providers are separate packages — pick the ones you use.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.117 44 10/31/2026
2.0.116 120 10/26/2026
2.0.115 128 10/17/2026
2.0.114 130 10/10/2026
2.0.113 136 10/3/2026
2.0.112 133 9/28/2026
2.0.111 128 9/28/2026
2.0.110 134 9/27/2026
2.0.109 127 9/26/2026
2.0.108 128 9/26/2026
2.0.107 132 9/26/2026
2.0.106 138 9/25/2026
2.0.105 122 9/25/2026
1.0.0.104 109 9/25/2026
1.0.0.103 112 9/25/2026
1.0.0.102 113 9/25/2026
1.0.0.101 111 9/25/2026
1.0.0.100 110 9/25/2026