Orrery Studio Part 3: How the A2A Protocol Works, From Agent Cards to Tasks

The A2A protocol (Agent2Agent) lets one AI agent hand a task to another, even when the two are built in different frameworks by different teams. This part walks through a real A2A call in Orrery...

Status, October 2026: calling remote A2A agents shipped in Orrery 0.10.0, inside the Studio preview. Only read-only remotes can be registered for now; remotes that act on your behalf need a human confirmation step that isn't built yet.

The A2A protocol (Agent2Agent) lets one AI agent hand a task to another, even when the two are built in different frameworks by different teams. This part walks through a real A2A call in Orrery Studio: the Agent Card, the task it creates, and the checks that make calling someone else's agent safe.


What Is an A2A Agent Card?

Every A2A agent publishes a JSON document at a well-known URL, /.well-known/agent-card.json, saying who it is, what it can do, and where to send requests. This is the live card of the Studio's demo writer, fetched from the lab (shortened):

{
  "name": "demo-writer",
  "description": "Drafts release notes from research notes (deterministic, no LLM).",
  "supportedInterfaces": [
    { "url": "https://demo-writer.studio.internal:8443/",
      "protocolBinding": "JSONRPC", "protocolVersion": "1.0" }
  ],
  "capabilities": { "streaming": false, "pushNotifications": false },
  "skills": [
    { "id": "draft", "name": "Draft release notes",
      "description": "Turns research notes into a bulleted release-notes draft." }
  ]
}

Three things matter to a caller:

The writer itself is one file of about 160 lines, on the plain a2a-sdk, with no LLM and no Orrery code. That is the point of A2A: Orrery doesn't need to know how it was built.


A2A Tasks: Work With a Lifecycle

When you send an A2A agent a message, it usually answers with a task; a simple agent may reply with a plain message instead. A task moves through states such as submitted and working, may pause at input-required, and ends completed, failed, canceled or rejected. It carries artifacts, the results. As Orrery sees it, the demo writer answers completed straight away, with one text artifact: its draft.

Orrery turns that into a plain result for the model (values shortened):

{ "status": "success", "task_state": "completed",
  "reply": "# Kafka consumer lag\n\n- Lag is the gap between …",
  "parts": [{ "kind": "text", "size": 412 }] }

Two states get special handling. On input-required, the model is told that a person must answer and that it must not answer for them. On a timeout, it is told the remote may still finish, so it shouldn't blindly call again.


One A2A Call, Step by Step

Sequence of one A2A call in Orrery Studio: the writer node calls the A2A tool, Orrery runs its guards, fetches and checks the agent card against its pin, sends only the request with SendMessage, and screens the task's reply

The node never talks to the remote directly. Orrery's GuardedRemoteA2aTool sits in the middle and does four jobs.

1. Pin the card

Orrery fetches the card itself and hashes the parts that decide trust: the interfaces, the security schemes and requirements, and the skills, their descriptions included. Only the card's own name and description, and skill examples, are left out, so those may change freely. The hash is SHA-256 over a canonical form of the JSON (RFC 8785), so reordering keys or adding spaces can't change it.

Orrery also checks that every JSON-RPC URL in the card is HTTPS and on the card's own origin (the same scheme, host and port), or on one the registry lists. Otherwise a card could quietly send your requests somewhere else.

Orrery Studio A2A inspector for the demo-writer agent, showing its draft skill, the pinned card digest and a timeline of outbound and inbound messages with task states

The A2A inspector with sample data: each call's states, and the card's pinned digest.

2. Send only the request

Comparison: a remote wired in as an agent node receives the whole session including earlier tool results, while Orrery's remote-as-a-tool sends only the request string the model wrote and screens the reply

Google ADK has a RemoteA2aAgent. Used as an agent, it forwards the whole session: the user's question, other agents' answers, and every earlier tool result. If one of those results held a secret, the remote now has it. Its reply also arrives as an agent event, which no tool-level guard ever sees.

So in Orrery a remote is always a tool. Behind the scenes, ADK's agent runs in a fresh, empty session, and the function that builds what it sends returns exactly one thing: the request string the model wrote. A test plants a marker string (a canary) in an earlier tool result and checks it never reaches the remote. Another test fails the build if any code uses RemoteA2aAgent another way.

3. Treat the reply as untrusted data

The reply is a tool result, so it passes the safety screen (looking for injected instructions), PII redaction (emails included), and a cap of 16,000 characters. Only text comes back. Files or other part types are reported by kind and size, never relayed.

4. Stay on a short leash


Limits Today

The full design is ADR-008, and the protocol itself is documented at a2a-protocol.org. Next: Part 4, MCP server security.

Read on Tirraflow