Skip to main content
The A2A protocol enables agent communication across system boundaries — between services, organizations, or deployment environments. It builds on internal messaging by adding authentication, authorization, and external transport.

Architecture

Three integration layers

LayerWhat it doesWhen you need it
Internal ProtocolTyped envelopes with idempotencyAlways (agents in the same system)
Auth ProviderToken validation, caller identityWhen agents are in different services
External AdapterHTTP/gRPC transport, discoveryWhen agents are in different systems

Request flow

1

Client builds invocation request

from afk.agents.contracts import AgentInvocationRequest

request = AgentInvocationRequest(
    target_agent="analyzer",
    user_message="Analyze this dataset",
    context={"source": "system-a"},
    idempotency_key="analysis-42",
)
2

Auth provider validates

The server validates the auth token, extracts the caller identity, and checks authorization rules.
3

Server runs the agent

The target agent executes locally with a Runner, using the invocation request as input.
4

Response returned

response = await client.invoke(request)
print(response.final_text)   # Agent's response
print(response.state)        # "completed"
print(response.run_id)       # For tracing

Invocation contracts

class AgentInvocationRequest(BaseModel):
    target_agent: str  # Which agent to invoke
    user_message: str  # The input message
    context: dict = {}  # Additional context
    idempotency_key: str  # Deduplication key
    timeout_s: float = 60.0  # Max wait time
    thread_id: str | None = None  # For multi-turn

Hosting an A2A service

Expose your agents as an A2A-accessible service:
from afk.agents.a2a import A2AServiceHost
from afk.agents.a2a.auth import APIKeyA2AAuthProvider
from afk.agents import Agent
from afk.core import Runner

# Define the agent
analyzer = Agent(name="analyzer", model="gpt-5.2-mini", instructions="Analyze data.")

# Create auth provider
auth = APIKeyA2AAuthProvider(
    keys={"system-a": "token-abc", "system-c": "token-xyz"},
    server_secret="hmac-secret-for-key-hashing",
)

# Start the server
server = A2AServiceHost(
    agents={"analyzer": analyzer},
    runner_factory=lambda: Runner(),
    auth_provider=auth,
    host="0.0.0.0",
    port=8080,
)
await server.start()

Authentication providers

AFK ships with three auth providers:
Permits all requests without authentication. Never use in production.
from afk.agents.a2a.auth import AllowAllA2AAuthProvider

auth = AllowAllA2AAuthProvider()

Google A2A adapter

For interoperability with Google’s A2A protocol, use the Google adapter:
from afk.agents.a2a.google_adapter import GoogleA2AAdapter

adapter = GoogleA2AAdapter(
    protocol=internal_protocol,
    auth_provider=auth,
)
The adapter normalizes Google A2A envelope formats to AFK’s internal protocol types.

Security considerations

ConcernMechanism
AuthenticationToken-based (API keys, JWT, OAuth)
AuthorizationPer-agent access control (which callers can invoke which agents)
Idempotencyidempotency_key prevents duplicate processing on retries
Rate limitingConfigure per-caller request limits
Input validationAll requests validated against AgentInvocationRequest schema
Cost isolationEach invocation has its own FailSafeConfig budget
Always authenticate A2A endpoints. An unauthenticated A2A server allows anyone to invoke your agents, consuming your LLM API credits.

Next steps