Verify the record yourself.
A signed fixture bundle in aga-proxy's receipt format: four tool-call decisions, a hash chain, a Merkle tree, and a signed checkpoint. Its receipt and bundle ids are bare UUIDs where aga-proxy writes them with an rcpt- prefix, and its unsigned schema_version label is 1.0 where aga-proxy writes 2.0. Seven cryptographic checks run live in this browser. Then tamper with it and watch the exact check catch you.
Open your network tab: verification itself makes no requests. A decision record you can check anywhere, offline.
How to use this page
Watch it verify
The clean bundle below is checked live and returns VERIFIED. All seven checks pass: the six integrity checks, plus the key match that a pinned key adds.
Break it yourself
Press a tamper button to flip one byte or drop one receipt. Watch the exact check that catches it turn red, then reset.
Bring your own bundle
Scroll to Verify your own bundle, paste or drop any AGA SEP bundle, and run the same six checks on your data.
Don't trust this page? Implemented in three toolchains, one verdict.
A single verifier is one witness. AGA ships reference verifiers in JavaScript, Go and Python. The clean bundle verifies on all three. Every tamper below fails on all three, and they agree on which internal check catches it. Re-run any of them and reach the same verdict. The table is a real captured run.
On narrow screens, scroll the comparison horizontally. Keyboard users can focus the table region and use the arrow keys.
| Mutation | Check(s) that FAIL, identical on every stack | JS | Go | verify.py (cryptography) | verify.py (stdlib) |
|---|---|---|---|---|---|
| sample bundle (unmodified) | all 7 steps pass | VER | VER | VER | VER |
| Flip one signature byte | receipt_signatures, chain_and_ordering, merkle_and_bijection | FAIL | FAIL | FAIL | FAIL |
| Drop a receipt | structural, merkle_and_bijection, signed_checkpoint | FAIL | FAIL | FAIL | FAIL |
| Reorder receipts | chain_and_ordering, merkle_and_bijection | FAIL | FAIL | FAIL | FAIL |
| Alter a decision field | receipt_signatures, chain_and_ordering, merkle_and_bijection | FAIL | FAIL | FAIL | FAIL |
| Corrupt the checkpoint root | signed_checkpoint | FAIL | FAIL | FAIL | FAIL |
| Corrupt the envelope root | envelope_consistency | FAIL | FAIL | FAIL | FAIL |
Captured run: 1 clean + 6 tampered bundles × 4 verifier engines = 28 verifications, plus the published npx @attested-intelligence/aga-verify on the clean bundle. Zero disagreements. The two Python columns are the reference verify.py in the aga-receipt-spec folder of the source repository, run with the cryptography library and with its stdlib Ed25519. The published aga-governance package on PyPI reports its own check names, so its per-check output differs from these columns.
ML-DSA-65 vectors run in the private reference runtime. The live signer does not use them.
Everything you verified above is classical Ed25519-SHA256-JCS, what the gateway signs and what this page checks. Separately, the private reference runtime (evaluation access) runs the NIST FIPS 204 ML-DSA-65 post-quantum known-answer vectors, which are not in the downloadable corpus, and the ML-DSA-65+Ed25519 composite profile is specified and reference-verified across two language oracles (a @noble/JavaScript engine and a CIRCL/Go oracle) in the reference implementation. The live gateway and the aga-verify CLI sign and verify classical Ed25519 only. No ML-DSA code path runs on this page.
ML-DSA-65 known-answer vectors (NIST ACVP, FIPS 204)
Reference profile, not the live defaultThese are the standardized NIST ACVP known-answer vectors the composite profile is tested against. They are pinned in the private reference runtime's test suite (evaluation access), not in the downloadable corpus, and that backend runs them as a gate: accept every valid signature, reject every invalid one.
What this proves, and what it does not.
- Classical Ed25519, not post-quantum in the live path.The live signing default here, in this bundle, in the live gateway output, and in the interactive checks above, is Ed25519-SHA256-JCS. No ML-DSA signature path runs on this page. The ML-DSA-65 panel above is a captured reference-corpus result, clearly labeled as a spec profile.
- Integrity, provenance, and order, not runtime blocking.Tampering with a decision record is detectable. This does not show runtime blocking or quarantine of a live agent, which is a separate and more limited capability.
- Tampers are structurally realistic but synthetic.They are programmatic single-field or single-byte mutations of a real signed bundle, chosen to hit each distinct check class, not captured from an in-the-wild attack.
- One gateway key.Every receipt here is signed by one published fixture key, which no gateway holds (its gateway_id label, aga-demo-001, is shared with the live demo gateway). Multi-issuer and key-rotation scenarios are out of scope for this demo.
The verifier is published. Check us with it
The same Ed25519-SHA256-JCS construction the gateway signs with is published as a standalone command-line verifier on npm. It is our own package, so the point is not that we vouch for it: run it yourself. The format is specified so you can re-implement it. Version 2.2.3 was manually published without a SLSA provenance attestation. Its retained archive hash and registry signature are separate checks; inspect the release evidence.
What you get depends on the key. Without a pinned key the verifier confirms integrity only: that the bundle is internally consistent under its own key. A separately trusted expected key also checks that the record was signed under that key. Connecting the key to a person or organization requires a trusted identity mapping. A key copied from the file does not establish its issuer, because a re-signed bundle carries its own matching key. A pin does not rule out the key holder signing a different history under the same key.
The sample-bundle signing key is a published fixture that no gateway holds, and the live demo gateway key is published at that gateway’s /pubkey. A deployment’s key persists only when AGA_GATEWAY_KEY or a valid AGA_GATEWAY_KEY_FILE is set; otherwise it is per-process.
Prefer the upload-first tool? Open the offline verifier.