Audit
Every legally relevant action is logged in three places:
- AccessLog: every API request (route, method, status, hashed
IP, hashed user agent). Pruned at 90 days.
- ExportLog: every download of a proof bundle, redacted PDF, or
raw atom export. Retained for 7 years.
- IntegrityAlert: every detected discrepancy between Postgres
and the chain. Retained until resolved.
Hashed IPs
IPs are hashed with IP_HASH_SALT (Vercel env var) before storage.
The salt is rotated quarterly; the post-rotation hash is incompatible
with the pre-rotation hash by design.
Integrity-check job
/api/cron/integrity-check walks the last 24h of anchors and
asserts each chain agrees. Discrepancies write IntegrityAlert rows
that the admin dashboard surfaces in red.
Cross links
/docs/security/encryption: how the audit tables are encrypted/docs/compliance/soc2: which controls map to audit