Standalone offline verifier for Open Decision Receipts (ODR) -- check schema, JCS canonical digest, Ed25519 signature, and hash-chain linkage with no Aragora install or account.
Project description
aragora-verify
Verify an Open Decision Receipt offline — no Aragora install, no server, no account.
Action-level receipts (Microsoft AGT, SCITT, in-toto/SLSA) prove what happened and whether policy allowed it. An Open Decision Receipt (ODR) proves the layer above: why it was decided, who adversarially examined it with what model diversity, who dissented, how calibrated the confidence was, and whether an accountable human accepted the risk.
aragora-verify is the free, standalone tool that lets anyone — an auditor, a
customer, a skeptic — check such a receipt is genuine and well-formed:
- Schema conformance to the ODR v0.1 content profile.
- Canonical digest — recomputes
SHA-256(JCS(receipt − signatures))per RFC 8785, the value any detached signature covers. - Ed25519 signature — verifies detached signatures with only the public key.
- Quorum consistency — every supporting/dissenting agent is a disclosed participant (a mismatch is a tamper/malformed signal).
- Hash-chain linkage — when a chain is supplied, the receipt is anchored in it and the links are continuous.
It depends only on the Python standard library plus cryptography.
Install
pip install aragora-verify
Use
# Structural + canonical-digest check
aragora-verify receipt.odr.json
# Full authenticity check against the issuer's published public key
aragora-verify receipt.odr.json --pubkey aragora-odr-signing-key.pem
# Also confirm the receipt is anchored in a hash chain
aragora-verify receipt.odr.json --pubkey key.pem --chain intent-chain.jsonl
# Machine-readable result
aragora-verify receipt.odr.json --pubkey key.pem --json
Exit code 0 means verified (no failed checks, and any present signatures were
checked); 1 means a check failed; 2 is a usage/input error; 3 means the
receipt is structurally OK but carries signatures that were not checked
(no --pubkey supplied) — authenticity is unestablished, so it is deliberately
not reported as 0/VERIFIED.
The public key for receipts emitted by an Aragora deployment is published at
GET /.well-known/aragora-odr-signing-key and GET /api/v2/receipts/signing-key.
Weakening vs. failing
Absent markers ({"status": "absent", ...}) and "undisclosed" model families
are honesty signals — a receipt full of them is visibly weak, not a
strong-looking fabrication. They are reported as weakening signals and do
not fail verification; the policy thresholds (e.g. "require ≥2 model
families", "require human attestation") are yours to apply on top.
Known limitations (v0.1)
The verifier is deliberately conservative and these are documented, not silent:
- Hash-chain (
--chain) is anchoring + self-consistency, not integrity. It confirms the receipt's content digest appears in the chain and that declaredprev_hash/hashlinks are internally consistent, but it does not recompute entry hashes — so it reportschain_linkasWARNwhen links are present. A party who controls the chain file can fabricate consistent-looking linkage; the chain is corroborating evidence, not a tamper proof on its own. - Signature verification is single-key, Ed25519-only. It verifies that at least
one
signatures[]entry validates against the supplied--pubkey(and fails if an entry targeting that key fails). Richer multi-signer / threshold policies are out of scope for v0.1. - I-JSON numeric range. Canonicalization assumes IEEE-754-double-safe numbers (per RFC 8785 / I-JSON). Integers at or beyond 1e21 are not expected in ODR payloads and are not specially handled.
Library
from aragora_verify import verify, load_public_key
result = verify(receipt_dict, public_key=load_public_key(pem_bytes))
print(result.ok, result.odr_digest)
for check in result.checks:
print(check.name, check.status, check.detail)
What this is part of
ODR-3 of the Open Decision Receipt epic. The verifier is free and standalone by design — the emitter (adversarial debate + signed decision receipts) is the product. See the content-profile spec.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aragora_verify-0.1.0.tar.gz.
File metadata
- Download URL: aragora_verify-0.1.0.tar.gz
- Upload date:
- Size: 22.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d212bb7fbba11d8039bdd05cab3dd9621eb139fb491529736e668c61f02389f
|
|
| MD5 |
97eaf4782d54d33f9333d4b419cb1acb
|
|
| BLAKE2b-256 |
4c82d3e2ddcb96527ccb98cf25d0d7b913214576c07767f4aa86e127318930ba
|
File details
Details for the file aragora_verify-0.1.0-py3-none-any.whl.
File metadata
- Download URL: aragora_verify-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aabd545530329e484a0624c1c476ce2fbb7d36b7b82dd83bb9f7a8d185b0d2b
|
|
| MD5 |
4930f1b4343d495472ced9cdfef9017f
|
|
| BLAKE2b-256 |
c07173fe6424785c484b7be7b6fc90813101ea94fbddc0de5888338aceab1132
|