GOVERNANCE RECEIPTS
Proof you can check yourself¶
A receipt is the signed record of one governed step: what was read, which model or tool ran, and under which Gate Token. A run's receipts are linked into a hash chain, so changing, removing or reordering any one of them visibly breaks it.
This page is for the person who has to show somebody else what an AI agent actually did.
What makes it evidence rather than a log: you verify it, offline, against published keys. No dashboard is required, not even ours. A proof that needed us to confirm it would not be a proof.
Plain English up top, mechanics for developers and auditors one tab over.
Check the whole chain on your own machine, with no EKKA service in the loop:
Why anyone should believe a receipt
EKKA can prove what your agent did without ever having seen your data. The signature covers what happened, not what was in it. That is a No Knowledge Proof: EKKA holds a thumbprint of the content, which identifies it beyond argument and cannot be run backwards to recover it. The thumbprint, explained in full.
It holds however you run EKKA, hosted or in your own Enclave. Where your data lives is a separate choice, and this claim does not depend on it.
What records does a run leave?¶
Every run leaves two complementary records:
| Command | What it is | Where it lives |
|---|---|---|
ekka receipts show <run-id> |
The signed receipt chain, the Gate Token issued, each gate's receipt, and the final run summary, cryptographically linked. | Your Enclave's local audit chain, on your machine. |
ekka run show <run-id> |
EKKA's allow / deny decision for the run and each step. | EKKA Govern's authoritative record. |
Use ekka receipts show for the cryptographic proof of what executed; use
ekka run show for the governance decision, especially for a denied action,
which produces a decision but no receipt chain (nothing ran, so nothing was
signed).
What is in a receipt?¶
Each entry in the chain carries:
- a kind, which step it records;
- a sequence number and a link to the entry before it (a fingerprint of the previous receipt);
- a signed envelope and its claims, the facts of the step (which resource, which token, actor, timestamps, and hashes of the inputs/outputs).
The kinds you'll see (the label ekka receipts show prints → the actual kind
string on the wire):
| What the CLI prints | kind |
|---|---|
| Gate Token issued | kat_issued |
| Knowledge Gate receipt (a database-gate read) | knowledge_gate_receipt |
| LLM Gateway receipt (an AI-model-gate call) | llm_gateway_receipt |
| The tool-gate receipt (on MCP tool calls) | (the tool gate's receipt) |
| Run attestation (the closing summary) | run_attestation |
Why can the chain not be faked?¶
This is the important part, and it's the same idea people already know from blockchain.
Like a blockchain ledger, every receipt is cryptographically linked to the one before it, so you can't quietly rewrite history, change, remove, or reorder any entry and the links stop matching. The difference: your chain is private to your run, no coins, no mining, no public network, just the tamper-evidence.
Two properties do the work. Here they are in three depths, pick your lens:
- Signed = a wax seal. EKKA and each gate stamp every receipt with a secret only they hold. Anyone can check the seal is genuine; no one can forge it. So a receipt can't be faked, and EKKA can't later deny issuing one.
- Chained = numbered pages that quote each other. Each receipt carries a fingerprint of the page before it. Tear one out, change a word, or shuffle the order, and the fingerprints no longer line up, tampering is obvious.
- Yours to check. You don't take anyone's word for it: you re-run the check yourself, even offline, against EKKA's public seals.
- Signatures. Each step emits a signed envelope (JWS-style): the claims are signed with the issuer's private key, each gate (a database gate, an AI-model gate, a tool gate) and EKKA itself, each with its own key. You verify with the matching public key from EKKA's published key set. A valid signature proves both the issuer and that the payload wasn't altered.
- Hash chain. Each receipt stores
prev_hash, a cryptographic hash of the previous receipt (the first links to a genesis marker). Recomputing the hashes end-to-end detects any insert, delete, reorder, or single-byte edit. This is exactly the Merkle/blockchain construction, scoped to one run. - Independent + offline. Verification needs only the chain plus EKKA's public keys, no live call to EKKA, so the proof survives even if EKKA is unreachable.
- Authenticity & non-repudiation, every step is signed by its issuer, so its origin is provable and cannot be disowned after the fact.
- Integrity / tamper-evidence, the hash chain makes any alteration, omission, or reordering detectable; the evidence defends itself and does not depend on a trusted log store.
- Independent verification, assurance rests on public-key cryptography you can check yourself, not on trust in EKKA's UI or infrastructure.
- Complete decision record, allows and denies are both signed into the chain, so the absence of an action is provable, not merely unlogged.
How do I verify it myself?¶
This recomputes every prev_hash link and checks every signature against EKKA's
published public keys, entirely on your machine, no network required. It
takes no run id and covers the whole local chain; to read one run's signed
record, use ekka receipts show <run-id>. If a
single field, receipt, or ordering had been touched, verification fails. The
guarantee doesn't rest on trusting a dashboard; it rests on math you can re-run.
What does a denied action leave behind?¶
- An allowed run produces a full chain, Gate Token → gate receipts → run summary.
- A denied action produces no receipt chain, by design: EKKA refuses it
before the Enclave does any work, so there is nothing to sign. The refusal is
recorded as a decision instead, see it with
ekka run show <run-id>(e.g.RESOURCE_GRANT_DENIED). Proving that something did not happen is exactly what an auditor needs, and the deny decision is that proof.
In your dashboard¶
Your organization's dashboard shows the governance record for each run, the
decision per step, the tokens exercised, and the plan that ran, so your team can
review runs without the CLI. The signed cryptographic chain stays on the Enclave
via ekka receipts show for independent, offline verification.
What the chain does and does not prove¶
The chain proves integrity: nothing in it was altered, reordered or removed.
ekka audit verify recomputes every hash link and every signature.
Completeness is a different claim: that everything which happened is in the chain. Re-reading the chain can never prove this one, because an action that wrote no entry leaves a chain that still verifies perfectly. It has to be built in instead.
For the records that decide who may do what, it now is. Issuing or revoking a Grant, publishing a Skill, changing your organization's settings: the database refuses to commit the change unless the audit entry is written in the same transaction. Not checked afterwards, and not checked by us remembering to. The change and its record land together, or neither lands.
That is a real check, not a reassurance. If the entry had been missing, the first command would have failed.
Where this stops¶
Five kinds of record are protected this way today, not everything EKKA stores. Some tables mix a decision with routine machine bookkeeping. A running Enclave reports that it is still alive every few seconds, on the same row that records who claimed it, and demanding an audit entry per heartbeat would bury the decisions rather than record them.
Those are guarded a weaker way, and it is worth being plain that it is weaker: a build check refuses any new code path that changes authority without recording it. That catches a developer who forgets. It cannot catch a change made by some other route, which is exactly what the database constraint above does catch.
Refusals are in the chain too, so a denied action is as provable as an allowed one.
Why does this matter?¶
The hardest thing in compliance is proving a negative, that your AI never touched something it shouldn't. Because a resource you never granted can never appear in the chain, the signed record proves the AI never read it. That's the difference between an AI feature that is an audit liability and one that is an audit asset.