Skip to main content

Audit Decision schema

One append-only row per allow/deny, written and committed before the enforcement point is told the outcome. See Audit Log for why the write ordering matters.

Invariants enforced by the database itself, not just application code​

ConstraintMeaning
outcome IN ('allow', 'deny')No third outcome
(outcome = 'deny') = (deny_reason IS NOT NULL)An allow never carries a reason; a deny always does
hop >= 1
target_kind IN ('tool', 'agent')
chain_complete = (chain_break IS NULL)A complete chain never carries a break reason, and vice versa
hop > 1 OR parent_action_id IS NULLA root hop (hop 1) has no parent
UNIQUE(seq)Total order for keyset pagination and chain-write ordering

These are Postgres CHECK/UNIQUE constraints, not just Pydantic validation — an invariant violation is rejected by the database even if application code has a bug.

AuditDecisionListItem (one row of GET /v1/audit/decisions)​

Includes session_id, acting_agent, target, target_kind, data_class, outcome, deny_reason, enforced, taint, policy_version, hop, action_id, ts. See Audit API for the paginated envelope (AuditDecisionPage).