eng-audit-log-schema

Category: Coding Risk: Medium risk ★ 3.9 · Rating 3.9/5 (8) sboghossian/mini-claude-for-legal MIT

Rating is derived from the repo's GitHub stars and shown for reference.

network_accessfilesystem_access

name: eng-audit-log-schema
description: Use when designing or reviewing the audit log schema for a legal AI product. Defines the canonical event record structure, required fields for legal-product compliance (attorney-client privilege considerations, regulatory retention rules, tamper-evidence), indexing strategy, retention policies, and the specific event types that must be logged in a law-firm or legal-AI context. Engineering skill — no practice-area jurisdictional notes.
license: MIT
metadata:
id: eng.audit-log-schema
category: eng
jurisdictions: [multi]
priority: P2
intent: [audit-log, schema, compliance, tamper-evidence, retention, observability]
related:
- eng-langfuse-trace-inspector
- eng-latency-slo-by-skill
- eng-cost-per-message-tracker
- eng-mcp-tool-registry
source: Louis — HAQQ Legal AI (github.com/sboghossian/mini-claude-for-legal)
version: "1.0"

Audit Log Schema

What it does

The audit log is the system of record for every meaningful event in the legal AI platform. It answers: who did what, to what, when, from where, and with what result. In a legal product, the audit log serves dual purposes: operational observability and legal/regulatory accountability.

Specifically, the audit log must be able to answer:

  • "Did the AI access this client's documents before the conflict check was complete?"
  • "What version of skill X was used when the AI generated this engagement letter?"
  • "Who approved the deletion of matter Y's data, and when?"
  • "Was the user's session authenticated before they queried a privileged document?"

Canonical event record

Every audit log entry is a single JSON object:

{
  "event_id": "ulid or uuid-v7",
  "event_type": "skill.invoked | user.auth | document.accessed | matter.created | ...",
  "timestamp": "2025-05-14T09:31:42.123Z",
  "timestamp_local": "2025-05-14T12:31:42.123+03:00",
  "actor": {
    "user_id": "usr_abc123",
    "role": "associate | partner | admin | system",
    "session_id": "sess_xyz789",
    "ip_address": "203.0.113.42",
    "user_agent": "..."
  },
  "resource": {
    "type": "matter | document | skill | tool | session | user | org",
    "id": "matter_2025-UAE-0147",
    "name": "Al Baraka SPA"
  },
  "action": {
    "name": "read | create | update | delete | invoke | approve | reject | transmit",
    "detail": "Skill efirm-conflict-check invoked for new matter",
    "result": "success | failure | partial",
    "error_code": null,
    "error_message": null
  },
  "context": {
    "skill_id": "efirm-conflict-check",
    "skill_version": "1.0",
    "model_id": "claude-sonnet-4-6",
    "trace_id": "langfuse-trace-id",
    "request_id": "req_abc123"
  },
  "metadata": {
    "org_id": "org_haqq",
    "workspace_id": "ws_default",
    "environment": "production | staging"
  },
  "integrity": {
    "prev_hash": "sha256-of-previous-entry",
    "entry_hash": "sha256-of-this-entry"
  }
}

Required fields (no nullable)

Field Type Purpose
event_id ULID or UUIDv7 Monotonic ordering + uniqueness
event_type enum string Fast filtering and alerting
timestamp ISO 8601 UTC Canonical time reference
actor.user_id string Who acted; "system" for automated events
actor.role enum Authorization context
actor.session_id string Links to authentication record
resource.type enum What was acted upon
resource.id string Specific resource identifier
action.name enum What happened
action.result enum Success / failure / partial
context.request_id string Links to request log

Event type taxonomy

Authentication events

  • user.auth.login.success
  • user.auth.login.failure
  • user.auth.logout
  • user.auth.token.refresh
  • user.auth.mfa.success
  • user.auth.mfa.failure

Matter and document events

  • matter.created
  • matter.status.changed
  • matter.accessed
  • document.created
  • document.accessed
  • document.transmitted (to external party — high importance)
  • document.deleted
  • document.version.created

Skill invocation events

  • skill.invoked
  • skill.completed
  • skill.failed
  • skill.escalated (skill routed to human review)

Conflict and compliance events

  • conflict.check.run
  • conflict.check.result.clean
  • conflict.check.result.concern
  • conflict.check.result.conflict
  • aml.screening.run
  • aml.flag.raised

Data events

  • data.export.requested
  • data.export.delivered
  • data.deletion.requested
  • data.deletion.completed

Admin events

  • user.created
  • user.role.changed
  • user.access.granted
  • user.access.revoked
  • org.settings.changed

Tamper-evidence (chained hashes)

For regulatory and malpractice defensibility, the audit log must be tamper-evident:

  1. Compute entry_hash = SHA256(event_id + event_type + timestamp + actor + resource + action + prev_hash).
  2. Each entry's prev_hash is the entry_hash of the immediately preceding entry.
  3. Any insertion, deletion, or modification breaks the hash chain.
  4. Periodically anchor the chain head to an external timestamp authority (e.g., RFC 3161 timestamp token) for legal evidentiary strength.

Indexing strategy

Index Purpose
(org_id, timestamp) Org-scoped time-range queries
(actor.user_id, timestamp) User activity history
(resource.id, timestamp) Resource event history
(event_type, timestamp) Alert and monitoring queries
(context.trace_id) Cross-service trace correlation
(action.result, event_type, timestamp) Failure analysis

Use a write-optimized append-only store (e.g., ClickHouse, BigQuery, S3+Athena, or a dedicated audit table in PostgreSQL with UNLOGGED disabled and row-level security). Do not use the same database table as application data.

Retention policy

Event category Minimum retention Rationale
Authentication 1 year Security investigation
Matter / document access 7 years Bar file retention; malpractice
Conflict check 7 years Bar discipline defense
Skill invocations 2 years Operational; AI accountability
Financial events (billing, invoices) 7 years Tax and audit
Data deletion events Permanent Proof of compliance

Retention may be extended by firm policy or jurisdiction-specific requirements.

Access control

  • The audit log is readable by: system admins, managing partner (org-level), compliance officer.
  • Individual users can read their own events only.
  • No user — including admins — can delete or update audit log entries.
  • Write access: system only (no user-facing write endpoint).
  • [[eng-langfuse-trace-inspector]]
  • [[eng-latency-slo-by-skill]]
  • [[eng-cost-per-message-tracker]]
  • [[eng-mcp-tool-registry]]