Book a demo →
← All articles
Behind-the-scenes ops

Reading the audit log and verifying the hash chain

4 min read

HIPAA and SOC 2 both require non-repudiable audit logging on every PHI access. CredTek goes further — every audit row's log_hash is SHA-256(prev_log_hash || canonical_json(this_row)). This forms a tamper-evident chain: tampering with any historical row breaks every subsequent hash, detectable in O(n).

Where to find it

/ops/audit in the Ops view. Filter by actor type (system / user / agent / specialist), action, or resource. Each row shows the previous hash and its own hash so you can eyeball the chain.

What gets logged

  • Every IntegrationJob state transition
  • Every PHI read (provider profile view, document download)
  • Every PHI write (provider edit, document upload, payload modification)
  • Every authentication event (login, logout, MFA challenge, session refresh)
  • Every authorization decision
  • Every external system call (request and response, with PHI redacted)
  • Every admin action (user create, role change, settings change)

Verifying the chain

Production: a nightly background job recomputes the chain from genesis and pages on-call if a break is detected. You can also verify a range manually — recompute SHA-256(prev_log_hash || canonical_json(row)) for each row and compare against log_hash. Mismatches surface the exact row that was tampered with.

Demoing the chain to an auditor

The audit page UI shows enough context for an NCQA or HIPAA auditor walkthrough. If the auditor wants to verify the math, the verifyChain() helper at app/_lib/ial/auditChain.ts in the source repo is the reference implementation. SOC 2 Type II auditors love it.

Got a question this didn't answer?

The fastest path is a 20-min demo where we walk through your specific workflow.

Book a demo →