Provenance

Decision ledger

Every Provenance Authorize authorize and verify call writes an append-only record: which token, which facts, which policy version, which rule, and the result. Months later you can answer "prove a human authorized this" — and prove the record wasn't edited after the fact.

The ledger is per account and tamper-evident: each record carries record_hash = sha256(canonicalize(record)) and a prev_hash linking to the account's previous record — the same hash-chain construction as our video chunk chain. Break any record and the chain no longer recomputes.

The record

| Field | Meaning | |---|---| | decision_id | ULID, primary key | | kind | authorize or verify | | result | valid | denied | pending | | reason | the deny/step-up reason code, when not valid | | facts | the policy fact object as evaluated (amount, action type, biometric_bound, tier…) | | matched_rule_id, policy_version | which rule of which policy version decided it | | jti, agent_session_id, device_id | the token/session/device bound | | record_hash, prev_hash | the per-account hash chain | | created_at | server timestamp |

Querying

# Newest-first, filterable + cursor-paginated (session or account key).
curl -s "$API/v1/decisions?result=denied&reason=policy_hardware_required" \
  -H "Authorization: Bearer $ACCT"
# → { data: [ … ], next_cursor: "01J…" }

curl -s "$API/v1/decisions/$DECISION_ID" -H "Authorization: Bearer $ACCT"

Filters: from/to (ISO time), result, reason, jti, session; page with limit + cursor. In the SDK: prov.decisions.list({ result: "denied" }), prov.decisions.get(id). The dashboard's Decisions view is a filterable table with a row drill-down (facts vs. matched rule vs. policy version).

Verifying integrity

curl -s "$API/v1/decisions/verify-chain" -H "Authorization: Bearer $ACCT"
# → { valid: true, count: 1234 }   (or { valid:false, broken_at, reason })

verify-chain recomputes the hash chain over an optional from/to range and reports the first break. In the SDK: prov.decisions.verifyChain(). The dashboard exposes a Verify chain button.

Notes