Skip to main content

Overview

Kong Gateway acts as an API gateway providing authentication, rate limiting, traffic control, and observability for the MCP Server with LangGraph. This reference documents all Kong plugins used in the deployment.

Authentication

JWT, API Key, and custom authentication plugins

Rate Limiting

Tiered rate limiting for fair usage and DDoS protection

Traffic Control

CORS, request transformation, and size limiting

Authentication Plugins

JWT Authentication

Validates JSON Web Tokens issued by Keycloak for secure API access. Plugin: jwt Resource: jwt-auth
Configuration:
  • uri_param_names: Accept JWT from ?jwt=... query parameter
  • cookie_names: Accept JWT from jwt cookie
  • claims_to_verify: Verify exp (expiration) claim
  • maximum_expiration: Maximum token lifetime (24 hours)
  • key_claim_name: Use iss (issuer) claim to identify key
Usage:
Token Validation:
  1. Verifies signature using Keycloak’s public key (JWKS)
  2. Checks expiration claim (exp)
  3. Validates issuer matches configured realm
  4. Extracts user identity from sub claim

API Key Authentication

Legacy authentication method using long-lived API keys. Plugin: key-auth Resource: api-key-auth
Configuration:
  • key_names: Accept keys from apikey or x-api-key headers
  • key_in_body: Don’t accept keys in request body
  • hide_credentials: Remove key header before proxying to backend
Usage:
This plugin is typically used with the API Key JWT Exchange custom plugin to convert API keys to JWTs.

API Key JWT Exchange (Custom Plugin)

Custom Kong plugin that exchanges API keys for JWTs, enabling legacy authentication while maintaining JWT standardization. Plugin: kong-apikey-jwt-exchange (custom) Resource: apikey-jwt-exchange
Configuration:
  • mcp_server_url: MCP Server endpoint for API key validation
  • cache_ttl: JWT cache duration (5 minutes recommended)
  • timeout: Request timeout for key validation
  • api_key_headers: Headers to check for API keys
Flow:
1

Client sends API key

Request includes apikey header with API key
2

Plugin validates key

Kong plugin sends key to MCP Server for validation
3

MCP Server returns JWT

If valid, MCP Server returns a JWT token
4

Plugin caches JWT

JWT is cached for cache_ttl seconds
5

Plugin forwards request

Request is forwarded to backend with Authorization: Bearer JWT header
Benefits:
  • Maintains JWT standardization across all requests
  • Backward compatibility for legacy API key clients
  • Caching reduces load on MCP Server
  • Transparent to backend services
Related ADR:

Rate Limiting Plugins

Basic Rate Limiting

Default rate limiting for all users with local policy (no Redis required). Plugin: rate-limiting Resource: rate-limit-basic
Limits:
  • Per minute: 60 requests
  • Per hour: 1,000 requests
  • Policy: Local (in-memory, no shared state)
  • Fault tolerant: Allow requests if counter fails
Response Headers:

Premium Tier Rate Limiting

Higher limits for premium users with Redis-backed synchronization across Kong instances. Plugin: rate-limiting Resource: rate-limit-premium
Limits:
  • Per minute: 300 requests
  • Per hour: 10,000 requests
  • Policy: Redis (shared across Kong instances)
  • Fault tolerant: Allow if Redis unavailable

Enterprise Tier Rate Limiting

Very high limits for enterprise customers. Plugin: rate-limiting Resource: rate-limit-enterprise
Limits:
  • Per minute: 1,000 requests
  • Per hour: 100,000 requests

Advanced Rate Limiting

Consumer group-based rate limiting with sliding windows. Plugin: rate-limiting-advanced (Kong Enterprise) Resource: rate-limit-advanced
Features:
  • Sliding window: More accurate rate limiting than fixed windows
  • Consumer groups: Different limits per user tier
  • Sync rate: Synchronize counters across instances every 10 seconds
  • Redis strategy: Distributed rate limiting
Consumer Group Limits:
Requires Kong Enterprise. Use standard rate-limiting plugin for open-source Kong.

Response Rate Limiting

Limits based on response tokens/data for streaming endpoints. Plugin: response-ratelimiting Resource: response-ratelimit
Limits:
  • Tokens per minute: 50,000
  • Tokens per hour: 1,000,000
Use Case: Prevent excessive LLM token usage by limiting based on actual tokens returned in responses rather than request count. Backend Header: The MCP Server must return:
Kong accumulates these values and enforces limits.

Traffic Control Plugins

CORS (Cross-Origin Resource Sharing)

