Two vendor-neutral paths that work without your gateway vendor's cooperation. Use either; use both for corroborated evidence.
Create a chained-observer source with your MCP server's URL. Interlok gives you an upstream URL; put it where your gateway's upstream setting points today:
agent → your gateway → Interlok observer → your MCP server
tools/call is signed after the response is returned, off the critical path: tool, argument hash, scrubbed arguments, outcome, result hash, timing, and what Interlok's own gate would have decided.x-interlok-observer-token) if your gateway supports custom upstream headers; a token in the URL path appears in access logs.Send one JSON object, a JSON array, or NDJSON (one record per line) to the webhook URL, signed with the source's key; or push with an API key to POST /api/v1/evidence-sources/<id>/events; or upload a .jsonl file in the console. Unknown fields are rejected, so a typo cannot silently drop evidence.
{"schema":"interlok.gateway-decision/1",
"event_id":"evt_01J9Z8K6Q1", // your gateway's own id (required, unique per source)
"occurred_at":"2026-10-09T14:03:11Z", // when the gateway decided (required)
"decision":"approve", // allow | deny | approve | hold | error | other
"tool":"github/create_release",
"server":"github-mcp",
"args":{"repo":"acme/api","tag":"v2.4.0"}, // or "args_hash": sha256 of RFC 8785 JSON
"agent":{"id":"agent-release-bot","type":"agent"},
"on_behalf_of":{"email":"dev@acme.com","type":"human"},
"approver":{"email":"lead@acme.com","type":"human"},
"policy":{"id":"pol_12","name":"releases need a human"},
"reason":"tag on main",
"correlation_id":"4bf92f3577b34da6a3ce929d0e0e4736"}event_id is recorded once per source. Retries are safe.approve is verified only if approver.type is human and names an id or email that is not the agent's. Otherwise it is recorded and marked unverified.t=$(date +%s)
sig=$(printf '%s.%s' "$t" "$(cat body.json)" | openssl dgst -sha256 -hmac "$INTERLOK_KEY" -hex | cut -d' ' -f2)
curl -X POST "$INGEST_URL" -H "content-type: application/json" \
-H "Interlok-Signature: t=$t,v1=$sig" --data-binary @body.jsonInterlok-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256(key, t + "." + body)>, five-minute tolerance. Up to 500 records or 2 MB per delivery.