Skip to content

Add the PAM access-audit event store - #8230

Draft
patriksvensson wants to merge 1 commit into
mainfrom
psvensson/pam-audit-log-scaffolding
Draft

Add the PAM access-audit event store#8230
patriksvensson wants to merge 1 commit into
mainfrom
psvensson/pam-audit-log-scaffolding

Conversation

@patriksvensson

Copy link
Copy Markdown
Member

🎟️ Tracking

PM-39047

📔 Objective

Adds the append-only store behind the PAM access-audit trail: the AccessAuditEvent
table, its two stored procedures, migrations for MSSQL and the three EF providers,
and the Dapper and EF implementations of IAccessAuditEventRepository.

Nothing calls it yet, and that's deliberate. The emitter that writes events and the
endpoint that reads the trail back are separate PRs. Landing the persistence layer on
its own keeps the schema reviewable without a feature's worth of code wrapped around
it. The parts DB Ops care about are the whole diff here, not a corner of it.

Two design decisions look like mistakes if you don't know the intent:

Rows are self-contained. AccessAuditEvent_Create snapshots the actor, requester,
cipher, collection, and rule display names into the row at write time. Reading the
trail then touches no other table, and a later rename can't rewrite history. The
subject ids are deliberately not foreign keyed for the same reason: an audit event
has to outlive what it references. Only OrganizationId is, so the rows are removed
with the organization.

The EF path resolves those names in C# instead of in the query. The stored
procedure pulls the cipher name out of its encrypted Data document with JSON_VALUE,
which has no portable translation across MySQL, Postgres, and SQLite.

Five DatabaseTheory integration tests cover the round trip. Two of them pin the
design above: GetManyByOrganizationId_SnapshotName_SurvivesEntityDeletion and
..._IsNotRewrittenByRename.

The append-only store the audit trail is written to and read back from: the
AccessAuditEvent table and its two stored procedures, a consolidated migration
for MSSQL plus generated ones for the EF providers, and the Dapper and EF
repositories behind IAccessAuditEventRepository.

Rows are self-contained. AccessAuditEvent_Create snapshots the actor,
requester, cipher, collection, and rule display names into the row at write
time, so the trail read touches no other table and a later rename or delete
cannot rewrite history. The subject ids are deliberately not foreign keyed for
the same reason -- an event outlives what it references. Only OrganizationId
is, so the rows go when the organization does. The EF path resolves those names
in C#, because JSON_VALUE -- which the procedure uses to read the cipher name
out of its encrypted Data document -- has no portable EF translation.

This is the persistence layer only; nothing consumes it yet. The emitter that
writes to it and the trail endpoint that reads from it are separate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit d06d9fa)
@codecov

codecov Bot commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.83784% with 27 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (main@5f3c0b6). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...ork/Pam/Repositories/AccessAuditEventRepository.cs 77.67% 21 Missing and 4 partials ⚠️
...ure.EntityFramework/Pam/Models/AccessAuditEvent.cs 95.83% 1 Missing ⚠️
src/Pam.Domain/Models/AccessAuditEvent.cs 95.65% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8230   +/-   ##
=======================================
  Coverage        ?   68.64%           
=======================================
  Files           ?     2388           
  Lines           ?   104168           
  Branches        ?     9416           
=======================================
  Hits            ?    71506           
  Misses          ?    30317           
  Partials        ?     2345           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

"[dbo].[AccessAuditEvent_Create]",
new
{
Id = CoreHelpers.GenerateComb(),

var row = new EfModel
{
Id = CoreHelpers.GenerateComb(),

var rule = new AccessRule
{
Id = CoreHelpers.GenerateComb(),

var rule = new AccessRule
{
Id = CoreHelpers.GenerateComb(),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant