Set up A2A federation between tenants
The A2A federation model explains what federation is; this guide is the working order of operations for standing up a federation edge between two tenants — the peer registration, the handshake that authenticates cross-tenant task traffic, the accept/reject policy on inbound calls, and the audit trail you revoke through when the edge ends.What a federated request looks like
Orbit speaks the A2A protocol v1.0.0, so a federated edge is not tenant-to-tenant only — your agent can task any A2A-conformant peer, and an A2A client you let in can task your agent. When both ends are Orbit tenants, both directions share one setup shape. A federated request is one prompt handed to a third-party agent: the requesting tenant persists an outbound envelope, signs it, forwards it to a registered peer URL, and polls the returned task id until the peer answers. Context beyond the prompt does not travel — the peer receives the envelope message only.Register a peer endpoint
A peer is registered because someone hands you their AgentCard URL. On Orbit the agent owner copies it from Agents → → A2A → Copy share URL; that works only after the agent’s discovery mode ispublic (or tenant,
if you share over an authenticated channel). See
the discovery-mode table.
Register the URL so your agent knows the peer exists:
signatures[] block (the A2A Signed Agent Card extension) so the peer’s
identity is verified without a shared secret. The URL must be a public FQDN
over HTTPS — localhost, private IP tiers, and link-local hosts are refused
at registration.
Two Orbit tenants federate by each registering the other’s AgentCard URL —
one call on each side, and the edge is symmetric.
Authenticate the handshake
Every task endpoint — inbound and outbound — requires the HMAC-signed header. AgentCard signatures authenticate the card, not the call.${ts}.${raw_body} exactly as sent, within a ±60-second replay
window. Share the per-org A2A secret (DEVOTEL_A2A_HMAC_SECRET; it falls
back to DEVOTEL_API_SECRET_KEY on fresh deployments) with the peer over a
side channel — never in the request itself. If either side rotates the
key, re-share before traffic resumes, or every task retries the signature
gate (see
Troubleshooting: A2A federation).
Send a federated task (outbound)
With a peer in the registry, delegate a task:GET …/a2a/tasks/{taskId} (sign over ${ts}., empty body) until the peer
answers.
What forwards: the skill name and the text parts you include — nothing
more. Any tenant, conversation, or contact identifiers you want the peer to
act on must be explicit payload fields on the message itself.
What does not forward: your conversation history, contact profile
fields, memory entries, or metadata of any kind. The receiving agent gets
the prompt and runs it against whatever its own tenant owns.
Accept or reject inbound calls
Inbound hits your agent’s task endpoints with a valid signature, only when a signing key is registered — the one signed-envelope boundary is fail-open until the first key is provisioned; after that, every unsigned or mismatched envelope returns a fixed-operator-safe401. The policy lever
you own is per-agent: to expose an agent to peers at all, its discovery
mode must be public (or tenant for share-URL-on-a-side-channel). An
agent with discovery disabled accepts tasks only from callers who already
know its URL — even so, the endpoint never announces “agent exists” to an
unauthenticated probe: the public card route answers a flat 404.
To reject a peer by policy rather than by signature: nothing rejects
inbound on a per-peer basis beyond the shared-secret gate. Revoke the peer
from the registry (next section) and rotate the HMAC key — that severs
their ability to sign. The fail-open boundary is documented on the
concept page; do not ask a peer to send
unsigned once a key exists.
Audit the registry and revoke a peer
Peer rows and every inbound/outbound task sit on per-tenant tables (agent_a2a_peers, agent_a2a_tasks), so a federation edge is auditable
end-to-end from your side alone.
- List every edge:
GET /api/v1/agents/{agentId}/a2a/peers— the full per-agent peer registry. - Revoke an edge:
DELETE /api/v1/agents/{agentId}/a2a/peers/{peerId}— removes the row; the peer’s URL stops resolving and outbound tasks to it error at the peer step. - Trace the round-trip:
GET /api/v1/agents/{agentId}/a2a/taskslists both directions with status and latency — the audit trail that survives a revocation.
agent.a2a.peer_added / agent.a2a.peer_removed fire on
each registry mutation, so a peer add or revoke is attributable to an
operator.
Worked example: returns-agent ⇄ order-status-agent
A customer-success org runs areturns-agent; its supplier runs an
order-status-agent on their own Orbit tenant.
- The supplier flips
order-status-agentdiscovery topublicand hands over its share URL. - Customer success registers it:
POST /agents/returns-agent/a2a/peerswith the supplier URL. The returns-agent now sees the supplier’sorder_statusskill. - A return landed in the success inbox — the operator delegates:
- The supplier’s agent answers on its own data; the success tenant polls
the returned task id and gets a
completedenvelope with the status text. Neither side saw the other’s contact records.
DELETE the peer row and rotate the shared HMAC
key.
Errors
The four failure classes — discovery refused, signature rejection, peer errors, registration refused on the URL — map one-to-one to gates you hit above. When one fires, work through Troubleshooting: A2A federation before re-tasking.See also
- A2A federation → — endpoint-by-endpoint reference: discovery modes, the two transports, peer registry.
- A2A federation model → — the concept page this guide assumes.
- Troubleshooting: A2A federation → — the failure taxonomy this guide’s gates can land in.