Enforce ACLs on aggregated MCP servers

TL;DR

Configure the AI MCP Proxy plugin in listener mode with include_consumer_groups: true on your aggregation route. Define per-tool ACLs on individual conversion-only routes. The listener enforces these ACLs based on the authenticated Consumer’s group membership.

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 quickstart script to automatically provision a Control Plane and Data Plane, and configure your environment:

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

    This sets up a Konnect Control Plane named quickstart, provisions a local Data Plane, and prints out the following environment variable exports:

     export DECK_KONNECT_TOKEN=$KONNECT_TOKEN
     export DECK_KONNECT_CONTROL_PLANE_NAME=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 requires Kong Gateway Enterprise. If you don’t have Kong Gateway set up yet, you can use the quickstart script with an enterprise license to get an instance of Kong Gateway running almost instantly.

  1. Export your license to an environment variable:

     export KONG_LICENSE_DATA='LICENSE-CONTENTS-GO-HERE'
    
  2. Run the quickstart script:

    curl -Ls https://get.konghq.com/quickstart | bash -s -- -e KONG_LICENSE_DATA 
    

    Once Kong Gateway is ready, you will see the following message:

     Kong Gateway Ready
    

decK is a CLI tool for managing Kong Gateway declaratively with state files. To complete this tutorial, install decK version 1.43 or later.

This guide uses deck gateway apply, which directly applies entity configuration to your Gateway instance. We recommend upgrading your decK installation to take advantage of this tool.

You can check your current decK version with deck version.

For this tutorial, you’ll need Kong Gateway entities, like Gateway Services and Routes, pre-configured. These entities are essential for Kong Gateway to function but installing them isn’t the focus of this guide. Follow these steps to pre-configure them:

  1. Run the following command:

    echo '
    _format_version: "3.0"
    services:
      - name: weather-internet-service
        url: https://api.weatherapi.com
      - name: deck-of-cards
        url: https://deckofcardsapi.com/api/deck
    routes:
      - name: weather-internet-mcp
        paths:
        - "/mcp/weather-internet"
        service:
          name: weather-internet-service
      - name: cards-api-mcp
        paths:
        - "/cards-api"
        service:
          name: deck-of-cards
      - name: mcp-aggregation
        paths:
        - "/mcp/aggregation"
    ' | deck gateway apply -
    

To learn more about entities, you can read our entities documentation.

  1. Go to WeatherAPI.
  2. Navigate to your dashboard and copy your API key.
  3. Export your API key by running the following command in your terminal:
    export DECK_WEATHERAPI_API_KEY='your-weatherapi-api-key'
    

Download and install ChatWise for your OS.

After installation:

  1. Launch the app.
  2. Navigate to the app’s settings.
  3. Click Providers in the sidebar.
  4. In the Providers sidebar, click OpenAI.
  5. In the API Key field, enter your OpenAI API key.

In this how-to, you’ll restrict access to aggregated MCP tools using Consumer Groups. This allows you to define per-tool ACLs on conversion-only plugins and enforce them through a listener with the include_consumer_groups setting.

Set up Consumer authentication

Configure authentication so Kong Gateway can identify each caller. Use the Key Auth plugin so each user (or AI agent) presents an API key with requests:

echo '
_format_version: "3.0"
plugins:
  - name: key-auth
    route: mcp-aggregation
    config:
      key_names:
      - apikey
' | deck gateway apply -

Create Consumer Groups for each access tier

Configure Consumer Groups that reflect access levels. These groups govern MCP tool permissions:

  • gold-partner - full access to all tools
  • silver-partner - full access to all tools
  • bronze-partner - blocked from MCP tools
  • no group (eason user) - blocked from MCP tools
echo '
_format_version: "3.0"
consumer_groups:
  - name: gold-partner
  - name: silver-partner
  - name: bronze-partner
' | deck gateway apply -

Create Consumers

Configure individual Consumers and assign them to groups. Consumers here can represent the humans or agents using the MCP tools. Each Consumer uses a unique API key and inherits group permissions which govern access to MCP tools:

echo '
_format_version: "3.0"
consumers:
  - username: alice
    groups:
    - name: gold-partner
    keyauth_credentials:
    - key: alice-key
  - username: bob
    groups:
    - name: silver-partner
    keyauth_credentials:
    - key: bob-key
  - username: carol
    groups:
    - name: bronze-partner
    keyauth_credentials:
    - key: carol-key
  - username: eason
    keyauth_credentials:
    - key: eason-key
' | deck gateway apply -

Configure the WeatherAPI MCP tool

In this how-to, we’ll use the WeatherAPI to demonstrate how you can enforce access limits on aggregated MCP servers by configuring it as an MCP tool.

Add an API key using the Request Transformer Advanced plugin

To authenticate to WeatherAPI, configure the Request Transformer Advanced plugin. This plugin automatically appends your API key to the query string so that all requests are authenticated.

echo '
_format_version: "3.0"
plugins:
  - name: request-transformer-advanced
    service: weather-internet-service
    config:
      add:
        querystring:
        - key:${{ env "DECK_WEATHERAPI_API_KEY" }}
' | deck gateway apply -

Configure the AI MCP Proxy plugin for WeatherAPI

Configure the AI MCP Proxy plugin in conversion-only mode to convert the WeatherAPI endpoint into an MCP tool and define access controls. The tags field enables the listener to discover this tool during aggregation. The acl block specifies which Consumer Groups can call this tool.

echo '
_format_version: "3.0"
plugins:
  - name: ai-mcp-proxy
    route: weather-internet-mcp
    tags:
    - ai-gateway-mcp-aggregation
    config:
      mode: conversion-only
      logging:
        log_audits: true
        log_payloads: true
        log_statistics: true
      tools:
      - name: weather-internet
        description: Get current weather for a location
        method: GET
        path: "./v1/current.json"
        acl:
          allow:
          - gold-partner
          - silver-partner
          deny:
          - bronze-partner
        parameters:
        - name: q
          in: query
          required: true
          description: Location query. Accepts US Zipcode, UK Postcode, Canada Postalcode,
            IP address, latitude/longitude, or city name.
          schema:
            type: string
            default: London
' | deck gateway apply -

Configure the Deck of Cards MCP tools

Configure the AI MCP Proxy plugin in conversion-only mode to convert the Deck of Cards API endpoints into MCP tools. Each tool has its own ACL configuration.

echo '
_format_version: "3.0"
plugins:
  - name: ai-mcp-proxy
    route: cards-api-mcp
    tags:
    - ai-gateway-mcp-aggregation
    config:
      mode: conversion-only
      logging:
        log_audits: true
        log_payloads: true
        log_statistics: true
      max_request_body_size: 16384
      tools:
      - name: shuffle-cards
        description: Shuffle a new deck of cards. Returns a deck_id to use with draw-cards.
        method: GET
        path: "/cards-api/new/shuffle/"
        acl:
          allow:
          - gold-partner
          - silver-partner
          deny:
          - bronze-partner
        parameters:
        - name: deck_count
          in: query
          required: false
          description: Number of decks to use (default 1, blackjack typically uses 6)
          schema:
            type: integer
            default: 1
      - name: draw-cards
        description: Draw cards from an existing deck. Requires a deck_id from shuffle-cards.
        method: GET
        path: "/cards-api/{deck_id}/draw/"
        acl:
          allow:
          - gold-partner
          - silver-partner
          deny:
          - bronze-partner
        parameters:
        - name: deck_id
          in: path
          required: true
          description: Deck ID returned from shuffle-cards
          schema:
            type: string
        - name: count
          in: query
          required: true
          description: Number of cards to draw
          schema:
            type: integer
            default: 1
      - name: shuffle-and-draw
        description: Create a new shuffled deck and draw cards in one request.
        method: GET
        path: "./new/draw/"
        acl:
          allow:
          - gold-partner
          - silver-partner
          deny:
          - bronze-partner
        parameters:
        - name: count
          in: query
          required: true
          description: Number of cards to draw
          schema:
            type: integer
            default: 1
' | deck gateway apply -

Configure the listener AI MCP Proxy plugin

Configure the AI MCP Proxy plugin in listener mode to aggregate and expose the tools registered by the conversion-only plugins. The listener discovers tools based on their shared tag value and serves them through an MCP server that AI clients can connect to.

The include_consumer_groups: true setting is essential. Without it, the listener cannot pass Consumer Group membership to the aggregated tools, and ACL rules will not evaluate correctly.

The table below shows the effective permissions for the configuration:

MCP Tool

gold-partner

silver-partner

bronze-partner

No group

weather-internet
shuffle-cards
draw-cards
shuffle-and-draw

The following plugin configuration applies the ACL rules for the MCP tools shown in the table above:

echo '
_format_version: "3.0"
plugins:
  - name: ai-mcp-proxy
    route: mcp-aggregation
    tags:
    - ai-gateway-mcp-aggregation
    config:
      mode: listener
      include_consumer_groups: true
      server:
        tag: ai-gateway-mcp-aggregation
        timeout: 45000
      logging:
        log_audits: true
        log_statistics: true
        log_payloads: true
      max_request_body_size: 32768
' | deck gateway apply -

Validate the configuration

Use ChatWise to validate the ACL configuration. ChatWise is an AI chat client that supports MCP servers. You should’ve already downloaded and installed ChatWise in the prerequisites for this how-to.

Configure ChatWise

  1. In the ChatWise app, navigate to settings.
  2. Click MCP in the sidebar.
  3. Click the + button.
  4. Select “HTTP Server (http)”.
  5. In the Name field, enter aggregated-mcp.
  6. In the URL field, enter http://localhost:8000/mcp/aggregation.
  7. Next to HTTP headers, click +.
  8. In the Key field, enter apikey.
  9. In the Value field, enter alice-key.
  10. Click Verify (View Tools) to confirm the connection. You should see the following tools listed:
    • draw-cards
    • shuffle-and-draw
    • shuffle-cards
    • weather-internet
  11. Close the settings window.

Test tool access

Now verify access for each user by updating the API key in the MCP server settings:

Something wrong?

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!