Checkfu currently serves A2A v1.0 over JSON-RPC 2.0 and SSE. Send
A2A-Version: 1.0 on every RPC request. The protocol treats an absent header
as v0.3, which Checkfu deliberately rejects with VersionNotSupportedError.Find the endpoint
Each active AgentInstallation and SurfaceScope pair has two URLs:ETag,
the exact JSON-RPC endpoint, supported text modes, streaming capability, and a
projection of the installed release’s active skills. An archived agent or an
inactive or mismatched installation/surface placement returns 404 instead of
publishing a stale card.
Issue an A2A Principal credential
An A2A caller authenticates as one existing person Principal. Use an identity-admin API key to issue an audience-bound bearer; thesecret appears only in this
response:
a2a bearer is
rejected by /v1/mcp, and an api_mcp bearer is rejected by the A2A endpoint.
Every request also rechecks the Principal, credential, installation placement,
Session admission, PermissionAssignments, and ActionPolicy. Give the Principal invoke, steer, and
observe on the installed agent and SurfaceScope required for the operations it
will use.
Task and occurrence identity is scoped to that Principal, AgentInstallation,
and SurfaceScope. A provider-native conversation or another Principal using the
same opaque context or message ID neither replays nor becomes visible as an A2A
task.
Send and observe a task
Call the card’s JSON-RPC URL with the issued bearer:SendMessage blocks until the task reaches a terminal or interrupted state by
default, as A2A v1 requires. Set returnImmediately: true to receive the
submitted or working Task and poll it with GetTask; use
SendStreamingMessage or SubscribeToTask for ordered SSE updates. Reusing the
same messageId is idempotent and returns the same Session-backed task.
The endpoint supports SendMessage, SendStreamingMessage, GetTask,
ListTasks, CancelTask, and SubscribeToTask. Only text/plain input and
output are admitted in this version. Push notifications, protocol extensions,
non-text message parts, and ZDR Sessions are rejected rather than accepted with
weaker custody or incomplete behavior.
This interface is routed by its installation-and-surface URL, so omit the A2A
tenant request field (the Agent Card does not advertise one). Message
extension URIs and referenceTaskIds are also rejected in this version rather
than silently ignored; a terminal task cannot accept another message or a new
subscription.
Consume an external A2A agent
An external A2A agent is a governed ToolSource, not a coordinator-roster member. An operator first reviews a ProviderPackage whose egress ceiling admits exactly the public Agent Card GET and JSON-RPC POST, then registers the card URL and its reviewed ES256 public JWK:POST /v1/tool-sources/{id}/source-revisions and a required
Idempotency-Key, not an ordinary sync. For a source already backing
Connections, first publish a higher host-configured ProviderPackage whose A2A
source contains both the old and new keys and declares every live predecessor
version compatible. Then submit the candidate source, exact package identity,
and the complete sorted list of dependent Connection IDs with their current
versions. Checkfu requires a monotonically higher compatible package for each
dependent Connection, verifies discovery before it publishes the source, and
durably resumes the version-fenced Connection migration after interruption. An
unused source still has to match the exact current host package, but has no
earlier Connection package binding to migrate. Once the peer signs
with the new key, repeat the operation with another higher host-configured package
that removes the old key. Restoring an old key is the same forward-only process
with a still-higher host-configured package. Rotation and rollback perform the bounded,
credential-free card discovery GET, but never read a credential or call an
executable provider endpoint. Audit records distinguish a source
revision (or failed revision) from an ordinary sync and record each dependent
Connection package migration separately.
Attach the discovered Tool and its Connection to an Agent as usual. At runtime,
the CapabilityGateway rechecks PermissionAssignments, ActionPolicy, ActionApproval, the frozen ProviderPackage,
the live Connection revision and scopes, the signed binding, and exact egress
before custody injects the peer credential. An OAuth2 selection requires a
custody-managed OAuth ProviderPackage and scopes within both its reviewed
ceiling and the Connection. Checkfu never follows a card-declared authorization,
token, refresh, or metadata URL: the already-qualified Connection custody
adapter obtains, refreshes, revokes, and injects the token only at its outbound
transport edge. The token never appears on the Tool, task custody, event log,
sandbox boundary, or result receipt.
An mTLS selection requires a custody-managed mTLS ProviderPackage and a
deployment-reviewed Worker certificate binding. The integration configuration
names only the binding, a generation marker, certificate expiry, and the exact
allowed peer hostnames; the certificate and private key are uploaded through
the Worker platform and are not JSON configuration. Hosted setup activates the
Connection without a credential form. Certificate rotation keeps the
Connection ID, but the operator must advance the generation/expiry metadata and
use the ordinary reconnect link so the sealed custody record advances before
provider traffic resumes. Checkfu checks the configured hostname set and the
Worker fetcher performs ordinary server-certificate hostname verification.
If the signed Agent Card declares streaming and the frozen Connection custody
adapter supports it, Checkfu sends one SendStreamingMessage. It attaches the
first active task before accepting ordered artifact or status updates, requires
the exact JSON-RPC, task, and context identity throughout, and closes the SSE
body at terminal state. Resume uses SubscribeToTask, never another send. A
disconnect after durable task identity falls back to the same fenced GetTask
observer; a disconnect before identity is indeterminate. If either the card or
custody adapter lacks streaming support, Checkfu sends one SendMessage and
uses GetTask as the baseline observer. In every mode, the final task becomes
one CapabilityGateway ToolInvocation result and one exec.tool_invocation event.
Replay the exact pending call after an observation failure: it retains the
original ActionApproval and resumes only the matching durable child. A lost or
invalid send response before task attachment is never replayed.
Polling starts immediately, then uses deterministic task-specific exponential
backoff with bounded jitter. A syntactically valid HTTP Retry-After on a
temporary 429 or 503 response may extend the local delay; other statuses,
malformed values, and non-HTTP date formats are ignored. Peer guidance and
local backoff are both capped, the immutable hard deadline always wins, and a
failure releases the fenced observer while retaining the exact next due time
for resume. A host-lifetime ceiling also bounds concurrent polls for one
reviewed Agent Card coordinate without holding a task lease while queued.
Operational counters and poll spans contain only closed outcome, schedule,
attempt-bucket, and fresh/resume labels—never peer coordinates, task IDs,
request IDs, provider content, or credentials.
SSE parsing is strict and bounded: the response must negotiate A2A v1 and
text/event-stream, the total stream and each event have fixed byte ceilings,
artifact chunks must be ordered, and task/context identity cannot change. A
caller cancellation or hard deadline interrupts provider reading, releases the
owned response body and fenced custody lease, and leaves no provider content in
durable task state.
Every attached task has an immutable hard deadline. A bounded scheduled sweep
finds due structural custody without calling the peer, expires the child, and
asks the CapabilityGateway to settle that exact ToolInvocation and Session execution
as indeterminate with a terminal audit record. The child records reconciliation
completion only after those authorities accept it, so a process loss resumes
the same settlement on a later bounded sweep without another provider request
or a second durable result. This expiry is Checkfu’s local indeterminate
settlement, not evidence that the remote peer canceled or stopped its task.
Outbound consume supports A2A v1.0 JSON-RPC with text/plain messages;
Bearer, reviewed OAuth2 authorization-code, or reviewed mTLS card
authentication; bounded GetTask polling; and signed-card-gated SSE through
SendStreamingMessage and SubscribeToTask. When a signed card instead
declares push notifications, Checkfu registers a task-scoped HTTPS callback
with a generated Bearer value, stores only its digest, and accepts bounded
application/a2a+json notifications as wake signals. The callback body never
settles the call or enters durable custody: Checkfu re-reads the exact task with
authenticated GetTask, and polling remains the missed-notification fallback.
API-key, OIDC, non-authorization-code OAuth2, and required protocol extensions
remain rejected rather than silently degraded.