Expose AgentSystems via A2A
This guide walks through exposing selected Orloj AgentSystems to external A2A clients.
Prerequisites
- Orloj server (
orlojd) running with--embedded-worker orlojctlavailable- At least one agent and model endpoint configured
If you have not set up Orloj yet, follow the Install and Quickstart guides first.
Step 1: Expose an AgentSystem
Add spec.a2a.enabled: true to each AgentSystem that should be reachable through A2A. Systems without this block remain internal.
apiVersion: orloj.dev/v1
kind: AgentSystem
metadata:
name: research-system
spec:
agents:
- research-agent
a2a:
enabled: trueSet the public base URL so generated Agent Cards point at the externally reachable host:
orlojd --a2a-public-base-url https://orloj.example.comStep 2: Verify the Default Agent Card
If exactly one AgentSystem is A2A-enabled, the root well-known URL returns its card:
curl -s http://localhost:8080/.well-known/agent-card.json | jq .Expected output:
{
"name": "research-system",
"description": "Research assistant with web search capabilities",
"url": "https://orloj.example.com/v1/agent-systems/research-system/a2a",
"protocolVersion": "0.2",
"capabilities": {
"streaming": true,
"pushNotifications": false,
"stateTransitionHistory": true
},
"skills": [
{
"id": "web-search",
"name": "web_search",
"description": "Search the web for information",
"tags": ["search", "web"]
}
],
"authentication": {
"schemes": ["bearer"]
}
}For a specific AgentSystem:
curl -s http://localhost:8080/v1/agent-systems/research-system/.well-known/agent-card.json | jq .Step 3: Test Inbound Task Creation
Send an A2A tasks/send request to create a task:
curl -s -X POST http://localhost:8080/v1/agent-systems/research-system/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ORLOJ_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": "req-1",
"method": "tasks/send",
"params": {
"id": "task-001",
"message": {
"role": "user",
"parts": [{"type": "text", "text": "Summarize recent AI news"}]
}
}
}' | jq .The response contains an A2A task with a status:
{
"jsonrpc": "2.0",
"id": "req-1",
"result": {
"id": "a2a-task-abc123",
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [{"type": "text", "text": "Here is a summary of recent AI news..."}]
}
},
"artifacts": [
{
"name": "summary",
"parts": [{"type": "text", "text": "..."}]
}
]
}
}Step 4: Multiple Systems
For deployments with multiple exposed systems, use per-system cards and endpoints:
# Discovery
curl -s http://localhost:8080/v1/agent-systems/research-system/.well-known/agent-card.json
# Task submission
curl -s -X POST http://localhost:8080/v1/agent-systems/research-system/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ORLOJ_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": "req-2",
"method": "tasks/send",
"params": {
"id": "task-002",
"message": {
"role": "user",
"parts": [{"type": "text", "text": "Find papers on transformer architecture"}]
}
}
}'The per-system card's url field points to https://orloj.example.com/v1/agent-systems/research-system/a2a, so A2A clients that discover the card know where to send requests.
Step 5: Streaming Subscribe
For long-running tasks, use tasks/sendSubscribe to receive streaming updates via SSE:
curl -s -N -X POST http://localhost:8080/v1/agent-systems/research-system/a2a \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ORLOJ_TOKEN" \
-d '{
"jsonrpc": "2.0",
"id": "req-3",
"method": "tasks/sendSubscribe",
"params": {
"id": "task-003",
"message": {
"role": "user",
"parts": [{"type": "text", "text": "Write a detailed report on quantum computing"}]
}
}
}'The server responds with a stream of SSE events containing status updates and artifact chunks as the agent works.
How It Works
When an A2A request arrives:
- The JSON-RPC method is parsed and validated.
- The target AgentSystem is resolved from the URL path or request params (shared endpoint).
- An Orloj Task is created with A2A metadata labels.
- The AgentSystem executes the task using the normal Orloj pipeline.
- Task status transitions are mapped to A2A states and returned in the response.
- For
tasks/sendSubscribe, the task's trace/watch SSE stream is converted to A2A streaming events.
Per-System Auth Policy
By default, A2A invoke requires a bearer token when instance-wide auth is configured. To allow unauthenticated callers to invoke a specific system, set spec.a2a.auth: public:
apiVersion: orloj.dev/v1
kind: AgentSystem
metadata:
name: public-assistant
spec:
agents:
- assistant-agent
a2a:
enabled: true
auth: publicThis is useful when you want admin tokens for the control plane (/v1/agents, /v1/tools, etc.) but need a public-facing A2A endpoint for external clients. Invalid tokens are still rejected — only missing tokens are permitted on public systems.
Public systems' Agent Cards omit authentication.schemes, so A2A clients that discover the card know not to send tokens. The A2A registry (GET /v1/a2a/agents) shows public systems to unauthenticated callers.
To require auth (the default), omit auth or set spec.a2a.auth: bearer.
Agent Card Customization
Agent Cards are auto-generated from the AgentSystem and its agents, but you can influence the output with annotations:
apiVersion: orloj.dev/v1
kind: AgentSystem
metadata:
name: research-system
annotations:
orloj.dev/description: "AI research assistant specializing in academic papers"
spec:
agents:
- research-agent
a2a:
enabled: trueThe orloj.dev/description annotation overrides the description in the generated card.
Next Steps
- Use Remote A2A Agents -- call external A2A agents from your Orloj pipelines
- A2A Interoperability -- concept deep-dive
- A2A JSON-RPC Reference -- per-method documentation
- Agent Card Reference -- full card schema