From dae6de2c489577effabdaff8b1ff66d53515f7e8 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 20 May 2026 16:56:18 -0400 Subject: [PATCH] docs(audit): roadmap corrections after M4 M5 head records M4 realities: - AuditingDbConnection/Command/DataReader decorators need filter plug-in at WriteAsync emission point. - CentralAuditWriter + FallbackAuditWriter are both filter integration points for the direct-write + chained-write paths. - InboundAPI middleware RequestSummary populated, ResponseSummary=null pending response-body buffering decision in M5. - UseWhen(/api/) path-scoped middleware gives natural per-target redaction hook. - Error-row cap raised on Status IN (Failed, Parked, Discarded, Attempted, Skipped) per M1 vocab reconciliation. --- docs/plans/2026-05-20-audit-log-code-roadmap.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/plans/2026-05-20-audit-log-code-roadmap.md b/docs/plans/2026-05-20-audit-log-code-roadmap.md index ebd12c4..878d6c9 100644 --- a/docs/plans/2026-05-20-audit-log-code-roadmap.md +++ b/docs/plans/2026-05-20-audit-log-code-roadmap.md @@ -902,6 +902,14 @@ The design for both is merged on `main` (`alog.md` cached-call tracking section; ## M5 — Payload + redaction policy +> **M4 realities to honor:** +> - **Decorator surfaces to filter**: `AuditingDbConnection`/`AuditingDbCommand`/`AuditingDbDataReader` (Bundle A) emit `RequestSummary` as raw SQL + parameters today. M5's `IAuditPayloadFilter` runs between event construction and writer call; the AuditingDb decorators must call into the filter before `WriteAsync`. +> - **CentralAuditWriter wraps `IAuditLogRepository.InsertIfNotExistsAsync`** (Bundle B). M5 should plug the filter into BOTH the site-side `FallbackAuditWriter` and the central-side `CentralAuditWriter` so direct-write paths (NotificationOutboxActor, AuditWriteMiddleware) are also filtered. Plugin location: in each writer's `WriteAsync` BEFORE the storage call. +> - **InboundAPI middleware `RequestSummary` already populates, `ResponseSummary = null`** (Bundle D punted response-body capture). M5 should add response-body buffering OR document that ResponseSummary stays null for v1 (acceptable per the spec — captures are best-effort). +> - **`AuditWriteMiddleware` path-scoped via `UseWhen(/api/)`** — M5 may want to introduce per-target redaction overrides; that path-scoped setup gives a natural hook for per-route redaction (e.g., `/api/secrets/*` has stricter caps). +> - **Error-row vocabulary**: cap raised to 64 KB on rows with `Status NOT IN ('Delivered', 'Submitted', 'Forwarded')`. The new vocabulary (`Failed/Parked/Discarded/Attempted/Skipped`) is what triggers the elevated cap. NOT "non-Success" wording from the original spec. +> - **InternalsVisibleTo precedent**: AuditLog.Tests can reach internals of SiteRuntime + NotificationOutbox + (newly) AuditLog. M5 redaction tests can exercise internal helpers similarly. + **Goal:** Payload capture is bounded (8 KB / 64 KB on error), headers are redacted by default, SQL parameter values are captured by default with per-connection opt-out, body redactor regexes are configurable per target, and the safety net over-redacts on misconfiguration. **Affected projects:** `AuditLog` (policy engine + options), `ExternalSystemGateway` (HTTP header redactors, SQL param redaction hook), `InboundAPI` (header redactors, body capture), `NotificationOutbox` (subject/body capture follows existing rules). Tests.