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
- uri_param_names: Accept JWT from
?jwt=...query parameter - cookie_names: Accept JWT from
jwtcookie - claims_to_verify: Verify
exp(expiration) claim - maximum_expiration: Maximum token lifetime (24 hours)
- key_claim_name: Use
iss(issuer) claim to identify key
- Verifies signature using Keycloak’s public key (JWKS)
- Checks expiration claim (
exp) - Validates issuer matches configured realm
- Extracts user identity from
subclaim
API Key Authentication
Legacy authentication method using long-lived API keys. Plugin:key-auth
Resource: api-key-auth
- key_names: Accept keys from
apikeyorx-api-keyheaders - key_in_body: Don’t accept keys in request body
- hide_credentials: Remove key header before proxying to backend
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
- 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
1
Client sends API key
Request includes
apikey header with API key2
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 seconds5
Plugin forwards request
Request is forwarded to backend with
Authorization: Bearer JWT header- Maintains JWT standardization across all requests
- Backward compatibility for legacy API key clients
- Caching reduces load on MCP Server
- Transparent to backend services
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
- Per minute: 60 requests
- Per hour: 1,000 requests
- Policy: Local (in-memory, no shared state)
- Fault tolerant: Allow requests if counter fails
Premium Tier Rate Limiting
Higher limits for premium users with Redis-backed synchronization across Kong instances. Plugin:rate-limiting
Resource: rate-limit-premium
- 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
- 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
- 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
| Tier | Requests/Minute |
|---|---|
| Free | 10 |
| Premium | 100 |
| Enterprise | 1,000 |
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
- Tokens per minute: 50,000
- Tokens per hour: 1,000,000
Traffic Control Plugins
CORS (Cross-Origin Resource Sharing)
Enables cross-origin requests from web applications. Plugin:cors
Resource: cors
- 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
Request Size Limiting
Prevents oversized payloads that could cause memory issues or DDoS. Plugin:request-size-limiting
Resource: request-size-limit
- allowed_payload_size: 10 MB maximum
- size_unit: megabytes (or kilobytes, bytes)
- require_content_length: Allow streaming uploads without
Content-Length
Request Transformer
Adds, modifies, or removes headers and query parameters. Plugin:request-transformer
Resource: request-transformer
- Add headers: Inject request ID and protocol
- Remove headers: Strip legacy headers
$(uuid): Generate UUID$(upstream_uri): Upstream request URI$(consumer_username): Authenticated consumer username
- 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
- allow: Whitelist mode - only these IPs allowed
- deny: Blacklist mode - these IPs blocked
- 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
- allow: Whitelist specific bots (SEO crawlers)
- deny: Block specific user agents
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
- status_code: HTTP status to return (503 Service Unavailable)
- message: Custom error message
- disabled: Plugin disabled by default
Observability Plugins
Prometheus Metrics
Exports metrics for Prometheus scraping. Plugin:prometheus
Resource: prometheus
kong_http_requests_total: Total HTTP requestskong_latency_ms: Request latency histogramkong_bandwidth_bytes: Bandwidth usagekong_datastore_reachable: Datastore healthkong_nginx_connections_*: NGINX connection stats
HTTP Log
Sends request/response logs to external endpoint (e.g., Logstash, Elasticsearch). Plugin:http-log
Resource: http-log
- 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
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:- CORS: Handle OPTIONS preflight
- jwt-auth: Validate JWT token
- rate-limit-premium: Check rate limits
- request-size-limit: Validate payload size
- request-transformer: Add correlation ID
- [Proxy to backend]
- prometheus: Record metrics
- http-log: Send audit log
Best Practices
Rate Limiting
- Use Redis-backed policies for multi-instance deployments
- Set
fault_tolerant: trueto 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: ["*"]withcredentials: true - Specify explicit allowed origins in production
- Keep
max_agehigh (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: truefor user-level metrics - Monitor Kong’s own metrics (
/statusendpoint)
Troubleshooting
JWT Validation Failing
JWT Validation Failing
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
issmust match Kong consumer config - Run manual JWKS update:
kubectl create job --from=cronjob/kong-jwks-updater manual
Rate Limiting Not Working
Rate Limiting Not Working
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
CORS Errors in Browser
CORS Errors in Browser
Symptoms:
Access-Control-Allow-Origin errors in consoleSolutions:- Add actual origin to
originslist (not*with credentials) - Verify
credentials: trueif using cookies/auth - Check
exposed_headersincludes needed headers - Ensure OPTIONS method is in
methodslist
Custom Plugin Not Loading
Custom Plugin Not Loading
Symptoms: Kong returns 500 error or plugin not foundSolutions:
- Verify plugin is installed in Kong image
- Check
KONG_PLUGINSenv 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/