Verify a Verdifax audit bundle
Every Verdifax run produces a sealed audit bundle, a structured JSON record of what happened (actor, model, decision, classification, effects) bound to cryptographic proof (manifest hash, per-artifact hashes, seal references). The bundle is designed so any third party can independently confirm that the recorded evidence is internally consistent, without trusting Verdifax, without contacting the API, and without any credentials.
verdifax-verify is the open-source command-line tool that performs
that check. It is the offline-verification path for Verdifax bundles:
the binary recomputes every hash from the bundle's own contents
without ever reaching the API.
Install
Go (any platform)
go install github.com/Verdifax/verdifax-verify@latest
The binary lands at $(go env GOBIN)/verdifax-verify, usually
~/go/bin/verdifax-verify.
Docker
If you do not have Go installed, the verifier ships inside the orchestrator container image:
docker run --rm -v "$(pwd):/work" ghcr.io/verdifax/verdifax-api:latest \
/app/verdifax-verify /work/bundle.json
Verify in 60 seconds (OK run)
For a sealed artifact from an OK run:
curl -s -H "X-Verdifax-Key: $VERDIFAX_KEY" https://api.verdifax.com/runs/63/artifacts | jq .manifest > manifest.json
verdifax-pepg-verify manifest.json
Sample output for OK manifest:
verdifax-pepg-verify 0.3.0
Manifest hash: 482f13e5c114551c507fb2ebff6df3f50a744e1fc1573b3a501e78aae8bae75c
PIPELINE ARTIFACTS
✓ envelope b5ff617aa37ce101...
✓ transport 0faf905e250d5e86...
✓ epa c7cd18d289828433...
✓ efa …
✓ aer …
✓ transcript …
✓ hardware_attestation …
✓ leakage_bundle …
✓ zksp_binding …
✓ migration_token …
✓ replay_fingerprint …
✓ pote_proof …
✓ final_vfa …
DECISION ARTIFACTS
✓ allow_token 6a2b4c8e9d1f5e3a...
✓ policy_hash 8f1d2c5e9a3b7f4c...
✓ evaluation_hash b2e0f5d1a8c3e7f9...
SEAL REFERENCES
✓ manifest_hash 482f13e5c114551c...
VERDICT: ✓ VERIFIED MANIFEST
Hash: 482f13e5c114551c507fb2ebff6df3f50a744e1fc1573b3a501e78aae8bae75c
Exit code is 0 on success.
Verify deny/halt receipts
For non-OK runs, the verifier handles sealed receipts (DenyReceipt, CCVHaltReceipt, MACCHaltReceipt):
# PEPG deny
curl -s -H "X-Verdifax-Key: $VERDIFAX_KEY" https://api.verdifax.com/runs/64/deny-receipt | jq .deny_receipt | verdifax-pepg-verify
# CCV halt
curl -s -H "X-Verdifax-Key: $VERDIFAX_KEY" https://api.verdifax.com/runs/65/ccv-halt-receipt | jq .ccv_halt_receipt | verdifax-pepg-verify
# MACC halt
curl -s -H "X-Verdifax-Key: $VERDIFAX_KEY" https://api.verdifax.com/runs/76/macc-halt-receipt | jq .macc_halt_receipt | verdifax-pepg-verify
The verifier CLI handles all four canonical-preimage formats. It recomputes the receipt hash and confirms it matches the sealed hash field.
What the verifier checks
The verifier's job is the same across all four outcome states: recompute the canonical preimage and confirm its SHA-256 hash matches the sealed hash field.
For OK runs (ExecutionManifest):
The verifier reconstructs the canonical preimage from all 18 manifest fields (envelope, transport, DKEC outputs, AER, ZKSP, Sealing, ledger, registry, DLA) plus the AllowToken decision fields, recomputes SHA-256, and compares against manifest_hash.
For pepg_deny (DenyReceipt):
The verifier reconstructs the preimage from envelope_id, policy_hash, evaluation_hash, fired_rule_id, decision_reason_code, mcd_finding_hash (if present), deny_clock, evaluator_version, and version, then recomputes SHA-256 against the sealed hash.
For ccv_halt (CCVHaltReceipt):
The verifier reconstructs from envelope_id, allow_token_hash, budget_hash, constraint_type, budget_limit, consumed_at_halt, partial_execution_hash, halt_reason_code, halt_clock, evaluator_version, version, then recomputes SHA-256.
For macc_halt (MACCHaltReceipt):
The verifier reconstructs from envelope_id, tenant_id, allow_token_hash, budget_hash, constraint_type, budget_limit, cumulative_at_halt, per_run_consumption, window_start, halt_reason_code, halt_clock, evaluator_version, version, then recomputes SHA-256.
Machine-readable vs. human-readable output:
The verifier CLI outputs machine-readable JSON (--json flag) for programmatic consumption. The audit PDF renders a human-friendly presentation of the same verification outcome.
Strict mode
Three artifacts in the bundle honestly declare themselves as scaffold
values, placeholders whose real cryptographic backing arrives in a
later build phase (transcript, hardware_attestation,
zksp_binding).
A fourth artifact, pote_proof, was historically scaffolded too. Its
scaffold flag is now cleared automatically when the run was sealed
against a real Sigstore Rekor ledger (the default for production runs).
Runs sealed in mock-ledger mode (dev/test) still carry the flag.
In default mode the verifier passes on scaffold artifacts: their hashes still recompute correctly because the scaffold value is part of the canonical content. The orchestrator is being honest about what is and isn't yet rooted in real hardware.
For high-trust environments (FedRAMP High, certain DoD use cases) where
nothing less than cryptographic root of trust counts, pass --strict:
verdifax-verify --strict --show-evidence-summary bundle.json
This makes the verifier exit 1 if any artifact carries
scaffold.is_scaffold = true. The --show-evidence-summary flag prints
a one-glance maturity report alongside the cryptographic verification,
including an explanatory verdict line so a strict-mode failure is never
mistaken for a cryptographic failure. Use this combined form as the
gate in your CI; the exit code drives the gate, the summary explains
the result.
Use in CI
A typical pipeline that wants to enforce both internal consistency and real hardware root of trust would call:
verdifax-verify --strict --json "$BUNDLE" > verdict.json
if [ $? -ne 0 ]; then
echo "Bundle did not verify under strict mode."
exit 1
fi
What the verifier does NOT prove
To set expectations honestly:
The verifier confirms internal consistency of a received bundle. It does not by itself prove that the underlying execution actually happened on Verdifax hardware. A malicious orchestrator could fabricate a bundle with consistent internal hashes. What the verifier rules out is the more common threat: evidence tampered with after the fact, someone modifying an actor id, a decision result, or a data classification on a real bundle and trying to pass it off as authentic.
For protection against fabrication, you also want:
- Manifest hash anchored to a transparency log (Sigstore Rekor).
✓ Live in production: every successful run is committed as a
hashedrekord entry on
rekor.sigstore.dev, the same public transparency log used by the Linux kernel and major open-source releases. The bundle's external witness is the public log itself. - Hardware-rooted attestation (TPM2 quote / AMD SEV-SNP report) bound to specific silicon. Scaffold today, the hardware-attestation step is designed to bind the run to a measured platform, but currently emits a scaffold value. Activates on confidential-compute deployment. See /concepts/scaffold-gaps/ for the activation procedure.
The verifier reports honestly when scaffold values are in play; nothing claims to be more than it is.
Verifier version
The current verifier is v0.3.0 and understands all four sealed artifact types (AllowToken, DenyReceipt, CCVHaltReceipt, MACCHaltReceipt) plus legacy artifact formats. It auto-detects the artifact schema from the version field and dispatches the correct canonical-preimage reconstruction.
Source code
The verifier is MIT-licensed and lives in its own public repository:
github.com/Verdifax/verdifax-verify
You are encouraged to read the source, that is the entire point of an open-source verifier.
