Skip to main content
Proof of value · In-browser verifier

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.

Zero AGA imports Ed25519 + SHA-256 Works offline

How to use this page

1

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.

2

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.

3

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.

Loading the sample bundle…
Cross-stack agreement

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.

MutationCheck(s) that FAIL, identical on every stackJSGoverify.py (cryptography)verify.py (stdlib)
sample bundle (unmodified)all 7 steps passVERVERVERVER
Flip one signature bytereceipt_signatures, chain_and_ordering, merkle_and_bijectionFAILFAILFAILFAIL
Drop a receiptstructural, merkle_and_bijection, signed_checkpointFAILFAILFAILFAIL
Reorder receiptschain_and_ordering, merkle_and_bijectionFAILFAILFAILFAIL
Alter a decision fieldreceipt_signatures, chain_and_ordering, merkle_and_bijectionFAILFAILFAILFAIL
Corrupt the checkpoint rootsigned_checkpointFAILFAILFAILFAIL
Corrupt the envelope rootenvelope_consistencyFAILFAILFAILFAIL

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.

Post-quantum · Reference profile

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 default

These 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.

KeyGen KAT
✓ PASS
SigGen KAT
✓ PASS
SigVer KAT
✓ PASS · 15 cases
Parameter set
ML-DSA-65
SigVer accept / reject
3 valid, 12 invalid
Interface
external / pure
Read this precisely. The bundle above, the live gateway output, and this in-browser checker are all classical Ed25519. The ML-DSA-65 result shown here is a captured run of the reference backend against the NIST vectors, evidence that the spec and corpus profile exists and passes. It is not a claim that the gateway signs post-quantum.
Honest scope

What this proves, and what it does not.

This demo proves the integrity of the records present: nobody without the signing key can alter a signed value the verifier reads, reorder, or trim the signed receipts or checkpoint of this bundle without the check against its pinned key failing, and that detection is available to anyone, offline, with the published JavaScript verifier, the published Python verifier (0.3.2) or the reference Go verifier. A field name repeated in the file still verifies (the verifiers read the last copy; read the verifier's parsed output; known issue 5 on /security). It does not constrain the gateway itself. One key signs both the receipts and the checkpoint, so a gateway that is also the party under audit can drop trailing receipts, rebuild the tree, re-sign a shorter checkpoint, and pass every check on this page including the pinned-key check. An earlier genuine export presented as the current one also passes, because the verifier has no freshness input. A PASS establishes what was recorded and signed. It does not prove that every action an agent took was recorded. That capture property is separate.
  • 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.
Verify us without trusting us

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.

$ npx -y @attested-intelligence/aga-verify@2.2.3 evidence-bundle.json

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.