Audit Log Search, Filtering, and Compliance Export#88
Merged
memplethee-lab merged 2 commits intoJun 24, 2026
Conversation
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #70
Summary
Implements a dedicated
AuditLogModulecovering full-text search, advanced filtering, signed bulk export, retention enforcement, and at-rest encryption for audit logs — closing all items in the linked issue's Definition of Done.The existing
ProvenanceController/DTOs attached to the issue cover AI agent call provenance (LLM provider calls, on-chain tx hashes, signature verification) — a different domain from generic audit logging (auth events, CRUD actions, IP-based access tracking). Rather than overloadProvenanceRecordwith unrelated fields, this PR introduces a parallelAuditLogentity and module, following the same architectural conventions already established inProvenanceController(NestJS guards, class-validator DTOs, Swagger decorators, paginated response shapes).What's included
Design decisions
searchTextis built once at write time (record()concatenates action, resource type/ID, IP, and details) so the GIN index stays simple and queries don't pay tokenization cost per row at read time.archiveOldLogsaccepts an optionalcoldStorageWriter: (logs) => Promise<void>callback rather than importing an S3 client directly, so the actual storage backend (S3/Glacier/GCS) can be wired in per environment without changing this module.AUDIT_LOG_ENCRYPTION_KEY,AUDIT_EXPORT_SIGNING_KEY) so rotating one doesn't invalidate the other.Required setup before merge
AUDIT_LOG_ENCRYPTION_KEY(32-byte hex string) andAUDIT_EXPORT_SIGNING_KEYin environment config — both throw at runtime if unset when first used.create-audit-log.ts.coldStorageWritercallback intoarchiveOldLogsfor production (currently a no-op if not supplied — logs are marked archived without actually moving data).