Verify it yourself¶
Reproduce a published certificate without trusting VeriLib’s UI alone. You check: (1) same image digest, (2) same INPUT_MANIFEST_SHA256 / image manifest, (3) extract counts/hashes match the published numbers, and (4) the on-chain record matches what you computed.
Steps 1–3 verify the lab: that the image you pulled is the one that produced the certificate. Step 4 verifies the claim independently of VeriLib — it reads Ethereum directly, so a compromised or simply wrong certificate page cannot fake it. If you only do steps 1–3 you are still trusting verilib.org to report the numbers honestly.
1. Pull by digest¶
2. Quick check (no Verus run)¶
docker run --rm --platform linux/amd64 --entrypoint '' \
IMAGE@sha256:DIGEST \
sh -c 'echo INPUT_MANIFEST_SHA256=$(cat /etc/dalek-probe-input-hash.txt); cat /etc/dalek-probe-image-manifest.json'
Compare to the certificate page / published manifest fields (dalek_lite_resolved_commit, etc.).
3. Full extract¶
docker run --rm --platform linux/amd64 IMAGE@sha256:DIGEST
# or from a clone of this repo:
./scripts/verify-local.sh YOUR_DOCKERHUB_USER/dalek-lite-probe:v1
./scripts/verify-local.sh --local dalek-lite-probe:local
Compare end-of-log verification counts, UNIFIED_EXTRACT_SHA256, and bundle hash.
4. Check the on-chain record¶
Certificates anchored on-chain emit a Certified event from the Certify contract. Reading it requires nothing from VeriLib except the transaction hash or the identifier — both of which are printed on the certificate page and can be independently confirmed on Etherscan.
| Network | Contract |
|---|---|
| Mainnet | 0x4f2a70eC878E9Adae88FF0c7528ebEbf83dFD83c |
| Sepolia | 0x125721f8a45bbABC60aDbaaF102a94d9cae59238 |
By transaction — open https://etherscan.io/tx/<mainnet_certify_tx_hash> (or the Sepolia explorer for sepolia_certify_tx_hash) and read the decoded Certified event.
By identifier — scan the logs yourself. Both identifierHash and contentHash are indexed, so this is a cheap filtered query:
# keccak256("owner/repo") — the indexed identifierHash
cast keccak "owner/repo"
cast logs --rpc-url "$RPC_URL" \
--address 0x4f2a70eC878E9Adae88FF0c7528ebEbf83dFD83c \
--from-block <certify-deploy-block> \
'Certified(bytes32,bytes32,address,string,bytes32,string,uint8,uint256)' \
<identifierHash>
Then confirm, from the event fields:
| Field | Check against |
|---|---|
contentHash |
The content hash you recomputed — keccak256(results_hash \|\| specs_hash [\|\| proofs_hash]). See doc/computing_hashes_locally.md. |
commitHash |
The dalek_lite_resolved_commit from the image manifest you read in step 2, as zero-padded bytes32. |
sender |
The expected authorized certifier — the BAIF Safe 0x8EAb4dB55DCEfb6D8bF76e1C6132d48D2048ef0e on mainnet. A different sender means a different contract instance. |
schemaVersion |
2 for the current contract. |
timestamp |
Plausible relative to the certificate's claimed date. |
You can also verify with the upstream CLI:
Not every certificate is anchored
On-chain anchoring is optional (ETH_CERTIFY_ENABLED, and a per-certificate eth_certify_enabled override on the request). A certificate with no sepolia_certify_tx_hash or mainnet_certify_tx_hash was never anchored — steps 1–3 are all the verification available for it. Mainnet anchoring is a separate, later promote action, so a valid certificate may be on Sepolia only.
Stats-site checklist¶
Upstream docs/CERTIFICATION_AND_VALIDATION_PSEUDOCODE.md lists what the public /cert/… page should expose for comparison. Optional HTML sketch: website/docker-hub-verify.html in the repo (if present on your branch).
Unknowns
Exact production Docker Hub org/tag for every language may differ from the dalek-lite examples; use the digest printed on the certificate you are validating.
Related¶
- Docker Hub
- Probe Docker image
- Certify contract — contract API, addresses, and trust model