Independent Verification Overview
Export it. Run our verifier. Detect tampering across the full permit lifecycle without requiring access to Keel’s internal systems.
This playbook is for security and compliance reviewers who want to validate Keel’s audit evidence before procurement, during an incident, or during a periodic audit. You do not need Keel-internal access. Since v1.0.2, the verifier ships with the production trust root bundled — closure verification works on a fresh pip install keel-verifier with no key flags. You need the export artifacts, the public key manifest, and the standalone verifier.
What independent verification proves
Independent verification proves that the artifact you hold is internally consistent under the cryptographic evidence Keel published with it.
For a signed export, you verify:
- the export bundle’s SHA-256 digest matches the digest recorded in the export manifest;
- the export manifest’s Ed25519 signature validates under the expected export-signing key;
- bundled governance chain entries recompute to their recorded hashes when you run
--walk-events; - adjacent bundled chain entries point to each other in sequence order;
- permit closure records carry valid Ed25519 signatures when you run
--verify-closure; - v6 permit binding hashes cover nested agent-payment rail evidence (x402, AP2, PayPal, Visa, Mastercard, OpenAI ACP, L402, UCP) stored inside
resource_attributes_json, sokeel-verifier3.3.0+ can independently verify that included rail evidence matches the signed permit binding; - closure dispatch request digests match the Phase A request body bytes binding when the export carries closure v2 evidence;
- closure records agree with provider-response and client-delivery digest evidence inside the bundled chain entries.
This is stronger than trusting a dashboard status. You are checking the export locally, with published verification material. Where the export includes the corresponding checkpoints or timestamp receipts, the covered evidence is part of Keel’s tamper-evident, externally anchored, independently witnessed integrity story.
Verification across binding versions
Keel signed evidence comes in multiple binding versions. As of 2026-06-06, two canonicalization profiles are in use:
| Binding version | Profile | Verification path |
|---|---|---|
| v6+ (new artifacts) | RFC 8785 (JSON Canonicalization Scheme — JCS) | Verify with keel-verifier 3.3.0+ OR any RFC 8785 implementation in any language. v6 also covers nested agent-payment rail evidence (x402, AP2, PayPal, Visa, Mastercard, OpenAI ACP, L402, UCP) stored inside resource_attributes_json in the permit binding hash. |
| v5 | RFC 8785 (JSON Canonicalization Scheme — JCS) | Verify with keel-verifier 3.2.0+ OR any RFC 8785 implementation in any language. No Keel-specific code required. |
| v1-v4 (historical) | Keel-defined canonical (see keel-permit/spec/canonical-json.md §1-§8 ) | Verify with keel-verifier. Third-party verification requires porting the §1-§8 spec into your language. |
Verifying v5+ artifacts with any RFC 8785 library
For binding version v5 and later, the canonical JSON used in Keel’s signatures conforms to RFC 8785. Any third-party implementation in any language can verify v5+ Keel-issued evidence using its language’s standard RFC 8785 library:
| Language | RFC 8785 library |
|---|---|
| Python | rfc8785 (PyPI) |
| Node.js | canonicalize or json-canonicalize (npm) |
| Go | github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer |
| Rust | jcs (crates.io) |
The verification flow is:
- Load the signed Keel artifact (e.g., a permit decision).
- Extract the
binding_version,canonicalization_profile, and signed fields. - Recompute canonical bytes using your language’s RFC 8785 library.
- Recompute the SHA-256 hash and compare to the signed binding hash.
- Verify the Ed25519 signature using the public key from Keel’s signing-key registry.
For convenience, we also publish keel-verifier (Python, on PyPI), which performs all of the above offline and ships with Sigstore + transparency-log verification of the verifier package itself.
What changed in v6?
Substrate-v6 keeps the RFC 8785 canonicalization profile and expands the signed permit-binding surface. Nested agent-payment rail evidence (x402, AP2, PayPal, Visa, Mastercard, OpenAI ACP, L402, UCP) persisted inside resource_attributes_json is now included in the permit binding hash.
With keel-verifier 3.3.0+, a reviewer can independently recompute the v6 binding hash from the exported permit evidence and compare it with the signed binding. If covered rail/tool evidence in resource_attributes_json is changed after signing, that change is detectable during verification.
This is a scope-bound integrity claim: the verifier checks the exported evidence it was given. It does not establish that every possible rail event, tool call, provider event, or downstream side effect was recorded.
Why two profiles?
Substrate-v5 (June 2026) adopted RFC 8785 as the canonicalization profile for all new signed artifacts after a 2026-06-04 audit confirmed pre-v5 Keel canonical was byte-equivalent to RFC 8785 for every realistic Keel payload, with divergences confined to edge cases the type system never reached. Historical v1-v4 artifacts are preserved byte-stable so existing signatures remain verifiable forever; v5+ artifacts use the stricter standard so any RFC 8785 implementation can verify them independently.
What independent verification does NOT prove
The verifier proves exported evidence has not been altered after signing. Like any signing system, the trust boundary includes the signer at signing-time. Defending against privileged signing-time manipulation requires a higher-assurance signing architecture beyond the scope of this verifier.
The verifier detects modification after signing, broken chain continuity inside the exported window, invalid closure signatures, and digest disagreement among the records included in your bundle. It does not prove that a compromised writer could not have signed false evidence before the export was created.
That is the writer-at-signing-time trust boundary. If your threat model requires protection from a compromised writer at the moment evidence is produced, treat that as a separate TEE-backed or HSM-backed attestation requirement. The current verifier does not make that claim.
The verifier also does not prove:
- that the export includes every record that should exist;
- that a record’s business decision was correct;
- that the provider behaved correctly;
- that Keel meets a particular regulatory control by itself;
- that your own downstream handling of the export preserved chain of custody.
Your audit conclusion should say exactly what was verified: artifact integrity, chain walk consistency, and closure evidence consistency for the supplied bundle.
When to run the verifier
Run the verifier during security review.
Ask Keel or your Keel admin for a signed export that includes chain entries. Run verification yourself before relying on any claim about tamper evidence.
Run the verifier during incident response.
If you are investigating a disputed permit, a provider response, or a suspected audit-integrity issue, request an incident-scoped export and verify it before analysis. Preserve the original files and command output.
Run the verifier during periodic compliance audit.
For SOC 2, HIPAA Security Rule, ISO/IEC 42001:2023, NIST CSF, or internal AI-governance review, run the verifier against a time-boxed sample export. Keep the verifier version, key manifest, command, and output in your audit file.
What you’ll need
You need three artifacts:
| Artifact | Why you need it |
|---|---|
| Signed export bundle | The audit evidence you are verifying. Request it with chain entries included. |
| Export manifest | The signed manifest for the bundle. It records the content hash, signature, signing time, and export-signing key material. |
| Public key manifest | The manifest from GET /v1/compliance/keys. It contains retained public verification keys and active windows for key rotation. |
You also need one verifier:
- the
keel-verifyCLI binary or pip-installable script; or - a clone of the published verifier repository if your review process requires inspecting or pinning the verifier distribution.
For the exact command sequence, see Running Keel Verify. For every tamper-detection code emitted by the current verifier, see Tampering Detection Matrix.