Skip to main content
Hexr implements Google’s Agent-to-Agent (A2A) protocol with SPIFFE identity extensions, so agents can securely discover and communicate with each other without manual service discovery, API keys, or shared secrets. Every message is encrypted over mTLS, every sender’s identity is verified via its SPIFFE certificate, and every exchange is authorized by OPA policy and traced with OpenTelemetry. This guide shows you how to enable A2A communication and implement the two most common patterns: fan-out and pipeline.

What you can build with A2A

  • Discover other agents in your namespace via Agent Cards
  • Delegate tasks to specialized agents
  • Fan out work to multiple agents in parallel
  • Pipeline sequential processing across a chain of agents

Steps

1

Enable A2A on your coordinator agent

Add a2a=True to the @hexr_agent decorator. This provisions the A2A sidecar and registers an Agent Card so other agents can discover yours:
coordinator.py
from hexr import hexr_agent
from hexr.a2a import A2AClient

@hexr_agent(name="coordinator", tenant="acme-corp", a2a=True)
def main():
    a2a = A2AClient()

    # Discover agents in the same namespace
    agents = a2a.discover()
    for agent in agents:
        print(f"Found: {agent.name} - {agent.description}")

    # Send a task to another agent
    task = a2a.send(
        agent="research-analyst",
        message="Research the latest AI agent frameworks",
    )

    # Get the result
    result = a2a.get_task(task.id)
    print(result.output)
2

Choose a communication pattern

Pick the pattern that fits your workflow:
# Fan-out: send tasks to multiple agents in parallel
@hexr_agent(name="coordinator", tenant="acme-corp", a2a=True)
def main():
    a2a = A2AClient()

    topics = ["quantum computing", "robotics", "biotech"]
    tasks = []

    for topic in topics:
        task = a2a.send(
            agent="research-analyst",
            message=f"Research {topic} trends for 2026",
        )
        tasks.append(task)

    # Collect results
    results = [a2a.get_task(t.id) for t in tasks]

    # Synthesize
    from hexr import hexr_llm
    synthesis = hexr_llm(
        provider="openai",
        model="gpt-4o",
        prompt=f"Synthesize these research results: {results}",
    )
    print(synthesis)
3

Build and deploy all agents

Build and deploy each agent that participates in A2A communication. Agents discover each other by name within the same tenant namespace:
hexr build coordinator.py --tenant acme-corp
hexr push && hexr deploy
Repeat for each downstream agent (research-analyst, writer, editor, etc.).

How A2A security works

All A2A communication is mTLS encrypted, identity verified, OPA authorized, and fully traced.
1

Agent A sends a task over mTLS

The coordinator sends a task to the researcher through the Envoy proxy, authenticated with its SPIFFE identity.
2

OPA authorizes the request

Envoy checks with OPA: “Can coordinator communicate with researcher?” OPA returns ALLOW based on your policy.
3

Task delivered over mTLS

Envoy delivers the task to the researcher over mTLS. The researcher processes it and returns the result.
A2A request flow
Agent A (coordinator) → Envoy (mTLS) → OPA (authorize) → Agent B (researcher) → Result → A
Security propertyMechanism
EncryptionmTLS using SPIFFE SVIDs
Identity verificationEach agent’s SPIFFE ID is validated on every message
AuthorizationOPA policies control which agents can communicate
Audit trailEvery message is traced via OpenTelemetry
Agents must be in the same tenant namespace to discover each other via a2a.discover(). Cross-tenant communication requires explicit OPA policy configuration.

Next steps

Multi-framework agents

Use CrewAI or AutoGen as the implementation for individual A2A agents.

LLM observability

Trace A2A task delegation alongside LLM calls in a unified view.

Multi-cloud tools

Grant each A2A agent role-specific cloud permissions.

SDK reference

Full reference for A2AClient, a2a.send(), and a2a.discover().