Persist the security-relevant events (authz denials + BIG-nummer reveal/step-up) into a data-minimised EF table (AuthzAuditEntry: At/Action/Resource/Decision/Role/CorrelationId — never a name/BSN/value), extending the DocumentStore AuditEntry pattern (migration AuthzAudit). AuditAuthz now persists via AuthzAuditStore.Record alongside its log line. GET /admin/audit (admin-gated by the existing CasesAdmin) returns the trail newest-first. +3 backend tests incl. a schema-carries-no-PII reflection test. Typed client regenerated (audit() + AuthzAuditDto); no FE consumer yet (a future audit view must add the ROLE_AWARE prefix). Finishes WP-42's audit half. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.4 KiB
WP-41 — Persisted, queryable authz/PII-reveal audit
Status: done Phase: 8 — platform/DX/showcase Priority: P2 Depends on: WP-40
Outcome
New data-minimised EF table AuthzAuditEntry (Data/AuthzAuditStore.cs, DbSet + key config in
AppDbContext, migration AuthzAudit): At, Action, Resource, Decision, Role, CorrelationId —
never a name/BSN/value. AuditAuthz now persists (via AuthzAuditStore.Record) alongside its
log line, so every authz denial + BIG-nummer reveal/step-up attempt is captured. GET /admin/audit
(admin-gated by the existing CasesAdmin/cases:manage — a dedicated audit:read cap is a later
refinement) returns the trail newest-first (client-side sort — SQLite can't ORDER BY DateTimeOffset).
+3 backend tests (deny recorded, reveal recorded, schema-carries-no-PII reflection test). Typed
client regenerated (audit() + AuthzAuditDto). No FE consumer yet — a future audit view (WP-42
finish) must add /api/v1/admin/audit to the role.interceptor ROLE_AWARE list or it silently 403s.
Why
The security-relevant events (authz denials via AuditAuthz, BIG-nummer reveal, step-up) are
log-only — never persisted, so there's no queryable trail. The one persisted AuditEntry table
covers document lifecycle only. PRD-0002 §8 calls for a persisted authorization audit. A register
(BIO) wants this queryable, and strictly data-minimised.
Decisions
- Persist authz/reveal/step-up events into a data-minimised EF table extending the existing
AuditEntry/AppDbContextpattern: role, action, resource-ref, decision, correlation-id, timestamp — never the value or any PII. - Wire
AuditAuthz+ the reveal endpoint to persist (in addition to the log line). - Optional thin admin read view — reuse
cases:manageor add anaudit:readcapability.
Files
backend/.../Data/— new audit entity +AppDbContextDbSet + EF migration.backend/.../Program.cs—AuditAuthz+ reveal endpoint persist.- Backend tests: events are persisted; no PII columns; correlation-id captured.
- (Optional) FE audit read page + adapter/store, gated by the capability.
Acceptance criteria
- Denials, reveals, and step-up attempts land as rows with no PII/value fields.
- A test asserts the schema carries no name/bsn/value column.
dotnet test(132) +npm run cigreen; api-client drift clean after commit.