How to Verify a Receipt
Verify a WitnessOps receipt or proof bundle offline without trusting WitnessOps.
How do I check a receipt or bundle offline, and how should I interpret valid, invalid, and indeterminate verification results?
Use this page when you need to confirm that a WitnessOps receipt or proof bundle is authentic without depending on the WitnessOps runtime.
If you also need signer continuity against a reviewer-supplied trust anchor obtained outside the package, continue to Anchored Replay. This page covers verification of the package material itself, not trust-anchor onboarding.
Verification is an independent act. The verifier checks signatures, timestamps, hashes, and inclusion proofs locally, then reports exactly what was confirmed and what remains external trust.
What you'll do
- Confirm you have the receipt or bundle and the artifacts needed to verify it
- Verify the signature, execution binding, timestamp, and inclusion proof in order
- Distinguish cryptographic proof from the trust assumptions that remain outside the bundle
Canonical artifact
Start with the signed receipt and, when available, the full proof bundle that surrounds it.
At minimum, a verifier should have:
- The receipt JSON or exported bundle
- The signing public key or trusted key distribution source
- Any included RFC 3161 timestamp token and certificate chain
- Any included log checkpoint and inclusion proof
The more complete the artifact set, the more of the evidence chain you can verify offline.
Use this compact view to tell at a glance what you can verify from the files you have:
| Artifact set | What you can verify | What remains external trust |
|---|---|---|
| Receipt only | Signature, structure, and any embedded proof references | Key distribution, timestamp trust, log trust |
| Receipt + timestamp | Signature plus trusted time for the signed object | Key distribution, log trust |
| Receipt + timestamp + inclusion proof | Signature, trusted time, and log commitment | Key distribution unless the bundle includes trusted roots |
| Full proof bundle | Manifest integrity plus the full declared proof chain | Out-of-band trust roots and policy prerequisites |
Use the table below to separate what is required from what is only needed when the bundle claims a stronger proof layer.
| Artifact | Status | Why it matters |
|---|---|---|
| Receipt JSON or exported bundle | required | This is the statement and its surrounding proof material |
| Signing public key or trusted key distribution source | required | The signature cannot be checked without trusted key material |
| RFC 3161 timestamp token and certificate chain | conditional | Needed only when the bundle claims trusted time |
| Log checkpoint and inclusion proof | conditional | Needed only when the bundle claims log inclusion |
Procedure
1. Confirm the artifact set
Check whether you are verifying a standalone receipt or a fuller proof bundle.
If you only have the receipt, you can still verify the signature, structure, and any embedded proof references. If you have the bundle, you can also verify manifest integrity and surrounding evidence files.
2. Verify bundle integrity
If a MANIFEST.json is present, verify every listed file against its SHA-256 digest before you inspect the receipt itself.
If any file is missing or its digest does not match, the bundle is tampered and the rest of the chain should be treated as suspect.
3. Verify the signature
Verify the signed receipt or signed envelope against the expected public key.
The goal here is not just “does a signature exist,” but “does this exact payload verify against the trusted key material for the claimed issuer.”
If the signature does not verify, the receipt cannot be treated as authentic.
4. Check the receipt structure and execution binding
Confirm the receipt follows the expected schema and that its digest references match the included artifacts.
This step answers two questions:
- Is the receipt well-formed?
- Does it bind to the execution material it claims to describe?
If the structure is malformed or referenced digests do not match, the receipt is not internally consistent.
5. Verify the timestamp
If an RFC 3161 token is present, compute the digest of the signed bytes and verify the timestamp token against the TSA certificate chain.
Timestamp verification is local. You need the token and the certificate chain, not a live connection to WitnessOps.
If the timestamp does not verify, you may still have a valid signature, but you do not have trusted time for that signed object.
6. Verify log inclusion
If an inclusion proof and checkpoint are present, verify the proof against the checkpoint and verify the checkpoint signature against the log public key.
This proves the receipt digest was committed to the append-only log at that checkpoint size.
If the inclusion proof fails, the receipt may still be signed, but ledger commitment is not established.
7. Verify continuity when available
If the bundle includes a prior receipt, prior checkpoint, or continuity link, verify that the current artifact extends the prior state without breaks.
This strengthens the claim from a single valid receipt to a replayable history segment.
Expected results
A careful verifier should report each step separately rather than collapse everything into a single pass/fail result.
| Check | Possible outcomes |
|---|---|
| Bundle integrity | pass / tampered |
| Signature | valid / invalid / missing key |
| Receipt structure and binding | well-formed / malformed / digest mismatch |
| Timestamp | valid / invalid / not present |
| Log inclusion | valid / invalid / not present |
| Continuity | proven / not present |
A receipt can be signed and structurally valid even when timestamping or log inclusion are absent. The point is to report what is proven, not to pretend all assurances are identical.
Treat not present as acceptable only for optional or conditionally claimed artifacts. If a claimed proof layer is required by policy but the verifier cannot satisfy it locally, the result should be indeterminate, not valid.
indeterminate means the artifact may still be authentic, but the verifier could not establish a required external trust condition with the material available locally. That is different from invalid, which means a proof-bearing check failed.
Worked interpretation
- A signed receipt with no timestamp token and no inclusion proof can still verify as
validif no policy requires those layers. - A receipt whose signature verifies but whose trust root cannot be established locally should be
indeterminate. - A receipt whose signature, digest, or inclusion checks fail should be
invalid.
Worked examples
valid: a receipt JSON, trusted signing key, and matching manifest all verify; the bundle lacks a timestamp token, but no policy requires trusted time.invalid: the receipt signature checks out, but the manifest digest for the signed envelope does not match the bytes in the bundle.indeterminate: the receipt is well formed and the signature is plausible, but the verifier cannot establish the required TSA or log trust root from the local bundle.
Trust boundaries and failure modes
Even a fully verified receipt still depends on some external trust:
- The signing key must be trusted. The verifier needs to know that the public key in the bundle belongs to the claimed issuer. Trust root distribution is out-of-band.
- The TSA must be trusted. The timestamp is only as strong as the TSA's certificate chain and time source.
- The log operator is a single party. Without a witness cosigning checkpoints, a single log operator can theoretically present different views to different verifiers. Witness support narrows this.
Common failure modes are straightforward:
- Missing or mismatched files mean the bundle was altered or exported incompletely.
- Invalid signatures mean the claimed issuer did not sign the artifact you received.
- Invalid timestamps mean trusted time was not established.
- Missing inclusion proofs mean append-only publication was not demonstrated.
WitnessOps should be explicit about these boundaries instead of hiding them behind a green check.
Related pages
- Getting Started — first-run path for new operators
- Receipt Specification — field-level schema reference
- Proof Model — explanation of the artifact model behind verification
- Anchored Replay — reviewer-supplied trust-anchor onboarding for issuer continuity