Verifying EVE MCP Execution Evidence
MCP execution evidence records that an approved MCP (Model Context Protocol) tool request and the request that actually executed are the same request — cryptographically bound. Any mutation between approval and execution is rejected before the side effect. The evidence lets a reviewer confirm approved-versus-executed binding and single-use authorization consumption — without trusting the EVE server.
Readiness: MCP execution binding, authenticated MCP identity, and distributed
single-use consumption are PILOT_READY (distributed-pilot validated in the documented test
topology). This is at-most-once authorization consumption, not remote exactly-once
execution.
What it proves
- Approved == executed — the approved-request digests (intent, capability schema, server identity, context) match the executed-request digests. A payload mutated after approval does not match and is rejected before the tool runs.
- At-most-once consumption — the single-use authorization was atomically consumed
(
authorization_consumed: true). Racing consumers of the same authorization see exactly one winner; the rest are recorded asREPLAY. - Server-derived identity — tenant, principal, and session are derived from authenticated
context, not from the payload or reverse-proxy headers. A forged identity header is rejected
(
MCP_UNTRUSTED_PROXY_IDENTITY) and payload/header identity assertions must match. - Authenticity + integrity — the evidence is signed (Ed25519 in the production
configuration; HMAC-SHA256 fallback is symmetric and not independently verifiable) over
jcs-1canonical bytes.
What it does NOT prove
- It does not provide remote exactly-once execution. When the remote outcome is
unknown, it is recorded as
OUTCOME_UNKNOWNand is never silently retried. Binding guarantees at-most-once authorization, not that a networked side effect happened exactly once. - It does not prove the tool did the right thing — only that the executed request equals the approved request and that authorization was consumed at most once.
- A cancellation during or after send records
OUTCOME_UNKNOWN; reuse of that authorization is aREPLAY. The evidence does not assert whether the cancelled operation had a remote effect.
Required keys
MCP execution evidence carries at least:
| Field | Meaning |
|---|---|
schema / schema version |
Execution-evidence schema identifier |
| approved digests | Intent / capability-schema / server-identity / context digests |
| executed digests | The same digests as executed |
authorization_consumed |
true when the single-use authorization was consumed |
binding_mode |
e.g. ENFORCED |
policy_version |
Policy version the base decision was evaluated under |
base_decision_id |
Reference to the CoreGuard decision |
| identity | Server-derived tenant / principal / session |
backend_type |
Consumption backend (e.g. postgresql) |
content_hash |
Digest over the canonical payload bytes |
canon |
Canonicalization identifier — jcs-1 |
kid |
Signer key identifier |
signature |
ed25519-... (production) or HMAC fallback |
A strict verifier additionally rejects evidence bearing a test stub / anonymous marker.
Canonicalization (jcs-1)
Evidence is signed over jcs-1, a constrained RFC 8785 profile with proven byte-for-byte
parity across Python, TypeScript, and the browser for the supported value domain. jcs-1
fails closed on non-integer floats / NaN / Infinity. A verifier reading evidence whose canon
is not jcs-1 reports unsupported canonicalization.
Verification profiles: strict vs standard
- Standard — verifies canonicalization, content hash, signature, schema, and that the approved digests equal the executed digests.
- Strict — additionally requires an independently verifiable Ed25519 signature, requires
authenticatedidentity (server-derived, not asserted), and rejects any evidence containing a test stub / anonymous marker. Use strict for external audit. The Python strict verifier isverify_execution_evidence(require_authenticated=True); the Node strict verifier is the--strict-prodmode.
Linked evidence
- Decision Certificate — the base CoreGuard decision referenced by
base_decision_id/policy_version. - Artifact Scan Evidence — if the tool argument was a file, the scan decision that bound the artifact digest.
- Red Team Report — adversarial chains that exercise MCP binding (approval → mutate payload → execute is caught by binding).
Verify each linked artifact independently.
Selective-disclosure / omission checks
The signature covers the whole canonical payload, including both the approved and executed
digest sets and the identity fields. Removing or altering a digest invalidates the
content_hash and the signature. Verify the full evidence, then compare the (already covered)
approved and executed digests; do not re-canonicalize a reduced object.
Failure categories
| Category | Meaning |
|---|---|
| invalid signature | Signature does not match the canonical content under the given key |
| unknown key | kid / public key not recognized or not supplied for a strict check |
| unsupported schema | Evidence schema version is not understood by this verifier |
| unsupported canonicalization | canon is not jcs-1 |
| digest mismatch | Approved digests != executed digests, or content_hash mismatch |
| selective omission | A signature-covered digest or identity field was removed/altered |
| stale | Evidence is older than your freshness window |
Related runtime reason codes you may see recorded in the evidence itself include
MCP_UNTRUSTED_PROXY_IDENTITY (forged identity header), BACKEND_UNAVAILABLE (consumption
backend down — request fails closed, transport not run), and OUTCOME_UNKNOWN (remote outcome
unknown after consume).
Freshness
Execution evidence records a completed binding and does not expire on its own. Enforce a
freshness policy on the decision/execution timestamp for real-time acceptance, and treat
over-age evidence as stale.
Replay behavior
Replay is a first-class, observable state. A single-use authorization is atomically
consumed once; a second attempt to consume it is recorded as REPLAY and produces no
additional side effect. In the documented distributed test topology, 50 separate OS processes
racing one authorization produced exactly one winner and one recorded side effect, with the
other 49 recorded as REPLAY. Re-presenting completed execution evidence does not re-authorize
or re-execute anything.
Verify it yourself
Python
# Strict MCP verification requires authenticated, server-derived identity. The
# unified verifier ships with the EVE service (not the pip client wheel); the first
# argument is the evidence KIND. Synthetic fixture — no production credentials.
import json
from core.eve_sdk import verify_evidence
with open("mcp_execution_evidence.json", "r", encoding="utf-8") as fh:
evidence = json.load(fh)
# strict=True routes to verify_execution_evidence(require_authenticated=True),
# which rejects asserted identity and test-stub / anonymous markers.
result = verify_evidence("mcp", evidence, strict=True)
print(result["valid"], result["reason"]) # True, "verified"
# Pip-wheel path for content-hash + Ed25519 signature only (no identity check):
# from eve_coreguard import verify_decision_record
# r = verify_decision_record(evidence, public_key_pem=public_key_pem)
# assert r.valid and r.independently_verifiable
Node (TypeScript / ESM, Node >= 18)
import { verifyEvidence } from "@eve/coreguard";
import { readFileSync } from "node:fs";
const publicKeyPem = readFileSync("public_key.pem", "utf8");
const evidence = JSON.parse(readFileSync("mcp_execution_evidence.json", "utf8"));
// The browser-safe verifier checks content hash + Ed25519 signature. The
// authenticated-identity ("strict-prod") check is a service-side path, not the
// browser verifier — see verify_execution_evidence(require_authenticated=True).
const result = verifyEvidence(evidence, { publicKeyPem });
console.log(result.valid, result.signature); // true "ed25519-valid"
CLI
# The `eve` CLI ships with the EVE service/repo. strict=True enforces authenticated
# identity for MCP evidence; the Ed25519 public key is auto-fetched from the issuer.
python -m core.eve_sdk.cli verify mcp mcp_execution_evidence.json --strict
Readiness
- MCP execution binding, authenticated MCP identity, and distributed at-most-once
consumption are
PILOT_READY— distributed-pilot validated in the documented single-host, multi-process PostgreSQL topology; true multi-host across networked machines is argued from PostgreSQL transactional guarantees, not yet demonstrated across hosts. - Offline verification (Python / Node / browser) is
SUPPORTED;jcs-1isSUPPORTED(constrained RFC 8785 profile). - MCP governance runs in
mcp_gateway/ embedded (service) mode; the Pythoneve-coreguardclient (0.2.1) reaches the service via hosted mode. TypeScript verifies offline and never signs. - Independent verification requires the Ed25519 public key; the HMAC fallback is symmetric and not independently verifiable.
- The release-candidate clients are distributed privately for pilots — install the pilot artifact, not a public
pip/npminstall (see readiness for public-registry status).
Limitations
- Binding provides at-most-once authorization consumption, not remote exactly-once
execution; unknown remote outcomes are recorded as
OUTCOME_UNKNOWNand never silently retried. - Distributed consumption was validated across separate OS processes on one host with a real PostgreSQL; multi-host across networked machines is not yet demonstrated.
- Authenticated identity requires the authentication middleware to be mounted; reverse-proxy identity headers are rejected as untrusted.
- HMAC-fallback signatures are not independently verifiable; use the Ed25519 configuration and the strict profile for external audit.