Route A2A agent traffic through AI Gateway

TL;DR

When agents need to communicate with other agents, route the traffic through AI Gateway to apply authentication, rate limiting, observability, and content policies at the gateway layer.

To route A2A agent traffic, create an AI Agent entity that exposes your upstream agent at a gateway endpoint and attach policies for logging, security, and traffic control. The gateway proxies A2A JSON-RPC requests, discovers agent capabilities through Agent Cards, and exports metrics and payloads as observability spans.

This tutorial shows you how to set up an AI Agent entity in Konnect using the Konnect API and how to test A2A traffic flowing through the AI Gateway.

Prerequisites

This is a Konnect tutorial and requires a Konnect personal access token.

  1. Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.

  2. Export your token to an environment variable:

    export KONNECT_TOKEN='YOUR_KONNECT_PAT'
  3. Run the AI Gateway quickstart script to automatically provision a control plane and data plane in Kong Konnect, and configure your environment:

    curl -Ls https://get.konghq.com/ai | bash -s -- -k $KONNECT_TOKEN 

This sets up a AI Gateway control plane named ai-quickstart, provisions a local data plane, and prints out the following environment variables export:

export AI_GATEWAY_ID=your-gateway-id
export KONNECT_TOKEN=$KONNECT_TOKEN
export KONNECT_CONTROL_PLANE_NAME=ai-quickstart
export KONNECT_CONTROL_PLANE_URL=https://us.api.konghq.com
export KONNECT_PROXY_URL='http://localhost:8000'

Copy and paste these into your terminal to configure your session.

This tutorial uses kongctl to manage Konnect resources programmatically. We recommend keeping kongctl up to date with the latest version (1.13.0).

  1. Install kongctl from developer.konghq.com/kongctl.
  2. Verify the installation:

    kongctl version
  1. Create an OpenAI account.
  2. Get an API key.
  3. Export your key:
    export OPENAI_API_KEY='YOUR_OPENAI_API_KEY'

You need a running A2A-compliant agent. This guide uses a sample KongAir travel agent that uses OpenAI and LangGraph to answer flight route queries.

Create a docker-compose.yaml file:

cat <<'EOF' > docker-compose.yaml
services:
  a2a-agent:
    container_name: a2a-kongair-agent
    image: ghcr.io/tomek-labuk/a2a-kongair-openai-agent:1.0.0
    environment:
      - OPENAI_API_KEY=${OPENAI_API_KEY}
      - OPENAI_MODEL=gpt-5-mini
      - KONGAIR_BASE_URL=https://api.kong-air.com
      - PUBLIC_AGENT_URL=http://localhost:10000
    ports:
      - "10000:10000"
EOF

Start the agent:

docker compose up -d --wait

The agent listens on port 10000 and uses the A2A JSON-RPC protocol to handle flight route queries. In this guide, the gateway service points to host.docker.internal:10000 instead of the container name because Kong Gateway runs in its own container with a separate DNS resolver.

Create an AI Agent entity

Create an AI Agent entity that proxies A2A traffic to your upstream agent.

kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" << 'EOF'
ai_gateway_agents:
  - ref: kongair-flight-booking-agent
    ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
    display_name: "Kong Air Flight Booking Agent"
    type: a2a
    enabled: true
    config:
      url: http://host.docker.internal:10000
      route:
        paths:
          - /a2a
        methods:
          - GET
          - POST
        protocols:
          - http
          - https
        strip_path: true
      logging:
        payloads: true
        statistics: true
        max_payload_size: 1048576
      max_request_body_size: 8388608
EOF

The ai_gateway_agents entry references your existing AI Gateway by its name (ai-quickstart, as set up by the quickstart script), so kongctl adds the agent to that gateway instead of creating a new one. Each nested agent still declares its own ai_gateway field, pointing at the gateway’s ID, to link it to the parent.

The agent is now accessible at the /a2a route and proxies A2A JSON-RPC requests to the upstream agent running at http://host.docker.internal:10000.

Retrieve the Agent Card

A2A agents expose their capabilities through an Agent Card at the /.well-known/agent-card.json endpoint.

Retrieve it through the gateway:

curl "$KONNECT_PROXY_URL/a2a/.well-known/agent-card.json" \
     --no-progress-meter --fail-with-body 

The response shows the agent’s capabilities, skills, and supported protocols:

{
  "name": "KongAir OpenAI Agent",
  "version": "1.0.0",
  "description": "An A2A-compatible agent powered by LangGraph and OpenAI that queries KongAir APIs for flights, routes, bookings, and loyalty info.",
  "protocolVersion": "0.3.0",
  "capabilities": {
    "pushNotifications": false,
    "streaming": false
  },
  "defaultInputModes": ["text", "text/plain"],
  "defaultOutputModes": ["text", "text/plain"],
  "preferredTransport": "JSONRPC",
  "url": "http://a2a-agent:10000/",
  "skills": [
    {
      "id": "search_routes",
      "name": "Search KongAir routes",
      "description": "Find KongAir routes between airports.",
      "examples": [
        "Show me routes from SFO to JFK",
        "Find flights from LHR to SFO"
      ],
      "tags": ["kongair", "flights", "travel", "routes"]
    }
  ]
}

Send an A2A request

Send a message/send JSON-RPC request to test the agent. The upstream agent uses the OpenAI API key from the prerequisites to answer the query, so you don’t need to pass the key in the request.

curl -X POST "$KONNECT_PROXY_URL/a2a/" \
     --no-progress-meter --fail-with-body  \
     -H "Content-Type: application/json" \
     --json '{
       "jsonrpc": "2.0",
       "id": "1",
       "method": "message/send",
       "params": {
         "message": {
           "kind": "message",
           "messageId": "msg-001",
           "role": "user",
           "parts": [
             {
               "kind": "text",
               "text": "What flights are available on route KA-123?"
             }
           ]
         }
       }
     }'

A successful response (status 200) contains the agent’s reply:

{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "message": {
      "kind": "message",
      "messageId": "msg-002",
      "role": "assistant",
      "parts": [
        {
          "kind": "text",
          "text": "Route KA-123 has 5 available flights today..."
        }
      ]
    }
  }
}

Cleanup

docker compose down
docker rm -f a2a-kongair-agent

To clean up all AI Gateway resources created in this guide, run:

curl -Ls https://get.konghq.com/ai | bash -s -- -d

FAQs

The Agent-to-Agent (A2A) protocol is an open standard originally developed by Google that defines how AI agents communicate with each other. It uses JSON-RPC over HTTP and supports capability discovery through Agent Cards, task lifecycle management, multi-turn conversations, and streaming responses. See the A2A protocol documentation for the full specification.

MCP (Model Context Protocol) standardizes how agents connect to tools, APIs, and data sources. A2A standardizes how agents communicate with other agents. They are complementary. Use MCP for agent-to-tool communication and A2A for agent-to-agent communication.

Yes. Reference an AI Auth Strategy using the openid-connect or key-auth auth strategy in the agent’s access.auth_strategies array. Authentication isn’t attached through the agent’s policies array. The AI Agent entity handles A2A protocol concerns independently of authentication.

Set config.logging.payloads to true and config.logging.statistics to true in the agent config to log A2A request and response bodies along with metrics.

Help us make these docs great!

Kong Developer docs are open source. If you find these useful and want to make them better, contribute today!