Adapter Contract
Adapter Contract (v2)
Section titled “Adapter Contract (v2)”Execution adapters are clients of Clasper Core. They are never peers and never trusted.
Adapters:
- authenticate with scoped adapter tokens
- request permission to execute (pre-execution decision)
- enforce the granted scope (time/steps/cost/capabilities)
- report telemetry back (ingest is mandatory)
Identity (required)
Section titled “Identity (required)”All adapter calls use:
- Header:
X-Adapter-Token: <jwt>
The token is minted by your platform and must be scoped to:
adapter_idtenant_idworkspace_idallowed_capabilities[]
Clasper Core verifies tokens using ADAPTER_JWT_SECRET.
Registration (recommended)
Section titled “Registration (recommended)”Adapters should register (and can be disabled at runtime):
POST /adapters/register
Example:
{ "adapter_id": "openclaw", "display_name": "OpenClaw Executor", "risk_class": "high", "capabilities": ["browser", "filesystem.read"], "version": "0.1.0", "enabled": true, "certification_tier": "community", "tool_capabilities": { "browser.navigate": ["browser"], "browser.execute_js": ["browser"] }}- certification_tier (optional):
verified|community|experimental— shown as a badge in the Ops Console. - tool_capabilities (optional): map of tool name → capability groups for tool-level scope.
Governed Execution Flow
Section titled “Governed Execution Flow”1) Decision
Section titled “1) Decision”Adapter requests permission:
POST /api/execution/request
Minimum fields:
execution_id(optional; generated if omitted)adapter_idtenant_idworkspace_idrequested_capabilities[]
Optional agent identity (for per-agent policies and budgets):
agent_id?: string— unique identifier for the agent (e.g. from multi-agent runtimes)agent_role?: string— role label (e.g.assistant,researcher)agent_metadata?: object— additional agent context
Optional execution context signals (recommended for high-risk capabilities like shell.exec):
intent?: string— human-readable declaration of why execution is requested (e.g.install_dependency,run_workspace_script)context?: object— high-signal flags about likely side effects:external_network?: booleanwrites_files?: booleanelevated_privileges?: booleanpackage_manager?: string(e.g.npm,pip,apt,brew)targets?: string[](e.g. domains/registries; optional)
provenance?: object— lightweight source metadata:source?: "marketplace" | "internal" | "git" | "unknown"publisher?: stringartifact_hash?: string
Notes:
- These fields are declarative, not authoritative.
- Missing fields are treated as unknown (they do not imply
false). - Policy matching currently supports a subset of fields:
- Supported:
intent,context.external_network,context.writes_files,context.elevated_privileges,context.package_manager,provenance.source,provenance.publisher, andcapability(matches againstrequested_capabilities[]). - Not matchable yet:
context.targetsandprovenance.artifact_hash(captured for audit only).
- Supported:
Example request:
{ "execution_id": "exec_abc123", "adapter_id": "openclaw", "tenant_id": "t1", "workspace_id": "w1", "requested_capabilities": ["shell.exec"], "intent": "install_dependency", "context": { "external_network": true, "writes_files": true, "package_manager": "npm", "targets": ["registry.npmjs.org"] }, "provenance": { "source": "marketplace", "publisher": "acme", "artifact_hash": "sha256:..." }}Decision response:
allowed: booleangranted_scope(if allowed)blocked_reasonorrequires_approval(if denied)decision: "pending"+decision_id(if async approval required)
2) Execute (adapter-owned)
Section titled “2) Execute (adapter-owned)”If allowed, adapter executes strictly within the granted scope:
capabilities[]max_stepsmax_costexpires_at
3) Ingest (mandatory)
Section titled “3) Ingest (mandatory)”Adapters must ingest telemetry after (and/or during) execution:
POST /api/ingest/tracePOST /api/ingest/auditPOST /api/ingest/costPOST /api/ingest/metricsPOST /api/ingest/violations
Signed telemetry (v2.1)
Section titled “Signed telemetry (v2.1)”All ingest payloads should be wrapped in a signed envelope:
{ "envelope_version": "v1", "adapter_id": "openclaw", "adapter_version": "0.4.1", "issued_at": "2026-02-06T14:12:33Z", "execution_id": "exec_abc123", "trace_id": "trace_xyz789", "payload_type": "trace", "payload": { "...": "..." }, "payload_hash": "sha256:...", "signature": "base64(...)"}Unsigned envelopes are accepted only in warn mode.
Tool authorization (v2.1)
Section titled “Tool authorization (v2.1)”Before executing sensitive tools, adapters must request authorization:
POST /api/governance/tool/authorizeThe response contains a short-lived JWT token. Adapters must include the token ID in telemetry for verification.
Async approvals + decision tokens (v2.2)
Section titled “Async approvals + decision tokens (v2.2)”When Core returns a pending decision:
- Adapter pauses execution.
- Adapter polls:
GET /api/decisions/:id
- On approval, adapter consumes the decision token once:
POST /api/decisions/:id/consume- header:
X-Decision-Token: <jwt>
Tokens are single-use and bound to (tenant_id, workspace_id, adapter_id, execution_id, decision_id).
All ingest payloads carry these identifiers:
tenant_idworkspace_idexecution_idtrace_idadapter_id
Idempotency
Section titled “Idempotency”Ingest endpoints are idempotent per (execution_id, event_type) to support retries.
OpenAPI
Section titled “OpenAPI”See the canonical spec in the clasper-core repo:
contracts/adapter.openapi.yaml