Skip to content

[FEATURE] Add Encina.Audit.Marten — event-sourced IAuditStore with temporal crypto-shredding for compliance-grade audit trails #800

@dlrivada

Description

@dlrivada

Feature Description

Add Encina.Audit.Marten as an additional provider for IAuditStore and IReadAuditStore, implementing event-sourced audit trails with temporal crypto-shredding via Marten (PostgreSQL).
This follows the Encina "pay-for-what-you-use" philosophy:

  • Simple apps ÔÇö InMemoryAuditStore (dev) or DB provider (production)
  • Compliance-heavy apps (SOX, NIS2) ÔÇö MartenAuditStore with immutable events + crypto-shredding
    The existing IAuditStore interface does NOT change ÔÇö this is a new implementation, not a migration.

Motivation

  • SOX 404: Requires immutable audit trail of internal controls. Current mutable stores allow tampering.
  • NIS2 Art. 10: Requires logging with integrity guarantees. Append-only event store provides this.
  • GDPR Art. 5(1)(e): Data minimization requires purging old audit data. Crypto-shredding achieves this without breaking immutability.
  • Forensics: Temporal queries ("what happened at time X?") are natural with event sourcing.

Design (Option C from architectural review)

IAuditStore (unchanged interface)
|-- InMemoryAuditStore          ÔÇö development/testing (existing)
|-- DB providers (13)           ÔÇö production simple (existing)
+-- MartenAuditStore (NEW)      ÔÇö production compliance-grade
    |-- Events encrypted with temporal keys (monthly/yearly)
    |-- PurgeEntriesAsync() destroys temporal keys (crypto-shredding)
    |-- Marten projections for efficient querying
    +-- ITemporalKeyProvider for key lifecycle management

Key Behaviors

Operation DB Provider (current) MartenAuditStore (new)
RecordAsync INSERT row Append encrypted event
QueryAsync SELECT with filters Project from decrypted events
PurgeEntriesAsync DELETE rows Destroy temporal encryption keys
Immutability Rows can be UPDATE/DELETE'd Events are append-only
Tamper evidence None Event stream integrity

Configuration

// Simple app ÔÇö existing DB provider (no change)
services.AddEncinaAudit(options => { ... });
// Compliance-grade ÔÇö opt-in to Marten ES provider
services.AddEncinaAuditMarten(options =>
{
    options.KeyRotationPeriod = TimeSpan.FromDays(365); // yearly keys
    options.EncryptionScope = AuditEncryptionScope.PiiFieldsOnly;
    options.RetentionPeriod = TimeSpan.FromDays(2555); // 7 years (SOX)
    options.EnableAutoPurge = true;
});

Acceptance Criteria

  • MartenAuditStore implements IAuditStore with event-sourced persistence
  • MartenReadAuditStore implements IReadAuditStore with event-sourced persistence
  • Audit events are encrypted with temporal keys via ITemporalKeyProvider
  • PurgeEntriesAsync() destroys temporal keys (crypto-shredding), does NOT delete events
  • Marten projections enable efficient QueryAsync with filtering and pagination
  • Shredded entries are handled gracefully in query results (placeholder or skip)
  • ServiceCollectionExtensions.AddEncinaAuditMarten() registers all components
  • Existing IAuditStore implementations are NOT affected
  • Unit tests with mocked IAggregateRepository<T>
  • Integration tests against real Marten/PostgreSQL (Docker)

Cross-Cutting Integration Checklist

  • OpenTelemetry ÔÇö inherit from Security.Audit diagnostics
  • Structured Logging ÔÇö inherit from Security.Audit logging
  • Health Checks ÔÇö verify Marten/PostgreSQL connectivity
  • Audit Trail ÔÇö this IS the audit trail implementation
  • Caching ÔÇö evaluate caching projections for read-heavy queries
  • N/A: Validation, Resilience (local DB), Distributed Locks, Transactions (Marten session), Idempotency (event versioning), Module Isolation
  • Deferred: Multi-Tenancy ([FEATURE] Add multi-tenancy support (TenantId filtering) for Security.Audit and Security.ABAC #798)

Dependencies

Package Structure

src/
+-- Encina.Audit.Marten/
    |-- MartenAuditStore.cs           ÔÇö IAuditStore implementation
    |-- MartenReadAuditStore.cs       ÔÇö IReadAuditStore implementation
    |-- Events/
    |   |-- AuditEntryRecorded.cs     ÔÇö ES event
    |   +-- ReadAuditEntryRecorded.cs ÔÇö ES event
    |-- Projections/
    |   |-- AuditEntryProjection.cs   ÔÇö Read model for queries
    |   +-- ReadAuditProjection.cs    ÔÇö Read model for read audit
    |-- Crypto/
    |   |-- ITemporalKeyProvider.cs   ÔÇö Temporal key lifecycle
    |   +-- TemporalKeyProvider.cs    ÔÇö Marten-backed implementation
    |-- ServiceCollectionExtensions.cs
    |-- MartenAuditOptions.cs
    +-- Diagnostics/
        +-- MartenAuditDiagnostics.cs

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-auditAudit trails and change trackingarea-complianceGDPR, EU Laws, and Regulatory Compliance patternsarea-martenMarten event sourcing providerarea-securitySecurity patterns and protectioncomplexity-highComplexity: HighenhancementNew feature or requestpriority-mediumPriority: Medium (⭐⭐⭐)

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions