Secure AI Agent traffic with an AI Auth Strategy and Kong Identity

TL;DR

Create an openid-connect AI Auth Strategy that points at a Kong Identity auth server’s issuer URL and client credentials, then reference it in an AI Agent entity’s access.auth_strategies array. Requests without a valid bearer token are rejected with a 401. Authenticated requests are proxied to the upstream A2A agent.

Prerequisites

This page is part of the Secure AI Agent A2A traffic with Kong Identity series.

Complete the previous page, Set up a Kong Identity auth server for AI Agent authentication before completing this page.

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.

This how-to continues from Set up a Kong Identity auth server for AI Agent authentication. Complete that how-to first, you need its $ISSUER_URL, $CLIENT_ID, and $CLIENT_SECRET to create the AI Auth Strategy.

Create an AI Auth Strategy and AI Agent

Create an openid-connect AI Auth Strategy that uses Kong Identity as the issuer, and an AI Agent that references it through access.auth_strategies.

kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" << 'EOF'
ai_gateway_auth_strategies:
  - ref: identity-oidc
    ai_gateway: !lookup {id: !env AI_GATEWAY_ID}
    display_name: "Identity OIDC"
    name: identity-oidc
    type: openid-connect
    config:
      issuer: !env ISSUER_URL
      client_id:
        - !env CLIENT_ID
      client_secret:
        - !secret {source: !env CLIENT_SECRET}
      auth_methods:
        - bearer
      scopes:
        - a2a-access
      cache_tokens_salt: identity-oidc-cache-salt
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
    access:
      auth_strategies:
        - !ref identity-oidc#name
    config:
      url: http://host.docker.internal:10000
      route:
        paths:
          - /a2a
        methods:
          - GET
          - POST
        protocols:
          - http
          - https
        strip_path: true
      logging:
        payloads: false
        statistics: true
      max_request_body_size: 8388608
EOF

All requests to the /a2a route now require a valid bearer token from Kong Identity.

Validate unauthenticated requests are rejected

Send an A2A request without a token:

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?"
             }
           ]
         }
       }
     }'

The request fails with 401 Unauthorized.

Validate authenticated requests succeed

Generate a token for the client and export it:

ACCESS_TOKEN=$(curl -X POST "$ISSUER_URL/oauth/token" \
     --no-progress-meter --fail-with-body  \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=client_credentials" \
     -d "client_id=$CLIENT_ID" \
     -d "client_secret=$CLIENT_SECRET" \
     -d "scope=a2a-access"  | jq -r ".access_token"
)

Send the A2A request with the token:

curl -X POST "$KONNECT_PROXY_URL/a2a" \
     --no-progress-meter --fail-with-body  \
     -H "Content-Type: application/json"\
     -H "Authorization: Bearer $ACCESS_TOKEN" \
     --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?"
             }
           ]
         }
       }
     }'

AI Gateway validates the bearer token against Kong Identity, then proxies the request to the upstream A2A agent. A successful response (status 200) contains the agent’s reply.

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
curl -X DELETE "https://us.api.konghq.com/v1/auth-servers/$AUTH_SERVER_ID?force=true" \
     --no-progress-meter --fail-with-body  \
     -H "Authorization: Bearer $KONNECT_TOKEN"\
     -H "Content-Type: application/json"

FAQs

No. The AI Agent entity handles A2A protocol detection, agent-card rewriting, and observability. The AI Auth Strategy runs independently in the access phase, before any A2A-specific processing.

Yes. The openid-connect AI Auth Strategy type works with any OIDC-compliant identity provider (Okta, Keycloak, Auth0, Azure AD, and others). Replace issuer, client_id, and client_secret with values from your provider.

Yes. access.acls on the AI Agent restricts which AI Consumers or AI Consumer Groups can reach it. The AI Auth Strategy authenticates the caller first, then ACLs decide whether that identity is allowed through.

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!