Execution Protocol — Open Specification
Version: 1.0.1 (draft) Status: Pre-public-launch draft. v1.0 will be finalized when the hosted reference implementation goes public. License: This specification is published under CC-BY 4.0.
1. Status
This document defines version 1.0 of the Execution Protocol. It is a pre-public-launch draft: the protocol shape is stable enough to implement against, but the specification has not yet entered public review. A public review window will open with the v1.0 launch; the closing date will be announced before any breaking change.
2. Abstract
The Execution Protocol defines a deterministic, stateless wire format for authorizing and committing autonomous-agent actions against real-world systems, with cryptographic proof of every committed action.
A protocol-conformant implementation MUST:
- Validate every request against the archetype's schema for
archetype+constraints. - Evaluate every action against the authorization-boundary stage with deterministic rules.
- Block actions that exceed delegation bounds and record the block in the receipt's audit chain.
- Emit a self-contained ES256-signed receipt for every terminal outcome (executed, blocked, failed).
- Refuse to commit any action that has not passed every required pipeline stage.
3. Terminology
- Action — a single committed change to a real-world system, produced by the protocol pipeline.
- Archetype — the named action shape (e.g.
PAYMENT_TRANSFER,HOTEL_RESERVATION,DATA_EXPORT). Determines whichconstraintsschema applies. - Constraints — the structured payload describing what the agent wants to do, validated against the archetype's schema.
- Scoped delegation token — an opaque token bounding what an agent is authorized to do (scope, spend cap, time-to-live, revocation path). Issued separately and supplied per-request.
- Authorization Boundary — the deterministic policy gate between probabilistic LLM intent and deterministic action commit; produces pass/block/escalate. (Colloquially: "the firewall.")
- Receipt — the self-contained signed artifact recording the terminal state of every action — executed, blocked, or failed.
4. Protocol overview
The protocol defines a single round trip:
Caller → POST /api/execute → Gateway
↓
Pipeline (8 canonical stages)
↓
Caller ← { kind, transaction_id, receipt_url, … }
No long-lived session state. No multi-step handshake. Every request is
independent and idempotent on the Idempotency-Key header.
5. Message format
Requests are JSON over HTTP POST. The canonical request shape:
{
"archetype": "string (required) — e.g. PAYMENT_TRANSFER",
"constraints": "object (required) — archetype-specific schema",
"payment_mode": "string (optional) — QUOTE_ONLY | RESERVE_IF_AVAILABLE | IMMEDIATE_CHARGE | IMMEDIATE_CHARGE_WITH_CHALLENGE",
"delegation_token": "string (optional) — opaque token bounding agent authority",
"deadline_ms": "number (optional) — soft deadline for the gateway pipeline"
}
{
"archetype": "string (required) — e.g. PAYMENT_TRANSFER",
"constraints": "object (required) — archetype-specific schema",
"payment_mode": "string (optional) — QUOTE_ONLY | RESERVE_IF_AVAILABLE | IMMEDIATE_CHARGE | IMMEDIATE_CHARGE_WITH_CHALLENGE",
"delegation_token": "string (optional) — opaque token bounding agent authority",
"deadline_ms": "number (optional) — soft deadline for the gateway pipeline"
}
Required headers:
Content-Type: application/jsonAuthorization: Bearer …(production; sandbox accepts no auth)EP-Version: 2026-04-27(production; defaults in sandbox)EP-Mode: production | sandbox(production; sandbox path implies sandbox)Idempotency-Key: …on every POST
Responses follow the gateway response shape:
{
"kind": "executed | held | needs_challenge | pending_settlement | failed | blocked",
"transaction_id": "uuid",
"receipt_id": "uuid",
"receipt_url": "https://…/r/<sig>",
"receipt_url_short": "https://…/r/<short>",
"message": "string",
"correlation_id": "string",
"details": { /* archetype-specific */ }
}
{
"kind": "executed | held | needs_challenge | pending_settlement | failed | blocked",
"transaction_id": "uuid",
"receipt_id": "uuid",
"receipt_url": "https://…/r/<sig>",
"receipt_url_short": "https://…/r/<short>",
"message": "string",
"correlation_id": "string",
"details": { /* archetype-specific */ }
}
Errors follow the error shape.
6. Authorization tokens
API keys are Bearer tokens supplied via the Authorization header. Sandbox
accepts no auth (the /api/sandbox/execute path or EP-Mode: sandbox
header signals test mode).
Scoped delegation tokens are opaque bearer artifacts bounding what an agent is authorized to do. Carry scope, spend cap, time-to-live, and a revocation path; validated server-side at each request. The wire format treats them as opaque strings — implementations choose their own encoding.
7. Authorization-boundary evaluation
The authorization boundary is the architectural separation between probabilistic LLM intent extraction and deterministic action authorization. No LLM is in the authorization path: every action MUST pass the boundary deterministically before commit.
The boundary MUST evaluate two rule families before any other stage:
- Hard-deny list — actions in the protocol's hard-deny list MUST be
blocked regardless of delegation. The hard-deny list MAY include
implementation-specific actions; it MUST include at minimum:
delete_audit_log,disable_boundary,rotate_master_key. - Delegation evaluation — the requested action MUST satisfy every constraint encoded in the supplied delegation token (action surface, resource scope, spend cap, expiry).
The boundary MUST emit one of three verdicts: pass, block, or escalate.
A block produces kind: 'blocked' in the response with a signed receipt
that records the block in the audit chain.
8. Anomaly + completeness checks
After the boundary, the pipeline MUST run two further deterministic checks:
- Completeness — every required field for the archetype is present
and non-empty. Missing required fields produce
kind: 'blocked'with a completeness error. - Math — anomaly assessment over recent activity for the agent. An action far outside the agent's typical pattern halts here.
Each check produces an entry in the receipt's entries[] audit chain.
9. Receipt generation
Receipts MUST follow the ep-receipt/2026-04-27 envelope. The receipt
includes:
version.spec— locked to'ep-receipt/2026-04-27'.receiptId,transactionId,agentId,sessionId— identifiers.created— ISO-8601 issue time. Not included in the signed bytes (so deterministic re-signing across replicas works under clock skew).entries[]— the audit chain. One entry per pipeline stage, plus a genesis sentinel at index 0. Each entry'shashcovers all of its own fields plus the previous entry'shashviapreviousHash.signature—{ kid, alg: 'ES256', value }. Thevalueis base64url of R||S (64 bytes for P-256).kidandalgARE in the signed bytes;valueis not (a value cannot cover its own bytes).eventType—'ORIGINAL'or one of the'AMENDMENT_*'types.paymentStatus—'charged' | 'not_charged' | 'pending_provider_confirmation'.money—{ offerCurrency, offerAmount, chargeCurrency, chargeAmount, … }, decimals as strings (never floats).idempotencyKey,replicaId,chainId,regulatoryFramework,metadata— bookkeeping.
Receipts MUST be self-contained: a verifier with only the receipt and the published JWKS for the kid MUST be able to confirm every check. The canonicalisation that drives the signature is RFC 8785 JCS.
10. Audit chain (per-receipt)
Each receipt's entries[] array forms a hash chain:
- Index 0 is
__genesis__withpreviousHashset to 64 hex zeros. - Each subsequent entry's
previousHashMUST equal the prior entry'shash. - Each entry's
hashcovers all entry fields excepthashitself — includingcost,latencyMs,metadata, andcheckpointSignature.
Tampering any byte of any entry breaks the chain at exactly that index.
11. Error codes
See Errors reference for the full catalog.
The hosted production gateway returns a deliberately tight shape — the gateway does not surface internal cause to the public response:
{
"code": "EP_…",
"request_id": "string",
"message": "string",
"correlation_id": "string"
}
{
"code": "EP_…",
"request_id": "string",
"message": "string",
"correlation_id": "string"
}
The public sandbox at /api/sandbox/execute returns a richer shape so
developers building integrations can iterate against structured fields:
{
"sandbox": true,
"error": {
"type": "string",
"code": "EP_…",
"message": "string",
"field": "string (optional)",
"remediation": "string[] (sandbox only)",
"request_id": "string",
"docs": "string (URL)"
}
}
{
"sandbox": true,
"error": {
"type": "string",
"code": "EP_…",
"message": "string",
"field": "string (optional)",
"remediation": "string[] (sandbox only)",
"request_id": "string",
"docs": "string (URL)"
}
}
Both shapes use snake_case identifiers (request_id, correlation_id)
and the same EP_-prefixed code namespace.
12. Discovery + JWKS
Implementations MUST publish a JWKS at /.well-known/jwks.json containing
every public key the signer has ever issued. Each JWK MUST carry the
standard fields plus four EP-extension fields:
ep_status: 'active' | 'verify-only' | 'compromised'ep_active_from: ISO-8601ep_active_through: ISO-8601(set on rotation)ep_compromised_at: ISO-8601(set on compromise; receipts created after this timestamp under this kid are quarantined)
Verifiers MUST gate on ep_status and ep_compromised_at against the
receipt's created timestamp.
13. Security considerations
See the Threat model for the full list. Key properties an implementation MUST preserve:
- Determinism — the protocol's policy evaluation is deterministic; replays of the same canonical receipt body verify identically.
- Statelessness — no inter-request session state.
- Token rotation — signing keys MUST be rotatable without breaking historical receipt verification.
- Hard-deny enforcement — the deny list MUST NOT be bypassable via the API.
14. References
- RFC 2119 — Key words for use in RFCs.
- RFC 7517 — JSON Web Key (JWK).
- RFC 7518 — JSON Web Algorithms (defines the
ES256alg name). - RFC 8785 — JSON Canonicalisation Scheme (JCS) — the canonical bytes the signature covers.
- FIPS 186-5 — ECDSA over P-256.
- FIPS 180-4 — SHA-256 hash function.
Notes on this document
Authors
A. Watts.