Skip to main content
CMDashCybersecurity Maturity Dashboard
DocsFeature guidesVerifying a Proof Receipt

Verifying a Proof Receipt

What it is

The public verifier checks a proof receipt — its signature, its place in the transparency log, and its freshness window — entirely in your own browser. It never asks CMDash "is this receipt valid," because that would only ever mean "the server agrees with itself." The only network requests it makes are the ones you explicitly ask for (fetching a key document, a log checkpoint, or an inclusion proof), and only from the deployment you confirm.

It ships in two places, built from the same code:

  • /verify on the SaaS portal (www.cmdash.com/verify) — for anyone checking a receipt issued by a CMDash SaaS workspace.
  • /proof-verify/ on every CMDash deployment — so a self-hosted deployment, which may not run the portal at all, still has a working verifier at its own origin.

A "Verify →" link next to a receipt (on /proof/<receiptId> or a proof-bundle share page) opens whichever of the two applies for that deployment automatically: proofVerifyHref() sends a *.cmdash.net SaaS host to the portal's /verify, and everything else (self-hosted, local dev, or an operator's own portal URL) to that deployment's own /proof-verify/.

The page currently opens with a line reading "CMDash does not issue proof receipts yet" — a leftover placeholder from before proof receipts existed in the product. It has no effect on checking a real receipt you drop or paste in below it.

When to use it

Use it whenever you're handed a proof receipt — as a .json file, pasted text, or a share link — and need to know whether it's genuinely signed, hasn't been altered, is recorded in the transparency log, and is still within its freshness window, without trusting whoever sent it to tell you the truth.

Before you start

  • No login required. The verifier is public and works for anyone with a receipt, including people who have never used CMDash.
  • Nothing is uploaded. Verification runs client-side; the receipt bytes never leave your browser except for the fetches you explicitly trigger against a deployment you've confirmed.

How to

Load a receipt

Drop a .json receipt file onto the page, use the file picker, or paste the receipt text directly. The reader is strict — it refuses a receipt with duplicate JSON members rather than silently keeping the last one (a plain JSON.parse would).

A ?r=<share-token> URL (from a proof-bundle share link) resolves automatically:

  • With &id=<receiptId> (a per-receipt "Verify →" link), that one receipt loads directly.
  • With just ?r=<token> and one receipt in the bundle, it loads directly too.
  • With just ?r=<token> and more than one receipt in the bundle, you get a picker to choose which one to verify.
  • A revoked, expired, or unknown token shows a plain-text notice — never a raw token or an internal error.

Confirm the deployment, then fetch trust inputs

Before any network request, you confirm which deployment issued the receipt (the page never guesses from a URL inside the receipt itself). Once confirmed, two optional fetches become available:

  • The issuer's key document — needed to check the signature against a key CMDash didn't just tell you to trust.
  • The log checkpoint / inclusion proof — needed to confirm the receipt is recorded in the transparency log at the index and tree size it claims. If the checkpoint route answers 404 for that size, the receipt is re-verified without its log section rather than treated as invalid outright.

Every fetch is capped in size and re-checks the origin; a plain-HTTP (non-loopback) fetch is flagged so you know the data travelled unencrypted.

Read the verdict

The verdict line leads with STALE before VALID when a claim's freshness window has closed — a stale receipt's signature can still be genuinely valid; the line says both, stale first. Below it, two lists explain exactly what the check does and does not establish, for example:

  • What it proves (when checked): the named key signed this exact payload; that key is published for this deployment and tenant; the payload hasn't changed since signing; what was measured and how, exactly as signed; the receipt's place in the transparency log, if checked.
  • What it does not prove: that the underlying source system told the truth; that the population measured is complete; that a control is effective rather than merely present and measured; that no newer receipt has since superseded this one.

Try it without a real receipt

The page includes a sample receipt you can load to see the flow before you have a real one to check.

Common questions

Do I need a CMDash account to use this? No — it's a public page built for anyone who receives a receipt, whether or not they use CMDash themselves.

Why does it ask me to confirm a deployment before fetching anything? So the verifier never silently trusts a URL embedded in the receipt itself to decide where to send follow-up requests — you decide that, explicitly, once.

What if the log checkpoint route 404s? That means the log never signed a checkpoint at that tree size (for example, a very recent receipt). The page re-verifies without the log section rather than reporting the receipt as invalid.

This page is the product manual, published from the repository at docs/user/feature-guides/verify-proof-receipts.md. Customers read the same text inside CMDash under Help. Last updated October 7, 2026.

Verifying a Proof Receipt — CMDash Docs