//Compliance Audit-Log API

Compliance Audit-Log API

A compliance-grade, append-only, tamper-evident audit read surface. Every audit record is linked into a per-org SHA-256 hash chain, so any edit, gap, or deletion is detectable. This endpoint returns recent rows and reports whether the returned set verifies as a contiguous chain.

Endpoint

GET /api/admin/apps/:app_id/audit-log

Returns recent audit rows for an app, with chain verification.

Auth: app admin (app owner or superuser).

Query Parameters:

  • org_uuid (optional): filter to a single chain. The chain key
  • is the org_uuid; omit for the platform (nil) chain mixed with all orgs. Mixing chains disables chain_valid.
  • action (optional): filter by action string.
  • limit (optional): default 100, capped at 500.
  • Output (200): ~~~json { "data": [ { "occurred_at": "2026-06-14T12:00:00.000000000Z", "actor_type": "user", "actor_email": "admin@example.com", "org_uuid": "…", "app_id": 50, "action": "app.security.policy_updated", "target_type": "org_security_policy", "outcome": "success", "chain_key": "…", "seq": 42, "prev_hash": "", "record_hash": "" } ], "chain_valid": true } ~~~

  • data — rows ordered ascending by (chain_key, seq).
  • chain_valid — true/false when the returned rows form one chain
with a dense, contiguous seq range; null when contiguity can't be established (an action filter skipped rows, or rows span multiple chains).

Tamper-evidence

Each row carries prev_hash (the prior row's record_hash) and record_hash = SHA-256(canonical(record) || prev_hash). Chains are partitioned by chain_key (the org_uuid, or the nil UUID for the shared platform chain); (chain_key, seq) is unique and dense. Verification recomputes the chain and flags any edited field, gap (deleted middle row), or broken link. Writes are append-only and serialized per chain — there is no update or delete path.