Evidence
Every decision, approval, execution report and state change writes exactly one evidence record. Each record is signed by Polivor's evidence key and carries the hash of the record before it, so the records form a chain. The chain starts, for each tenant, at a genesis value of 32 zero bytes. Nothing in the API can edit or delete a record.
A record has: seq (its number in the tenant's chain), event_type, subject_id, payload (what happened, including the list of checks for a decision), prev_hash, hash, jws (the signature), key_version and created_at.
Read records
GET /v1/evidence?from_seq=<n>&limit=<m> (admin key) returns records in order, up to 1000 at a time.
Export a bundle
GET /v1/evidence/export?from_seq=<n>&to_seq=<m> returns a bundle with everything needed to verify the range without contacting Polivor:
- the records, with canonical payloads,
- all public keys (the JWKS),
- the authorizations issued for the decisions in the range.
At most 10,000 records per export; a larger range returns 422 RANGE_TOO_LARGE.
Verify a bundle
The verifier checks that:
- each record's
hashis the SHA-256 of the previous hash (32 bytes) followed by the canonical form of the payload (RFC 8785 JSON), - each
prev_hashis the previous record'shash, - each record's signature verifies with the public key named in its header,
- each authorization in the bundle is signed and matches the evidence of its decision.
Change one byte anywhere and verification fails at the first affected seq, and says which.
There are two verifiers. The console has a verifier page: load a bundle file and it runs in your browser, sending nothing anywhere. The standalone command-line verifier is a Node.js script (Node 20 or later, no other dependency) that uses no network and trusts only the bundle; ask us for it during the sandbox phase.
A bundle that does not start at record 1 verifies internally. The first record's prev_hash is then the anchor: compare it with the hash of the previous record you already hold.
What evidence does and does not say
It proves that Polivor made this decision with these checks at this time and has not changed it since. It does not, by itself, have a legal standing: Polivor's sandbox terms make no such promise, and that question is open until a lawyer has looked at it.