Verify a packet

Check a Castle packet right here, with zero install.

For carriers, examiners, and auditors who received a Castle evidence packet, a Transparent Statement, or a delegation chain export from a counterparty. Drop the JSON file below and this page runs the same castle_verify.py that ships inside every examiner packet, unmodified, on a CPython runtime compiled to WebAssembly, in your browser. The file you drop never leaves your machine.

What this page is, stated plainly

This is a convenience, not the authority. The authoritative check remains your own offline run of the verifier on your own machine. This page runs identical code and shows you its full output, byte for byte, so you can see exactly what an offline run would say. On first use it downloads the Python runtime from a public CDN (cdn.jsdelivr.net); that download is cached by your browser and never includes your file.

01 / Verify

Drop a packet

Drop a packet JSON here

or click to choose a file

Accepts an examiner packet, a Transparent Statement, or a delegation chain export (.json). From a downloaded pack ZIP, the signed file is packet.json; the exhibits are reports covered by it, not the packet itself. Nothing is uploaded; verification runs in this tab.

Demo data, signed with a demo key. Download the full sample packet ZIP to run the same check offline.
No registry loaded.

What you are looking at

What was checked

Technical report (verbatim verifier output)

            

Runtime unavailable, verify offline instead

The in-browser runtime could not load (you may be offline, or the CDN may be blocked on your network). The offline check is one command and needs only Python 3.10+ with the cryptography package:

python castle_verify.py packet.json

Get the verifier from castle_verify.py (the same file this page runs) or from the copy bundled inside your packet. Exit code 0 means the packet verified; the printed report explains every check.

A valid result proves integrity: the bytes you received are exactly the bytes that were signed. Without pinning the publisher's key it does not prove who signed, and it never proves the underlying evidence is complete. The verifier's own output states these limits and this page will not soften them.

The packet format this page checks is an open specification: github.com/bencrooks-dev/castle-spec (v0.2 draft). The verifier running on this page is byte-identical to the copy published in that repository.

02 / What gets checked

Every check, in plain language

  • Merkle root. The packet commits to a single root hash built from every artifact. The verifier rebuilds the whole tree from the packet's leaves and confirms it produces exactly the committed root.
  • Ed25519 signature. The signature over the packet's canonical bytes must verify against the signing key. Pin the publisher's out-of-band published key to prove who attested, not just that the bytes are intact.
  • Per-artifact hashes. Every artifact's recorded hash is recomputed and compared, so a single edited exhibit fails the exact leaf that was touched.
  • Inclusion proofs. Each artifact is proven to belong to the committed root on its own, so any one exhibit can be checked without the rest.
  • Public anchor, when present. If the packet was anchored in the public Sigstore Rekor transparency log (hashes only, opt-in), the anchor verifies fully offline against the log key pinned in the packet.
  • Receipts and countersignatures. A Transparent Statement carries receipts from an independent verifying instance; each receipt's signature and binding to the exact packet bytes is checked.
  • Delegation chains. Across a carrier, MGA, TPA chain, each link's countersignature is verified in order, so oversight rolls up on evidence rather than assertion.
03 / Privacy

How this page runs, exactly

The verifier on this page is the standalone castle_verify.py, served from this site and executed unmodified by Pyodide, a CPython interpreter compiled to WebAssembly. On first use your browser downloads the pinned runtime (Pyodide v0.27.7) and the cryptography package from cdn.jsdelivr.net; both are cached, so later visits load from cache. Your packet is written to an in-memory filesystem inside this browser tab, verified there, and discarded when you leave the page. No file you drop is ever part of a network request.

If your security policy does not allow loading the runtime from a CDN, use the offline command instead. It is the same file and the same checks.

04 / Verify node

Prefer a standing endpoint? Run a verify node.

If your organization receives Castle packets on an ongoing basis, you can run a free verification node instead of checking files one at a time: castle countersign serve re-verifies incoming packets over HTTP and can countersign them, so verified evidence rolls up your delegation chain automatically. Setup takes about ten minutes with the runbook we provide. Ask us and we will send the runbook and walk your team through it.