Offline verifier.
This page sends no analytics and sets no cookies.
Choose a local Ed25519 AGA bundle and an expected signing key. The file stays in your browser. Or try the published static sample, with its fixture key clearly labeled.
Sample signing key for /sample-bundle.json:b900a315c50d9516c4efcb7a2300c25c602855eac8aa3b5a9d0939234d738ebe
Sample-bundle SHA-256 (recompute and compare): 83b2cb8d22fa4568f3d1599d8a3fbde544723574d0dfdd48a11b55df9263c3c0
Live demo gateway key (distinct from the static sample key):c21d3d2def305160e69dcba4f829c204580d935b7c6ea7ede63168fa63584d0c
This key signs the public demo only. A PASS against it is not a customer attestation.
The demo gateway is aga-mcp-gateway.attested-intelligence.workers.dev. Its /bundle endpoint uses the live key above. Do not substitute a key from another host.
Offline: aga-verify evidence-bundle.json --pubkey <key> with the key that matches the bundle's source.
Drop an evidence bundle here
or click to browse
Don't have a bundle? Download a real signed sample and drag it in:
curl -O https://attestedintelligence.com/sample-bundle.jsonHow this works
Checks Ed25519 signatures on every receipt, hash-chain continuity, Merkle inclusion proofs, and a gateway-signed checkpoint that binds the root and the receipt count, all client-side. Pin a gateway key to also verify provenance.
This page starts with local upload. The sample tab fetches a static fixture; the optional Live Gateway tab contacts the demo only when you click its fetch button. Neither is evidence of customer activity or a fresh tool execution. To watch verification fail on purpose, the tamper bench on /proof mutates a real signed bundle one field at a time.
This in-browser checker reproduces the verification here as a demonstration. To check an AGA bundle outside this page, run the published aga-verify (npm) or aga-governance (PyPI) verifier. The VerifyBundle offline verifier is the verifier for VerifyBundle's own records (what it seals and proves).
Source: the MCP server, the aga-verify offline verifier, the receipt specification, and the conformance corpus are public at github.com/attestedintelligence/aga-mcp-server under the MIT license (the receipt-spec directory carries its own Apache-2.0 license).
Take it offline
Run the offline verifier yourself. Download our sample evidence bundle and verify it locally, no network required.
Sample evidence bundle
sample-bundle.zip contains three files: evidence-bundle.json, verify.mjs, and README.txt. Open a terminal in the extracted folder and run node verify.mjs evidence-bundle.json. It needs Node 18 or later, has zero dependencies, and makes no network calls. To also check which key signed it, add --pubkey with the sample-bundle signing key, printed here in full: b900a315c50d9516c4efcb7a2300c25c602855eac8aa3b5a9d0939234d738ebe. README.txt carries a copy, but it ships in the same zip, so pin the copy on this page. Pinning it shows the bundle matches the key this site publishes. This site and the bundle come from the same party, so the pin catches a bundle swapped on its own, not a download substituted together with this page.
Try the tamper test
Edit any signed field in evidence-bundle.json (a tool name, a decision, a hash, a timestamp), reorder receipts, or delete one, save it, and re-run verification. The verdict flips to FAIL, with an error indicating which check broke. An earlier genuine export presented as the current one still verifies, because the verifier has no freshness input.
- Some fields will not trip the verifier: bundle_id, schema_version, the envelope copy of policy_reference, offline_capable, any field the format does not define (at top level or inside a Merkle-proof entry), and JSON whitespace anywhere. They are unchecked, unsigned metadata, and nothing should be read from them.
- A field name repeated anywhere in the bundle (in a receipt, in the checkpoint or in the envelope) does not trip it either: this page and every published verifier read the last copy, so a forged value placed ahead of the genuine one passes, and a tool or a person reading the first copy can see a value that was never signed. Read the bundle's content from the verifier's parsed result, not from the raw file (see known issue 5 on /security).
- The other envelope copies (gateway_id, generated_at, merkle_root) are unsigned too, but the envelope-consistency check compares them against the signed checkpoint and the recomputed root, so editing them fails.
- The signed policy_reference inside each receipt is bound, and editing it fails verification. On aga-proxy it is the SHA-256 of the policy's canonical JSON (reformatting the file does not change it); aga-mcp-server 3.6.0 through 3.6.2 signs it as an empty string, so its bundles do not identify a policy.
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.
Want to try breaking one yourself? Try the interactive bench, or watch a denied call that never reached the tool (a recorded run under a custom allowlist). aga-proxy's default profile, permissive, denies nothing on policy grounds; policy denial needs --profile standard or restrictive, or a --policy file in allowlist or denylist mode.