Enables cross-origin requests from web applications. Plugin: cors Resource: cors
Configuration:
  • origins: Allow all origins (*). Restrict in production (e.g., https://app.example.com)
  • methods: Allowed HTTP methods
  • headers: Allowed request headers
  • exposed_headers: Headers visible to JavaScript
  • credentials: Allow cookies and authentication
  • max_age: Cache preflight response for 1 hour
Preflight Response:
Using origins: ["*"] with credentials: true is a security risk. Always specify explicit origins in production.

Request Size Limiting

Prevents oversized payloads that could cause memory issues or DDoS. Plugin: request-size-limiting Resource: request-size-limit
Configuration:
  • allowed_payload_size: 10 MB maximum
  • size_unit: megabytes (or kilobytes, bytes)
  • require_content_length: Allow streaming uploads without Content-Length
Error Response:

Request Transformer

Adds, modifies, or removes headers and query parameters. Plugin: request-transformer Resource: request-transformer
Operations:
  • Add headers: Inject request ID and protocol
  • Remove headers: Strip legacy headers
Variables:
  • $(uuid): Generate UUID
  • $(upstream_uri): Upstream request URI
  • $(consumer_username): Authenticated consumer username
Example Use Cases:
  • Add correlation IDs for distributed tracing
  • Inject environment/version headers
  • Remove sensitive headers before proxying
  • Add authentication context headers

Security Plugins

IP Restriction

Whitelist or blacklist IP addresses/ranges. Plugin: ip-restriction Resource: ip-restriction
Configuration:
  • allow: Whitelist mode - only these IPs allowed
  • deny: Blacklist mode - these IPs blocked
Cannot use both allow and deny simultaneously. Choose one mode.
Use Cases:
  • Restrict admin endpoints to VPN/office IPs
  • Block abusive IP addresses
  • Geo-restriction (with GeoIP database)
  • Corporate network-only access

Bot Detection

Detects and blocks automated bots and scrapers. Plugin: bot-detection Resource: bot-detection
Configuration:
  • allow: Whitelist specific bots (SEO crawlers)
  • deny: Block specific user agents
Detection Method: Examines User-Agent header for known bot patterns. Blocked Response:
Sophisticated bots can spoof User-Agent headers. Consider additional protection like CAPTCHA or rate limiting.

Request Termination

Circuit breaker for maintenance mode or emergency shutdowns. Plugin: request-termination Resource: request-termination
Configuration:
  • status_code: HTTP status to return (503 Service Unavailable)
  • message: Custom error message
  • disabled: Plugin disabled by default
Enable for Maintenance:
Disable After Maintenance:

Observability Plugins

Prometheus Metrics

Exports metrics for Prometheus scraping. Plugin: prometheus Resource: prometheus
Metrics Endpoint:
Exported Metrics:
  • kong_http_requests_total: Total HTTP requests
  • kong_latency_ms: Request latency histogram
  • kong_bandwidth_bytes: Bandwidth usage
  • kong_datastore_reachable: Datastore health
  • kong_nginx_connections_*: NGINX connection stats
per_consumer: true: Breaks down metrics by authenticated consumer:
Prometheus Scrape Config:

HTTP Log

Sends request/response logs to external endpoint (e.g., Logstash, Elasticsearch). Plugin: http-log Resource: http-log
Configuration:
  • http_endpoint: Logstash/Elasticsearch endpoint
  • method: HTTP method (POST recommended)
  • timeout: Request timeout (10s)
  • flush_timeout: Batch logs every 2 seconds
  • retry_count: Retry failed sends 10 times
  • queue_size: Buffer 1000 log entries
Log Format:

Plugin Chaining

Plugins are executed in a specific order. Understanding the order is crucial for correct behavior.

Execution Order

1

1. Certificate (TLS Handshake)

SSL/TLS termination
2

2. Rewrite

Request transformer, IP restriction
3

3. Access (Before Authentication)

Bot detection, CORS (preflight)
4

4. Authentication

JWT, API key, API key→JWT exchange
5

5. Access (After Authentication)

Rate limiting, request size limiting
6

6. Header Filter

Add/remove headers
7

7. Response

Response transformer
8

8. Log

Prometheus, HTTP log

Example Plugin Chain

For a typical authenticated API request:
Execution:
  1. CORS: Handle OPTIONS preflight
  2. jwt-auth: Validate JWT token
  3. rate-limit-premium: Check rate limits
  4. request-size-limit: Validate payload size
  5. request-transformer: Add correlation ID
  6. [Proxy to backend]
  7. prometheus: Record metrics
  8. http-log: Send audit log

Best Practices

Rate Limiting

  • Use Redis-backed policies for multi-instance deployments
  • Set fault_tolerant: true to allow requests if Redis fails
  • Don’t hide rate limit headers - clients need them
  • Monitor rate limit violations in Prometheus

Authentication

  • Always use HTTPS in production
  • Rotate JWKS keys regularly (Kong JWKS updater CronJob)
  • Cache JWT validation results to reduce latency
  • Use API key→JWT exchange for backward compatibility

CORS

  • Never use origins: ["*"] with credentials: true
  • Specify explicit allowed origins in production
  • Keep max_age high (1 hour) to reduce preflight requests
  • Expose only necessary headers

Observability

  • Enable Prometheus for all routes
  • Use HTTP log for audit trails
  • Include per_consumer: true for user-level metrics
  • Monitor Kong’s own metrics (/status endpoint)

Troubleshooting

Symptoms: 401 Unauthorized with JWT errorSolutions:
  • Verify JWKS is up-to-date: kubectl logs job/kong-jwks-updater
  • Check token expiration: Decode JWT at jwt.io
  • Verify issuer matches: Token iss must match Kong consumer config
  • Run manual JWKS update: kubectl create job --from=cronjob/kong-jwks-updater manual
Symptoms: No rate limit headers or limits not enforcedSolutions:
  • Check Redis connectivity: kubectl exec -it redis -- redis-cli ping
  • Verify plugin is applied: kubectl get kongplugin -n mcp-server-langgraph
  • Check Ingress annotations: kubectl describe ingress mcp-api
  • Review Kong logs: kubectl logs -n kong deployment/kong-gateway
Symptoms: Access-Control-Allow-Origin errors in consoleSolutions:
  • Add actual origin to origins list (not * with credentials)
  • Verify credentials: true if using cookies/auth
  • Check exposed_headers includes needed headers
  • Ensure OPTIONS method is in methods list
Symptoms: Kong returns 500 error or plugin not foundSolutions:
  • Verify plugin is installed in Kong image
  • Check KONG_PLUGINS env includes custom plugin name
  • Review plugin syntax: kubectl logs kong-gateway | grep "plugin"
  • Ensure plugin is in correct directory: /usr/local/share/lua/5.1/kong/plugins/

See Also