From 956bf48ba0a8cb44a4c45df20ffb71d650ff5c68 Mon Sep 17 00:00:00 2001 From: jbaross Date: Tue, 4 Aug 2026 15:58:40 +0100 Subject: [PATCH 1/5] init consumer config --- .../use-access-controls-for-mcp-tools.md | 349 ++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md diff --git a/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md new file mode 100644 index 0000000000..e19ddc6d50 --- /dev/null +++ b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md @@ -0,0 +1,349 @@ +--- +title: Control MCP tool access with Consumer and Consumer Group ACLs +content_type: how_to +related_resources: + - text: "{{site.ai_gateway}}" + url: /ai-gateway/ + - text: AI MCP Proxy + url: /plugins/ai-mcp-proxy/ + +description: Learn how to use the AI MCP Proxy plugin to restrict access to specific MCP tools based on Kong Consumers and Consumer Groups. Configure global and per-tool ACLs, define user roles, and validate access behavior using Insomnia’s MCP Client. + +products: + - gateway + - ai-gateway + - insomnia + +permalink: /ai-gateway/use-access-controls-for-mcp-tools/ + +series: + id: mcp-acls + position: 1 + +works_on: + - konnect + +min_version: + ai-gateway: '2.0' + +tags: + - ai + - openai + - mcp + +tldr: + q: How do I enforce control access to MCP tools using {{site.ai_gateway}}? + a: | + Use the AI MCP Proxy plugin to control access to MCP tools with global and + per-tool ACLs based on Consumers and Consumer Groups. Use Insomnia’s MCP + Client feature to test and validate which tools each user can access. + +tools: + - kongctl + +prereqs: + inline: + - title: Mock API Server + content: | + Before using the [AI MCP Proxy](/plugins/ai-mcp-proxy/) plugin, you need an upstream MCP-compatible HTTP server to expose. For this tutorial, we’ll use a simple Express-based MCP server that simulates a marketplace system. It provides read-only access to sample users and their orders. + + The server exposes a single `/mcp` endpoint and registers tools instead of REST routes, including: + + * `list_users` + * `get_user` + * `list_orders` + * `list_orders_for_user` + * `search_orders` + + These tools operate on in-memory marketplace data, allowing you to test MCP behavior without connecting to a real backend. + + Run the following command to clone the repository, install dependencies, build the server, and start it: + + ```bash + git clone https://github.com/tomek-labuk/marketplace-acl.git && \ + cd marketplace-acl && \ + npm install && \ + npm run build && \ + node dist/server.js + ``` + + When the server starts, it listens at: + + ``` + http://localhost:3001/mcp + ``` + icon_url: /assets/icons/github.svg + konnect: + - name: KONG_STATUS_LISTEN + value: '0.0.0.0:8100' + +faqs: + - q: "Why do I see the error code `INVALID_PARAMS -32602` on failed requests instead of `HTTP 403 Forbidden`?" + a: | + Prior to {{site.ai_gateway}} 3.14, requests that matched an MCP ACL deny rule or failed to match an allow list returned the JSON-RPC error code `INVALID_PARAMS -32602`. + This has now changed to match the [MCP 2025-11-25 authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#error-handling) and returns `HTTP 403 Forbidden`. + +--- + + +## Create Consumer Groups for each AI usage tier + +Start by configuring [AI Consumer Groups](/ai-gateway/entities/ai-consumer-group/) that reflect access levels. + +These groups govern MCP tool permissions: +- `admin` - full access +- `developer` - limited access +- `suspended` - blocked from MCP tools + +{% entity_examples %} +ai_gateway_consumer_groups: + - ref: admin + ai_gateway: !lookup name:ai-quickstart + display_name: Internal Teams + name: admin + policies: [] + - ref: developer + ai_gateway: !lookup name:ai-quickstart + display_name: Internal Teams + name: developer + policies: [] + - ref: suspended + ai_gateway: !lookup name:ai-quickstart + display_name: Internal Teams + name: suspended + policies: [] +{% endentity_examples %} + +## Create Consumers + +Let's configure individual AI Consumers and assign them to groups. + +We'll use the [Key Auth](/ai-gateway/policies/key-auth/) AI Policy so that each AI Consumer presents an API key in their requests that is used for `api-key` authentication. + +Each AI Consumer inherits group permissions which will govern access to MCP tools: + +{% entity_examples %} +ai_gateway_consumers: + - ref: alice + ai_gateway: !lookup name:ai-quickstart + display_name: Alice + name: alice + type: api-key + policies: + - !ref my-key-auth#name + - ref: bob + ai_gateway: !lookup name:ai-quickstart + display_name: Bob + name: bob + type: api-key + policies: + - !ref my-key-auth#name + - ref: carol + ai_gateway: !lookup name:ai-quickstart + display_name: Carol + name: carol + type: api-key + policies: [] + - ref: eason + ai_gateway: !lookup name:ai-quickstart + display_name: Eason + name: eason + type: api-key + policies: + - !ref my-key-auth#name +ai_gateway_policies: + - ref: my-key-auth + ai_gateway: !lookup name:ai-quickstart + name: my-key-auth + display_name: "my-key-auth" + type: key-auth + config: + key_names: + - apikey +{% endentity_examples %} + +## Configure the AI MCP Proxy plugin + +Now, let's configure the AI MCP Proxy plugin to apply tool-level access rules. The plugin controls which users or AI agents can see or call each MCP tool. Access is determined by Consumer Groups and individual Consumers using allow and deny lists. A tool ACL replaces the default rule when present. + +The table below shows the effective permissions for the configuration: + + +{% table %} +columns: + - title: MCP Tool + key: tool + - title: Admin group + key: admin + - title: Developer group + key: developer + - title: Eason consumer + key: eason + - title: Suspended group + key: suspended + +rows: + - tool: "`list_users`" + admin: Yes + developer: No + eason: Yes + suspended: No + - tool: "`get_user`" + admin: Yes + developer: Yes + eason: No + suspended: No + - tool: "`list_orders`" + admin: Yes + developer: Yes + eason: No + suspended: No + - tool: "`list_orders_for_user`" + admin: Yes + developer: Yes + eason: No + suspended: No + - tool: "`search_orders`" + admin: Yes + developer: No + eason: No + suspended: No +{% endtable %} + + +The following plugin configuration applies the ACL rules for the MCP tools shown in the table above: + +{% entity_examples %} +entities: + plugins: + - name: ai-mcp-proxy + route: mcp-acl-route + config: + mode: passthrough-listener + include_consumer_groups: true + default_acl: + - scope: tools + allow: + - developer + - admin + deny: + - suspended + logging: + log_payloads: false + log_statistics: true + log_audits: true + tools: + - description: List users + name: list_users + acl: + allow: + - admin + - eason + deny: + - developer + - description: Get user + name: get_user + acl: + allow: + - admin + - developer + - description: List orders + name: list_orders + acl: + allow: + - admin + - developer + - description: List orders for users + name: list_orders_for_user + acl: + allow: + - admin + - developer + - description: Search orders by name (case-insensitive substring) + name: search_orders + acl: + allow: + - admin + deny: + - developer +{% endentity_examples %} + +## Validate the configuration + +Let's use Insomnia's MCP Client feature to validate our ACL configuration: + +1. Go to the Insomnia app. +1. Click **Create MCP Client** in the left sidebar. +1. Enter the preferred name and click **Create**. +1. In the `HTTP` field enter `http://localhost:8000/mcp`. +1. Go to the **Auth** tab. +1. Select **API Key** from the Auth type dropdown. + +Now let's verify access for each user by connecting with their API key: + +{% navtabs "validate-mcp-access" %} +{% navtab "Alice (admin group)" %} + +1. Enter `apikey` in the Key field. +1. Enter `alice-key` in the Value field. +1. Click the **Connect** button. +1. Once connected, Insomnia should list these tools in the sidebar: + + ```text + list_users + get_user + list_orders + list_orders_for_user + search_orders + ``` + + Alice belongs to the **admin** group and has access to all tools. +1. Click **Disconnect** to switch to another user. + +{% endnavtab %} +{% navtab "Bob (developer group)" %} + +1. Enter `apikey` in the Key field. +1. Enter `bob-key` in the Value field. +1. Click the **Connect** button. +1. Once connected, Insomnia should list these tools in the sidebar: + + ```text + get_user + list_orders + list_orders_for_user + ``` + {:.no-copy-code} + + Bob belongs to the **developer** group and is denied access to `list_users`. +1. Click **Disconnect** to update the key for the next user. + +{% endnavtab %} +{% navtab "Carol (suspended group)" %} + +1. Enter `apikey` in the Key field. +1. Enter `carol-key` in the Value field. +1. Click the **Connect** button. + + The connection should fail with a `HTTP 403 Forbidden` response.
+ Carol belongs to the **suspended** group, which is globally denied access to all tools. +1. Click **Disconnect** to switch to another user. + +{% endnavtab %} +{% navtab "Eason (no group)" %} + +1. Enter `apikey` in the Key field. +1. Enter `eason-key` in the Value field. +1. Click the **Connect** button. +1. Once connected, Insomnia should list this tool in the sidebar: + + ```text + list_users + ``` + {:.no-copy-code} + + Eason is not part of any group but is explicitly allowed access to `list_users` in the tool’s ACL. +1. Click **Disconnect** after validation. + +{% endnavtab %} +{% endnavtabs %} From 4a92b972f7cfe90e3e2ed9ad97065bcb0a7f67ac Mon Sep 17 00:00:00 2001 From: jbaross Date: Tue, 4 Aug 2026 16:53:36 +0100 Subject: [PATCH 2/5] mcp config --- .../use-access-controls-for-mcp-tools.md | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md index e19ddc6d50..07531c6196 100644 --- a/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md +++ b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md @@ -213,6 +213,100 @@ rows: The following plugin configuration applies the ACL rules for the MCP tools shown in the table above: + +```sh +kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" < Date: Tue, 4 Aug 2026 17:09:24 +0100 Subject: [PATCH 3/5] cleanup --- .../ai-gateway/map-api-to-mcp-tools.md | 2 +- .../use-access-controls-for-mcp-tools.md | 76 ++----------------- 2 files changed, 8 insertions(+), 70 deletions(-) diff --git a/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md b/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md index 50beb54905..df30602fe8 100644 --- a/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md +++ b/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md @@ -7,7 +7,7 @@ related_resources: - text: AI MCP Server entity url: /ai-gateway/entities/ai-mcp-server/ -description: Learn how to create an MCP Server entity in {{site.ai_gateway}} to convert any RESTful API into MCP tools, including setting up a mock Node.js server for testing. +description: Learn how to create an AI MCP Server entity in {{site.ai_gateway}} to convert any RESTful API into MCP tools, including setting up a mock Node.js server for testing. products: - ai-gateway diff --git a/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md index 07531c6196..c056293045 100644 --- a/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md +++ b/app/_how-tos/ai-gateway/use-access-controls-for-mcp-tools.md @@ -7,10 +7,9 @@ related_resources: - text: AI MCP Proxy url: /plugins/ai-mcp-proxy/ -description: Learn how to use the AI MCP Proxy plugin to restrict access to specific MCP tools based on Kong Consumers and Consumer Groups. Configure global and per-tool ACLs, define user roles, and validate access behavior using Insomnia’s MCP Client. +description: Learn how to create an AI MCP Server entity in {{site.ai_gateway}} to restrict access to specific MCP tools based on AI Consumers and AI Consumer Groups. Configure global and per-tool ACLs, define user roles, and validate access behavior using Insomnia’s MCP Client. products: - - gateway - ai-gateway - insomnia @@ -34,8 +33,8 @@ tags: tldr: q: How do I enforce control access to MCP tools using {{site.ai_gateway}}? a: | - Use the AI MCP Proxy plugin to control access to MCP tools with global and - per-tool ACLs based on Consumers and Consumer Groups. Use Insomnia’s MCP + Use the AI MCP Server to control access to MCP tools with global and + per-tool ACLs based on AI Consumers and AI Consumer Groups. Use Insomnia’s MCP Client feature to test and validate which tools each user can access. tools: @@ -45,7 +44,7 @@ prereqs: inline: - title: Mock API Server content: | - Before using the [AI MCP Proxy](/plugins/ai-mcp-proxy/) plugin, you need an upstream MCP-compatible HTTP server to expose. For this tutorial, we’ll use a simple Express-based MCP server that simulates a marketplace system. It provides read-only access to sample users and their orders. + Before creating an AI MCP Server, you need an upstream MCP-compatible HTTP server to expose. For this tutorial, we’ll use a simple Express-based MCP server that simulates a marketplace system. It provides read-only access to sample users and their orders. The server exposes a single `/mcp` endpoint and registers tools instead of REST routes, including: @@ -77,12 +76,6 @@ prereqs: - name: KONG_STATUS_LISTEN value: '0.0.0.0:8100' -faqs: - - q: "Why do I see the error code `INVALID_PARAMS -32602` on failed requests instead of `HTTP 403 Forbidden`?" - a: | - Prior to {{site.ai_gateway}} 3.14, requests that matched an MCP ACL deny rule or failed to match an allow list returned the JSON-RPC error code `INVALID_PARAMS -32602`. - This has now changed to match the [MCP 2025-11-25 authorization specification](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization#error-handling) and returns `HTTP 403 Forbidden`. - --- @@ -116,11 +109,11 @@ ai_gateway_consumer_groups: ## Create Consumers -Let's configure individual AI Consumers and assign them to groups. +Configure individual AI Consumers and assign them to groups. We'll use the [Key Auth](/ai-gateway/policies/key-auth/) AI Policy so that each AI Consumer presents an API key in their requests that is used for `api-key` authentication. -Each AI Consumer inherits group permissions which will govern access to MCP tools: +Each AI Consumer inherits group permissions that govern access to MCP tools: {% entity_examples %} ai_gateway_consumers: @@ -164,7 +157,7 @@ ai_gateway_policies: ## Configure the AI MCP Proxy plugin -Now, let's configure the AI MCP Proxy plugin to apply tool-level access rules. The plugin controls which users or AI agents can see or call each MCP tool. Access is determined by Consumer Groups and individual Consumers using allow and deny lists. A tool ACL replaces the default rule when present. +Configure the AI MCP Server to apply tool-level access rules. The AI MCP Server controls which users or AI agents can see or call each MCP tool. Access is determined by AI Consumer Groups and individual AI Consumers using allow and deny lists. A tool ACL replaces the default rule when present. The table below shows the effective permissions for the configuration: @@ -307,61 +300,6 @@ ai_gateway_mcp_servers: EOF ``` -{% entity_examples %} -entities: - plugins: - - name: ai-mcp-proxy - route: mcp-acl-route - config: - mode: passthrough-listener - include_consumer_groups: true - default_acl: - - scope: tools - allow: - - developer - - admin - deny: - - suspended - logging: - log_payloads: false - log_statistics: true - log_audits: true - tools: - - description: List users - name: list_users - acl: - allow: - - admin - - eason - deny: - - developer - - description: Get user - name: get_user - acl: - allow: - - admin - - developer - - description: List orders - name: list_orders - acl: - allow: - - admin - - developer - - description: List orders for users - name: list_orders_for_user - acl: - allow: - - admin - - developer - - description: Search orders by name (case-insensitive substring) - name: search_orders - acl: - allow: - - admin - deny: - - developer -{% endentity_examples %} - ## Validate the configuration Let's use Insomnia's MCP Client feature to validate our ACL configuration: From 48aa5f05834f90600ebba1523faafdb02f1236cb Mon Sep 17 00:00:00 2001 From: jbaross Date: Thu, 6 Aug 2026 15:34:09 +0100 Subject: [PATCH 4/5] initial file log example --- .../observe-mcp-traffic-with-acls.md | 247 ++++++++++++++++++ .../use-access-controls-for-mcp-tools.md | 3 - 2 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 app/_how-tos/ai-gateway/observe-mcp-traffic-with-acls.md diff --git a/app/_how-tos/ai-gateway/observe-mcp-traffic-with-acls.md b/app/_how-tos/ai-gateway/observe-mcp-traffic-with-acls.md new file mode 100644 index 0000000000..405b2131ea --- /dev/null +++ b/app/_how-tos/ai-gateway/observe-mcp-traffic-with-acls.md @@ -0,0 +1,247 @@ +--- +title: Observe MCP Traffic with Access Control Enabled +content_type: how_to +related_resources: + - text: "{{site.ai_gateway}}" + url: /ai-gateway/v1/ + - text: AI MCP Proxy + url: /plugins/ai-mcp-proxy/ + +description: Learn how to observe MCP tool activity after you apply access controls. Enable file-based logging, then review audit entries to confirm permitted tools and RPC calls. + +products: + - ai-gateway + - insomnia + +permalink: /ai-gateway/observe-mcp-traffic-with-acls/ + +series: + id: mcp-acls + position: 2 + +works_on: + - konnect + +min_version: + ai-gateway: '2.0' + +tags: + - ai + - openai + - mcp + +tldr: + q: How do I observe MCP tool usage with {{site.ai_gateway}}? + a: | + Use the File Log plugin to write MCP tool activity to a local file. Inspect the entries to see which tools each Consumer or Consumer Group accessed. Confirm the RPC calls that Chatwise sends to your MCP server. + +tools: + - kongctl + +prereqs: + inline: + - title: ChatWise desktop application + content: | + Download and install [ChatWise](https://chatwise.app/) for your OS. + + After installation: + 1. Launch the app. + 2. In Settings > Providers, configure your AI provider endpoint and API key. + +automated_tests: false + +--- + +## Configure MCP tools in Chatwise + +1. Open Chatwise and go to **Settings > MCP**: + + 1. Click **+** at the bottom of the window and choose **HTTP server (http)** from the **Type** dropdown. + 1. Enter a user-friendly name in the **Name** field. + 1. Enter `http://localhost:8000/mcp` in the **URL** field. + 1. Enable the **Run tools automatically** option. + 1. Click **+** next to the **HTTP headers** section and add: + + - **KEY**: `api-key` + - **VALUE**: `alice-key` + 1. Click the **Verify (view tools)** button. You should see the following tools: + + - `list_users` + - `get_user` + - `list_orders` + - `list_orders_for_user` + - `search_orders` + 1. Close **Settings**. + 1. In the chat window, click the hammer icon to enable tools. + 1. Toggle your MCP server on. You should see `1` next to the hammer icon. Click the icon to view the server name and the number of available tools. + +## Configure the File Log plugin + +Now, create a File Log AI Policy and add it to the existing AI MCP Server: + +```sh +kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" < Date: Thu, 6 Aug 2026 16:17:54 +0100 Subject: [PATCH 5/5] new kongctl syntax --- .../ai-gateway/map-api-to-mcp-tools.md | 22 +++++++++---------- .../observe-mcp-traffic-with-acls.md | 8 +++---- .../use-access-controls-for-mcp-tools.md | 8 +++---- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md b/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md index df30602fe8..5dfb7e8f9f 100644 --- a/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md +++ b/app/_how-tos/ai-gateway/map-api-to-mcp-tools.md @@ -99,11 +99,10 @@ This request confirms that the mock server is up and responding. Later, the MCP With the mock API server running, create an [MCP Server](/ai-gateway/entities/ai-mcp-server/) entity configured as a `conversion-listener` to expose its endpoints as MCP tools. The following example maps the mock API operations to MCP tool definitions that the client can invoke. -```sh -kongctl apply -f - --auto-approve --pat "$KONNECT_TOKEN" <