Migration uses the kongctl convert ai-gateway extension to translate your existing declarative configuration into the AI Gateway 2.x entity model, then applies it with kongctl.
- Install the
kongctl convert ai-gateway extension.
- Export the declarative configuration from your existing Kong Gateway control plane with decK.
- Prepare a
./config directory with the target control plane, auth strategies, Vaults, and per-model ACLs the converter cannot recover from the decK export.
- Run the converter to merge
./config and produce a directory of AI Gateway entity configuration files.
- Validate that the output includes all of your AI Models, AI MCP Servers, and AI Agents.
- Authenticate
kongctl with a Konnect PAT or System Account Access Token.
- Apply the converted configuration to the new AI Gateway control plane.
The diagram below shows where each tool sits in the flow:
sequenceDiagram
participant A as API Gateway CP
AI Gateway v1
participant B as kong.yaml
participant C as ./config (manual config)
participant D as ./out (entity files)
participant E as AI Gateway CP
AI Gateway v2
A->>B: deck gateway dump
Note over C: add control plane, auth
strategies, vaults, and ACLs
B->>D: kongctl convert ai-gateway
C-->>D: merged on conversion
D->>D: review and validate
D->>E: kongctl apply
The kongctl-ext-aigw-converter extension is used to translate your existing declarative configuration into the AI Gateway 2.x entity model.
Install it with kongctl install extension Kong/kongctl-ext-aigw-converter and type yes when prompted by the terminal.
Use deck to dump the declarative configuration from the Kong Gateway control plane that currently runs your AI plugins. Replace the placeholders with your Konnect PAT and the name of the source control plane.
deck gateway dump \
--konnect-token $KONNECT_TOKEN \
--konnect-control-plane-name $KONNECT_API_GATEWAY_CONTROL_PLANE_NAME \
> kong.yaml
The resulting kong.yaml contains your Services, Routes, plugins (including ai-proxy-advanced, ai-mcp-proxy, and ai-a2a-proxy), Consumers, and Vaults.
Converter requirements:
- Each
ai-proxy or ai-proxy-advanced plugin you’re migrating needs a model name (for example gpt-4o) configured. The converter can’t generate one for you, and a converted AI Model with no model name fails validation when you apply it. If any of your plugins are missing one, set it on the Kong Gateway 3.x control plane before you export.
- Each
ai-proxy or ai-proxy-advanced plugin’s target needs authentication (auth) configured if the upstream provider requires it. The converter carries this into the AI Gateway Model Provider’s config.auth. If the target has no auth configured, the converted provider is missing config entirely and fails validation when you apply it.
-
ai-proxy-advanced, ai-mcp-proxy, and ai-a2a-proxy plugins can be attached to a Service or a Route, but the Service they’re attached to must have at least one Route attached, or the plugin won’t convert to the AI Gateway 2.x entity model.
The converter cannot recover some configuration from the decK export:
- The target AI Gateway 2.x control plane
- Auth strategies
- Vaults
- Per-model ACLs
Declare these in a ./config directory before you run the converter, and it merges them into the output. Create the directory:
Add a config/gateway.yaml that points at the AI Gateway 2.x control plane you created in the prerequisites. Use an _external selector to reference the existing control plane by name so kongctl does not create a new one:
# config/gateway.yaml
ai_gateways:
- ref: ai-gateway
_external:
selector:
matchFields:
name: "your-ai-gateway-name"
Authentication works differently in version 2.x. Route auth plugins are not carried over onto AI Models, AI MCP Servers, or AI Agents. Instead you declare auth strategies here, and the converter attaches them to the entities you list. AI Models, AI MCP Servers, and AI Agents all support auth strategies the same way, referenced from the entity’s access.auth_strategies.
Add a config/auth_strategies.yaml with an entry for each authentication method (key-auth or openid-connect). Each entry may optionally list the models, agents, and mcp_servers it attaches to by name, or "*" to attach to every entity of that kind:
# config/auth_strategies.yaml
auth_strategies:
- ref: key-auth-prod
name: key-auth-prod
display_name: Key Auth
type: key-auth
config:
key_names:
- x-api-key
# Optional entity selectors
models: ['*']
mcp_servers: ['*']
agents: ['*']
- ref: oidc-prod
name: oidc-prod
display_name: OIDC
type: openid-connect
config:
issuer: "https://your-idp.example.com"
client_id:
- your-client-id
client_secret:
- !secret {source: !env OIDC_CLIENT_SECRET}
scopes:
- openid
cache_tokens_salt: "a-random-string"
# Only one auth strategy per entity kind can use the '*' wildcard,
# so name the specific models, MCP servers, and agents that use OIDC.
models: ['my-model']
mcp_servers: ['my-mcp-server']
agents: ['my-agent']
The openid-connect entry above shows only the fields AI Gateway requires at minimum. Add any other fields your identity provider actually uses (additional scopes, claims, cookie settings, and so on). Don’t copy fields straight from your v1 openid-connect plugin config if they’re unset (null) there. AI Gateway 2.x rejects explicit null values for most fields, so it’s easier to start minimal and add only what you need.
At most two auth strategies are allowed (at most one key-auth and one openid-connect), and at most one may use the "*" wildcard per entity kind. The converter attaches each strategy to the listed entities via their access.auth_strategies. An AI Agent or AI MCP Server accepts at most one auth strategy, so linkage that would attach two to the same agent or MCP server fails the run; AI Models are uncapped.
Add a config/vaults.yaml with an entry for any secret store your migrated config references with {vault://...} syntax:
# config/vaults.yaml
vaults:
- ref: ai-vault
name: ai-vault
display_name: AI Gateway Vault
type: konnect
description: Credential store for AI Gateway
config:
config_store_id: "${KONNECT_CONFIG_STORE_ID}"
Note: For a Konnect Config Store vault (type: konnect), you can either reference an existing Config Store by its ID, or leave config_store_id: "" empty and let the converter create one for you: it emits an empty AI Gateway Config Store and wires the vault to it. Either way, populating real secret values into the store is a manual step after you apply.
Optionally, add a config/model_acls.yaml to control which AI Consumers or AI Consumer Groups can reach each AI Model. Each entry names a model and sets allow or deny:
# config/model_acls.yaml
acls:
- name: azure-gpt-4o
allow:
- Azure-OpenAI-Gold
- Azure-OpenAI-Silver
name must match the AI Model’s converted name, which the converter derives from the v1 Route name the ai-proxy/ai-proxy-advanced plugin is attached to, not from any field inside the plugin itself. If you’re not sure what a model will be named, run the converter once without model_acls.yaml, check the ref/name values in models.yaml in ./out, then add your ACLs and re-run.
Run kongctl convert ai-gateway against the exported kong.yaml file and your ./config directory. The tool reads the AI Gateway running on Kong Gateway plugin configuration, merges the manual config, and emits an AI Gateway 2.x entity and Policy configuration to ./out.
kongctl convert ai-gateway \
--input kong.yaml \
--config ./config \
--out ./out
The --out flag sets the output directory for the converted files, which the converter creates for you. It inspects each AI plugin and translates it into the matching version 2.x entity or Policy:
- Each
ai-proxy-advanced plugin becomes an AI Model (and one AI Model Provider per distinct upstream provider and credential set).
- Each
ai-mcp-proxy plugin becomes an AI MCP Server whose type matches the plugin mode.
- Each
ai-a2a-proxy plugin becomes an AI Agent.
- Non-auth supporting plugins on the same Service or Route become AI Policies attached to the relevant entity.
- Authentication plugins (
key-auth, openid-connect) on any AI route (AI Model, AI MCP Server, or AI Agent) are stripped; identity comes from the auth strategies you declared in ./config, attached to each entity’s access.auth_strategies.
Open the yaml files in ./out and confirm that the converter captured everything you expect. At minimum, check that:
- Every AI Proxy plugin-based model has a corresponding AI Model entry in
models.yaml, with the right capabilities, formats, and targets.
- Provider credentials were extracted correctly, and each
targets[].provider reference resolves to a declared AI Model Provider in providers.yaml.
- Every AI MCP Server in
mcp_servers.yaml has the correct type for its original plugin mode, and that each listener names its tool sets in sources.
- Each AI Agent points at the correct upstream URL and carries the logging settings you had configured.
- The auth strategies you declared in
./config were merged into auth_strategies.yaml and attached to the right AI Models, AI MCP Servers, and AI Agents via access.auth_strategies, and vaults.yaml and gateway.yaml reflect what you declared.
- Non-auth supporting plugins were converted to AI Policies and attached to the right entities.
- Any write-only credential field carried over as a plain string, such as an AI Model Provider’s
config.auth.headers[].value, is wrapped in a deferred !secret source rather than left as a literal. See Validate AI Model converted configuration files.
Pay particular attention to anything the converter can’t infer from the config of AI Gateway running on Kong Gateway, such as an AI Model Provider display_name or an AI Model display_name. These are required in AI Gateway 2.x and may be generated from the source data, so rename them to something meaningful before you apply.
In AI Gateway running on Kong Gateway, a model is an AI Proxy Advanced plugin attached to a Service and Route. The plugin holds the provider, credentials, route type, model options, and load balancer all in one place.
In AI Gateway version 2.x, that single plugin becomes two entities: an AI Model Provider that holds the upstream connection and credentials, and an AI Model that holds routing, capabilities, format, load balancing, and one or more targets that each reference an AI Model Provider.
This allows you to reuse AI Model Providers in multiple AI Models.
The following deck snippet defines a chat model that load balances across two OpenAI models using round-robin:
# kong.yaml (AI Gateway v1, exported with deck gateway dump)
services:
- name: openai-chat
url: https://api.openai.com:443
routes:
- name: openai-chat-route
paths:
- /chat
plugins:
- name: ai-proxy-advanced
config:
balancer:
algorithm: round-robin
targets:
- route_type: llm/v1/chat
weight: 70
auth:
header_name: Authorization
header_value: Bearer {vault://openai-vault/api-key}
model:
provider: openai
name: gpt-4o
options:
max_tokens: 512
temperature: 0.7
- route_type: llm/v1/chat
weight: 30
auth:
header_name: Authorization
header_value: Bearer {vault://openai-vault/api-key}
model:
provider: openai
name: gpt-4o-mini
options:
max_tokens: 512
temperature: 0.7
The converter splits the credentials into an AI Model Provider and the routing and balancing into an AI Model. The route_type of llm/v1/chat becomes capabilities: [generate] with an openai format, and each target references the AI Model Provider by name.
# providers.yaml (AI Gateway v2 entity model)
ai_gateway_model_providers:
- ref: openai-prod
ai_gateway: !ref ai-gateway#id
type: openai
name: openai-prod
display_name: OpenAI Production
config:
auth:
# Carried over from the v1 target auth block.
type: basic
headers:
- name: Authorization
value: !secret {source: !env OPENAI_API_KEY}
# models.yaml (AI Gateway v2 entity model)
ai_gateway_models:
- ref: openai-chat
ai_gateway: !ref ai-gateway#id
type: model
name: openai-chat
display_name: OpenAI Chat
enabled: true
capabilities:
- generate
formats:
- type: openai
access:
acls:
allow: []
deny: []
policies: []
config:
route:
paths:
- /chat
model:
name_header: true
balancer:
algorithm: round-robin
targets:
- name: gpt-4o
provider: openai-prod
weight: 70
config:
type: openai
max_tokens: 512
temperature: 0.7
- name: gpt-4o-mini
provider: openai-prod
weight: 30
config:
type: openai
max_tokens: 512
temperature: 0.7
AI Model Provider credential fields, such as config.auth.headers[].value for basic auth, or the equivalents for other auth types (for example secret_access_key, client_secret), are write-only in AI Gateway 2.x.
The converter carries over whatever value was in the v1 target’s auth block as a plain string, whether that was a hardcoded literal or {vault://...} syntax.
A plain string in a write-only field makes kongctl apply/plan fail:
Error: failed to load configuration: failed to process !secret tags in out/providers.yaml:
resource ai_gateway_model_provider "openai-1" field /config/auth/headers/0/value
is write-only and requires !secret with a deferred source
After the converter runs, find each plain string value in a write-only credential field in providers.yaml and wrap it in a deferred !secret source as shown above, then set the real value out of band:
export OPENAI_API_KEY="YOUR CREDENTIAL"
The environment variable name is your own choice. It doesn’t need to match anything you declared in config/auth_strategies.yaml or any other file in ./config.
To verify your AI Models entity migration, be sure to check the following:
- Capabilities and format: Confirm the
route_type was decomposed correctly. For example, llm/v1/chat maps to capabilities: [generate] and formats: [{type: openai}], while llm/v1/embeddings maps to capabilities: [embeddings]. Asynchronous file and batch route types map to an AI Model with type: api and capabilities of files or batches.
- Provider reuse: If several AI Gateway running on Kong Gateway targets shared the same provider and credentials, the converter should produce a single AI Model Provider that all targets reference. Deduplicate any near-identical AI Model Providers it couldn’t merge.
- Model options: Per-target options such as
max_tokens, temperature, top_p, and top_k move into each targets[].config, keyed by the provider type.
- Auth override: If you relied on
config.targets.auth.allow_override when running AI Gateway on Kong Gateway, set allow_auth_override: true on the corresponding target in version 2.x.
- Identity: AI Models have no route auth after conversion. Confirm the auth strategies you added previously are attached via
access.auth_strategies.
- Vector database and embeddings:
config.vectordb and config.embeddings settings carry over onto the AI Model config under the balancer config, keeping the same Redis or pgvector strategy.
In AI Gateway running on Kong Gateway, an MCP server is an AI MCP Proxy plugin attached to a Service and Route. The plugin runs in one of four modes and holds the tools, Access Control Lists (ACLs), and logging settings in its config.
In AI Gateway version 2.x, that plugin becomes a single AI MCP Server entity, with the following changes:
- The plugin
mode setting becomes an MCP Server type setting. This part of the migration essentially consists in copying the value you set in config.mode to the type setting.
- ACLs, which were plugin fields in AI Gateway running on Kong Gateway, become a top-level fields on the AI MCP Server.
The following table maps each Kong Gateway plugin mode to its version 2.x MCP Server type:
|
V1 MCP proxy config.mode
|
V2 AI MCP Server type
|
passthrough-listener
|
passthrough-listener
|
conversion-listener
|
conversion-listener
|
conversion-only
|
conversion-only
|
listener
|
listener
|
|
(no V1 equivalent)
|
upstream-server
|
The AI MCP OAuth2 plugin has no direct AI Gateway 2.x Policy equivalent, so the converter splits its config in two:
- The OAuth2/OIDC token-verification fields (
client_id, client_secret, introspection_endpoint, jwks_endpoint, consumer_claim, and similar) become an openid-connect auth strategy, referenced from the server’s access.auth_strategies, the same way a key-auth or openid-connect plugin is handled.
- The OAuth 2.0 Protected Resource Metadata fields (
authorization_servers, metadata_discovery_endpoint, metadata_endpoint, resource, scopes_supported) become the server’s access.metadata block, which the AI Gateway advertises to OAuth clients per RFC 9728.
Fields with no equivalent in either destination are dropped, with a warning naming them. Proxy authorization headers (http_proxy_authorization, https_proxy_authorization) have no migrated equivalent and need to be reconfigured manually.
Note: If your config/auth_strategies.yaml linkage attaches a different (non-openid-connect) auth strategy to this MCP server, for example a key-auth wildcard, the synthesized access.metadata is dropped instead of being carried through: the AI Gateway API only accepts Protected Resource Metadata paired with an openid-connect auth strategy.
In version 1.x, a listener plugin aggregated tool sets implicitly: config.server.tag named a decK plugin tag, and every ai-mcp-proxy plugin carrying that tag contributed its tools. Version 2.x replaces this with an explicit sources list of AI MCP Server names, which is required on a listener.
The converter resolves this for you: it matches config.server.tag against the plugin tags of the other MCP proxies and writes the resulting AI MCP Server names into sources, dropping the now-unsupported config.server.tag.
# V1: aggregation by tag
- name: ai-mcp-proxy
tags: [aigw610:tools] # the tool set
config:
mode: conversion-only
- name: ai-mcp-proxy # the aggregator
config:
mode: listener
server:
tag: aigw610:tools
# V2: aggregation by name
ai_gateway_mcp_servers:
- name: reports-mcp
type: conversion-only
- name: aggregate-mcp
type: listener
sources:
- reports-mcp
A sources entry must name a conversion-only tool set or an upstream-server. If a tag matched a conversion-listener instead, the converter still lists it and displays a warning.
Split that entity into a conversion-only tool set (plus its own listener, if it also served a route) before you apply. If a listener declared no config.server.tag, or the tag matched nothing, the converter warns and emits no sources; add them manually.
The following AI Gateway running on Kong Gateway example config:
- Converts a REST flights API into MCP tools
- Serves the tools on a Route, with
key-auth in front and a default ACL
# kong.yaml (AI Gateway v1, exported with deck gateway dump)
services:
- name: kongair-flights
url: https://flights.internal.kongair.com
routes:
- name: kongair-flights-mcp
paths:
- /flights-mcp
plugins:
- name: key-auth
- name: ai-mcp-proxy
config:
mode: conversion-listener
logging:
log_statistics: true
log_audits: true
default_acl:
allow:
- flight-operators
tools:
- name: search_flights
description: Search available flights
# ...OpenAPI-derived tool definition...
Converting the example to use the version 2.x model:
- Moves the upstream URL, route, tools, and logging settings onto a single AI MCP Server entity
- Copies the value from the plugin
mode into the MCP Server type
- Strips the
key-auth plugin. Like AI Models, an AI MCP Server declares identity separately: add an auth strategy manually and reference it from the server’s access.auth_strategies.
- Renames
default_acl to default_tool_acls and sets the ACL evaluation mode explicitly with acl_attribute_type
- Renames the
config.logging fields: log_audits becomes audits and log_payloads becomes payloads. log_statistics has no AI Gateway 2.x equivalent and is dropped.
# auth_strategies.yaml (in ./out, generated from the strategy you declared
# in ./config in Step 3; the v1 key-auth plugin itself is stripped on conversion)
ai_gateway_auth_strategies:
- ref: flights-key-auth
ai_gateway: !ref ai-gateway#id
type: key-auth
name: flights-key-auth
display_name: Flights Key Auth
config:
key_names:
- apikey
# mcp_servers.yaml (AI Gateway v2 entity model)
ai_gateway_mcp_servers:
- ref: kongair-flights
ai_gateway: !ref ai-gateway#id
type: conversion-listener
name: kongair-flights
display_name: Kong Air Flights
enabled: true
access:
acl_attribute_type: consumer
acls:
allow: []
deny: []
default_tool_acls:
allow:
- flight-operators
deny: []
auth_strategies:
- flights-key-auth
config:
url: https://flights.internal.kongair.com
route:
paths:
- /flights-mcp
logging:
audits: true
tools:
- name: search_flights
description: Search available flights
# ...OpenAPI-derived tool definition...
To verify your AI MCP Servers entity migration, be sure to check the following:
- Mode and type: Confirm the
type matches the original mode. The conversion-only and conversion-listener modes require Route information, so make sure the converted entity includes a config.route.
- Listener aggregation: If you used
conversion-only plugins feeding a listener plugin via tags, confirm the version 2.x listener AI MCP Server lists each of those tool sets by name in sources. sources is required on a listener, so any converter warning about it must be resolved before you apply.
- ACL mode: Version 2.x makes the ACL subject explicit. Use
acl_attribute_type: consumer to evaluate against Consumers and Consumer Groups, or acl_attribute_type: oauth_access_token with access_token_claim_field to evaluate against a claim in an OAuth2 access token.
- Per-tool ACLs: A per-tool
acl replaces the default for that tool and does not merge with default_tool_acls. Ensure every allowed subject is listed on the tool explicitly.
- Logging field names:
log_payloads and log_audits become payloads and audits under config.logging. log_statistics has no AI Gateway 2.x equivalent and is dropped.
- Authentication: Like AI Models, auth plugins on MCP routes (like the
key-auth example above) are stripped on conversion. Declare the auth strategy manually and reference it from the server’s access.auth_strategies.
-
ai-mcp-oauth2 servers: Confirm the generated openid-connect auth strategy is attached via access.auth_strategies and that access.metadata carries the Protected Resource Metadata fields you expect. Review any converter warnings naming dropped config fields, and reconfigure proxy authorization headers manually if you used them.
In AI Gateway running on Kong Gateway, an agent is an AI A2A Proxy plugin attached to a Service and Route. The plugin is a transparent proxy that adds observability and agent card URL rewriting to Agent-to-Agent (A2A) traffic (where the gateway automatically changes the agent’s address so clients connect through the gateway instead of directly to the agent.)
In AI Gateway version 2.x, that plugin becomes an AI Agent entity, which captures the following in a single entity and applies the agent card which automatically rewrites the:
- Upstream URL
- Routing
- Logging
The following example for AI Gateway running on Kong Gateway defines an A2A agent that proxies an upstream agent that handles flight bookings:
# kong.yaml (AI Gateway v1, exported with deck gateway dump)
services:
- name: flight-booking-agent
url: https://booking-agent.internal.kongair.com
routes:
- name: flight-booking-agent-route
paths:
- /booking-agent
plugins:
- name: ai-a2a-proxy
config:
max_request_body_size: 8388608
logging:
log_statistics: true
log_payloads: false
max_payload_size: 1048576
Converting the example to use the version 2.x model:
- Moves the upstream URL, route, request-size limit, and logging settings onto a single AI Agent entity.
- Renames the
config.logging fields: log_payloads becomes payloads. log_statistics has no AI Gateway 2.x equivalent and is dropped.
Like AI Models and AI MCP Servers, any authentication plugin on the agent’s route is stripped on conversion. If the agent needs auth, declare an auth strategy manually and reference it from the agent’s access.auth_strategies.
# agents.yaml (AI Gateway v2 entity model)
ai_gateway_agents:
- ref: kongair-flight-booking-agent
ai_gateway: !ref ai-gateway#id
type: a2a
name: kongair-flight-booking-agent
display_name: Kong Air Flight Booking Agent
enabled: true
access:
acls:
allow: []
deny: []
policies: []
config:
url: https://booking-agent.internal.kongair.com
route:
paths:
- /booking-agent
max_request_body_size: 8388608
logging:
payloads: false
max_payload_size: 1048576
To verify your AI Agent entity migration, be sure to check the following:
- Agent type: Most A2A workloads use
type: a2a. Use type: http for plain HTTP agent traffic that does not follow the A2A protocol bindings.
- URL rewriting: The AI Agent entity rewrites the agent card
url and additionalInterfaces[].url fields to the gateway address automatically, the same behavior the older plugin provided. No extra configuration is needed.
- Logging field names: As with AI MCP Servers,
log_payloads becomes payloads under config.logging, and log_statistics is dropped (no AI Gateway 2.x equivalent).
- Identity: Like AI Models, an AI Agent has no route auth after conversion. If the agent needs authentication, confirm the auth strategy you declared is attached via
access.auth_strategies.
- Analytics: A2A metrics flow into Konnect analytics. View them under Agentic usage analytics in Konnect Explorer and Dashboards.
kongctl apply needs a Konnect PAT or System Account Access Token to reach your control plane. Reuse the token from the prerequisites with one of the following:
- Run
kongctl login to authenticate interactively through the browser.
- Pass the token with the
--pat flag on the apply command.
- Set the
KONGCTL_DEFAULT_KONNECT_PAT environment variable.
Preview the changes before applying them:
Review the plan, then sync the converted configuration to the AI Gateway control plane:
kongctl creates the AI Model Providers, Models, MCP Servers, Agents, and Policies defined in the files. Because the configuration is declarative, you can re-run to apply after edits and kongctl will reconcile the control plane to match the files.
After the apply succeeds, the AI Gateway exposes its configuration and telemetry endpoints. Send a representative request to each migrated AI Model, MCP server, and Agent to confirm behavior matches AI Gateway running on Kong Gateway before you transfer traffic over.