Drop a Consent Tree evidence pack below. Your browser checks the signature and every file hash locally. Your pack is never uploaded, and the verification code makes no network call at all — if it did, it would be worthless.
To be exact, because it matters here: the page itself loads this site's shared navigation and cookie scripts on open, like every other page, so you will see those requests in your network tab. None of them carry your file, and none of them run during the check. If you would rather trust nothing on this domain at all, use the command-line verifier below.
Drop a pack here, or click to choose one
A pack.zip from the evidence vault. Nothing is uploaded.
Every pack is signed with an Ed25519 key. This is the public half — the value baked into the checker above:
Do not take that key from this page if it matters to you. This page is served by us — so if we were dishonest, we could serve you a forged pack and the key that verifies it, and this checker would go green while telling you nothing. That is a real limitation of any in-browser verifier hosted by the party being checked, and we would rather write it down than let the green tick imply otherwise.
The key is therefore also published in a public git repository, where every change is a timestamped commit hosted by someone other than us: consentree/ct-verify → SIGNING_KEYS.md. Pin it from there, then run the command-line verifier below, which talks to nobody at all.
ct-verify is a single Go file, about 500 lines, in
its own public repository.
Read it before you run it — the whole point is that you should not have to take our word for
anything, including about the verifier. It is MIT-licensed: fork it, audit it, or rewrite it
in another language. A second independent implementation would be a good outcome.
go install github.com/consentree/ct-verify@latest ct-verify --key 17d153ff…bdccce pack.zip ct-verify --key … --prev previous-pack.zip pack.zip # also check the chain link # or build it yourself, which is the better habit git clone https://github.com/consentree/ct-verify && cd ct-verify && go build -o ct-verify .
Exit codes: 0 fully verified · 1 a check failed · 2 unreadable input · 3 nothing failed, but not everything could be checked.
Don't want to install anything? openssl — already on your machine —
will parse the timestamp token on its own and tell you whether DigiCert actually granted it:
unzip -p pack.zip manifest.tsr > manifest.tsr openssl ts -reply -in manifest.tsr -text
Look for Status: Granted, a real timestamp, and a SHA-256 message
imprint. That alone proves DigiCert signed something at that exact moment — it does not yet
prove that something is this pack, or that this pack chains to the last one. Checking
that requires reproducing our canonical manifest hash byte-for-byte, including the exact way Go
serializes it — a real implementation detail, not a shell one-liner, which is why
ct-verify above exists as actual code instead of a recipe.
That the pack's files are exactly the bytes that were signed, that nothing was added or removed, that the signature is from the holder of the key you supplied, and — where a timestamp token is present — that an unrelated authority saw this content by a given date.
That the underlying facts are true. A signed pack is a faithful record of what our
systems reported; it is not an audit opinion, and we never issue one. It also says nothing
about anything the pack does not contain — which is why every pack carries a
disclosures.json, present even when there is nothing to disclose.
On this page, INCOMPLETE is the strongest verdict a genuine pack can earn — that is a ceiling, not a defect. The page checks structure, every file's hash, and the Ed25519 signature; it deliberately does not parse the RFC 3161 timestamp token (that needs CMS/ASN.1 and a certificate chain — more than a web page should pretend to do) and cannot follow the pack-to-pack chain with only one pack in hand, so those rows always read "not checked here". A full VERIFIED comes from the command-line verifier, which checks everything. And a pack with no timestamp token at all still reports INCOMPLETE there too: anchoring is best-effort in the producer, so an unreachable timestamping authority at generation time leaves the token out — in that case nothing independently establishes when the pack was made, and we would rather show you that than round it up to a tick.