A2A Protocol Guide: Agent-to-Agent Communication
Source: mortalapps.com- A2A is an open-standard communication protocol designed for secure, vendor-neutral interaction between autonomous AI agents.
- It solves the fragmentation of agent ecosystems by providing a standardized framework for discovery, task delegation, and settlement.
- In production, A2A enables cross-platform agent swarms (e.g., AWS to Azure) while maintaining strict security and audit boundaries.
- Implementation results in interoperable agent fleets that can dynamically discover capabilities and negotiate task execution without manual integration code.
- Key caveat: A2A requires robust identity management (DIDs) to prevent unauthorized resource consumption across trust boundaries.
Why This Matters
The current AI landscape is characterized by 'agent silos' where systems built on different frameworks - such as LangGraph, CrewAI, or Semantic Kernel - cannot natively communicate or share tasks. This fragmentation forces engineering teams to build custom, brittle API bridges for every cross-agent interaction, leading to high maintenance costs and limited scalability. The A2A Protocol Guide was developed to provide a universal 'handshake' and 'contract' for agentic systems, drawing inspiration from the success of HTTP for web services and TCP/IP for networking. By standardizing how agents describe their capabilities (Agent Cards), how they request assistance (Task Delegation), and how they stream results, A2A allows for the emergence of a decentralized agent mesh. If ignored in production, developers face significant vendor lock-in and the 'N-to-N integration problem,' where adding a single new agent requires updates to every existing agent in the fleet. A2A is the preferred choice for enterprise environments where agents must operate across different cloud providers, organizational departments, or security zones. It moves the industry away from hard-coded tool-calling toward dynamic, capability-based discovery. From a production engineering perspective, A2A provides the necessary hooks for observability, cost attribution, and governance that are missing in ad-hoc agent implementations. It ensures that every interaction is signed, authorized, and traceable, which is a non-negotiable requirement for compliance in regulated industries like finance and healthcare. Use A2A when building multi-agent systems that require high degrees of autonomy, cross-vendor interoperability, or formal governance over agent-to-agent interactions.
Core Concepts
The A2A protocol relies on several foundational concepts that define how agents interact as first-class citizens in a network.
1. Agent Cards
An Agent Card is a machine-readable JSON-LD document that serves as an agent's 'resume' or 'manifest.' It defines the agent's identity, capabilities, input/output schemas, and cost structures. Under the A2A v1.0 spec, these cards are often hosted at a well-known URI or registered in a decentralized registry.
2. Decentralized Identifiers (DIDs)
A2A uses W3C DIDs to provide a verifiable, decentralized identity for every agent. This ensures that an agent's identity is not tied to a specific cloud provider or platform, allowing for cross-vendor trust verification without a central authority.
3. Task Delegation Envelopes
Communication in A2A is wrapped in 'Envelopes' that contain metadata for routing, security, and tracing. These envelopes support both synchronous request-response patterns and asynchronous streaming for long-running LLM tasks.
4. Capability Negotiation
Before a task is executed, agents engage in a negotiation phase. This involves checking if the 'Provider' agent has the necessary tools, permissions, and capacity to fulfill the 'Consumer' agent's request. Negotiation includes price discovery and SLA (Service Level Agreement) confirmation.
5. Trust Anchors and Handshakes
A2A interactions begin with a cryptographic handshake. Agents exchange public keys and verify signatures against trusted roots (Trust Anchors) to establish a secure session, preventing man-in-the-middle attacks in the agent mesh.
| Concept | Purpose | Standard Reference |
|---|---|---|
| Agent Card | Discovery & Metadata | A2A-AC-1.0 |
| DID | Identity Verification | W3C DID Core |
| Envelope | Message Transport | JSON-RPC 2.0 / A2A-E |
| Trace Context | Observability | W3C Trace Context |
How It Works
The A2A protocol defines a task-based lifecycle over HTTP + JSON. Every interaction is represented as a Task with a defined set of states.
Phase 1: Task Initiation (tasks/send)
The 'Consumer' (client) agent identifies a capability it needs from a 'Provider' (server) agent. It retrieves the Provider's Agent Card from /.well-known/agent.json to discover capabilities and the agent's URL. The Consumer sends an HTTP POST to the Provider's URL with a JSON-RPC 2.0 payload:
- Method:
tasks/send - Params: A
Taskobject containing a uniqueid, the requestingmessage(withroleandparts), and optional metadata.
Phase 2: Task Processing and Status Polling (tasks/get)
The Provider returns an initial Task response with status.state: "submitted" or "working". For long-running tasks, the Consumer polls for updates using:
- Method:
tasks/get - Params:
{ "id": "<task_id>" }
The task transitions through states: submitted → working → completed (or failed/canceled).
Phase 3: Streaming via Server-Sent Events (tasks/sendSubscribe)
For real-time streaming responses, the Consumer uses:
- Method:
tasks/sendSubscribe
The Provider responds with Content-Type: text/event-stream and pushes TaskStatusUpdateEvent SSE events as the task progresses, until the final completed or failed state.
Phase 4: Task Cancellation (tasks/cancel)
At any time, the Consumer may cancel a running task:
- Method:
tasks/cancel - Params:
{ "id": "<task_id>" }
All interactions use standard HTTP authentication (Bearer tokens, API keys) defined in the Agent Card's authentication field.
Architecture
The A2A architecture is designed as a decentralized peer-to-peer mesh, though it can be implemented in a hub-and-spoke model for enterprise governance. The primary components include:
- Agent Gateway: An edge component that handles the A2A protocol details (signing, encryption, envelope parsing) so the core agent logic remains protocol-agnostic. It acts as the 'Network Interface Card' for the agent.
- Discovery Registry: A service (centralized or distributed) where Agent Cards are published. It supports semantic search, allowing agents to find peers based on capability descriptions rather than just IDs.
- Policy Enforcement Point (PEP): A component within the Gateway that validates incoming requests against organizational rules (e.g., 'Do not talk to agents outside the .corp domain').
- Message Bus / Transport: A2A is transport-agnostic but typically runs over HTTP/2 (for streaming) or HTTP + JSON. The 'Envelope' ensures that the message content is decoupled from the transport layer.
- State Store: Maintains the status of active delegations, session keys, and conversation history to allow for recovery if a connection is dropped.
Execution starts when a Consumer Agent logic triggers a 'Remote Task' call. The Gateway handles the discovery and negotiation. The data flows through the Gateway, which wraps it in A2A Envelopes, signs it, and transmits it to the Provider's Gateway. The Provider's Gateway unwraps, validates, and passes the task to the Provider's core logic. The return path follows the same envelope-wrapping logic, often utilizing Server-Sent Events (SSE) for the streaming phase.
A2A Agent Card Specification
The Agent Card is the foundational document for A2A interoperability. It must follow the JSON-LD format to ensure semantic clarity. A standard A2A v1.0 Agent Card includes the following top-level fields:
| Field | Type | Description |
|---|---|---|
id |
URI (DID) | The unique, verifiable identifier for the agent. |
version |
String | The A2A specification version (e.g., "1.0.0"). |
capabilities |
Array | List of semantic descriptors for what the agent can do. |
schema |
Object | JSON Schema definitions for inputs and outputs. |
pricing |
Object | Token-based or flat-fee cost structures. |
endpoints |
Array | Transport-specific URIs (e.g., https, wss). |
signature |
JWS | A JSON Web Signature proving the card was issued by the DID owner. |
The Task Delegation Lifecycle
Delegation in A2A is more complex than a simple API call because it involves a transfer of agency. When Agent A delegates to Agent B, Agent B may need to perform its own sub-delegations. To manage this, A2A implements a 'Delegation Chain' within the message envelope. Each hop in the chain adds its own signature and trace ID, ensuring that the 'Originator' can be identified even through multiple layers of delegation. This is critical for preventing recursive loop attacks where agents accidentally call each other in an infinite cycle.
Authentication and Authorization via DIDs
A2A moves away from static API keys. Instead, it uses a 'Challenge-Response' mechanism during the handshake.
- The Consumer sends its DID.
- The Provider sends a random nonce.
- The Consumer signs the nonce with its private key and returns it.
- The Provider resolves the Consumer's DID Document to find the public key and verifies the signature.
Authorization is then handled via 'Capability-Based Security.' An Agent Card might specify that certain capabilities require a specific 'Trust Level' or membership in a 'Trust Registry' (e.g., a corporate-approved list of agents).
Streaming and Partial Results
Because AI agent tasks can take seconds or minutes, A2A mandates support for streaming. The protocol uses a 'Chunked Envelope' format. Each chunk contains:
sequence_id: To ensure chunks are processed in order.payload_type: Distinguishes between 'content', 'tool_call', or 'metadata'.is_final: A boolean indicating the end of the stream.
This allows the Consumer agent to begin processing the Provider's output immediately, which is essential for maintaining a responsive user experience in agentic applications.
Governance and the Google (published by Google; see the official A2A GitHub repository for governance details) Model
The A2A protocol is governed by the Google (published by Google; see the official A2A GitHub repository for governance details)'s AI & Data division. This governance model ensures that no single vendor (like OpenAI or Microsoft) controls the standard. The specification is developed through a 'Request for Comments' (RFC) process. Key working groups include:
- The Schema Working Group: Standardizing how 'Travel Agents' or 'Coding Agents' describe their specific domains.
- The Security Working Group: Defining the standards for DID-based handshakes and encrypted transport.
- The Interop Working Group: Running 'Plugfests' where different implementations are tested against each other to ensure compatibility.
Code Example
import json
import time
import uuid
from typing import Dict, Any
import requests # In production, use httpx for async
# Mock function for signing - in production use a library like authlib or jwcrypto
def sign_envelope(payload: Dict[str, Any], private_key: str) -> str:
# This would return a JWS (JSON Web Signature)
return "signed_" + json.dumps(payload)
def create_a2a_task_request(target_agent_url: str, task_input: Dict[str, Any]):
# 1. Define the A2A Envelope
envelope = {
"a2a_version": "1.0.0",
"message_id": str(uuid.uuid4()),
"timestamp": int(time.time()),
"sender_did": "did:web:mortalapps.com:agents:orchestrator",
"type": "task_request",
"payload": {
"task_type": "data_analysis",
"input_data": task_input,
"constraints": {
"max_tokens": 2000,
"timeout_ms": 30000
}
}
}
# 2. Sign the envelope for integrity and non-repudiation
# SECRET_KEY should be loaded from env vars
signature = sign_envelope(envelope, "PRIVATE_KEY_FROM_ENV")
# 3. Send the request to the Provider Agent's A2A endpoint
try:
response = requests.post(
f"{target_agent_url}/a2a/v1/execute",
json={"envelope": envelope, "signature": signature},
headers={"Content-Type": "application/json"},
timeout=35 # Slightly higher than task timeout
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"A2A Communication Error: {e}")
return None
# Example usage
result = create_a2a_task_request(
"https://api.partner-agent.ai",
{"query": "Analyze Q4 revenue trends"}
)
print(result)
{
"a2a_version": "1.0.0",
"message_id": "resp-8823-4412",
"status": "success",
"payload": {
"analysis": "Revenue increased by 12%...",
"usage": {"tokens": 450, "cost_usd": 0.009}
}
}