🚪 API Gateway

api-gateway-kong-api-gateway

Configuration de Kong API Gateway — services, routes, plugins, rate limiting, authentification et monitoring.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- api-gateway-kong-api-gateway --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } api-gateway-kong-api-gateway -Launch"

🚀 Déjà installé ?

claude "/api-gateway-kong-api-gateway"

Ou tapez /api-gateway-kong-api-gateway dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

KongKong GatewayKong pluginKong routeAPI gateway Kongkong.ymlKong declarative

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/api-gateway-kong-api-gateway ~/.claude/skills/

Payload du plugin : skills/api-gateway-kong-api-gateway · source éditable : api-gateway-skills/kong-api-gateway

📖 Manuel

Kong API Gateway

Workflow en 6 étapes

1. Choisir le mode de déploiement

CritèreDB-less (declarative)DB (PostgreSQL)
Environnement immutable / GitOpsOuiNon
Portail dev, plugins KonnectCINonOui
Multi-noeud avec sync dynamiqueNonOui
Démarrage simple (Docker, K8s)OuiNon

Règle : choisir DB-less par défaut. Passer en mode DB uniquement si Kong Manager, Konnect, ou des plugins enterprise nécessitent une base.

2. Écrire le kong.yml (DB-less)

_format_version: "3.0"
_transform: true   # permet d'utiliser des urls courtes (http://host:port)

services:
  - name: payment-service
    url: http://payment-api:8080
    connect_timeout: 5000
    write_timeout: 60000
    read_timeout: 60000
    retries: 3
    routes:
      - name: payment-route
        paths:
          - /api/payments
        methods: [GET, POST, PUT, DELETE]
        strip_path: true
        preserve_host: false
    plugins:
      - name: rate-limiting
        config:
          minute: 100
          policy: redis
          redis_host: redis
          redis_port: 6379
      - name: jwt
        config:
          claims_to_verify: [exp]
          key_claim_name: kid

  - name: order-service
    url: http://order-api:8080
    routes:
      - name: order-route
        paths: [/api/orders]
        strip_path: true
    plugins:
      - name: rate-limiting
        config:
          minute: 200
          policy: local          # local si pas de Redis, attention au multi-noeud
      - name: cors
        config:
          origins: [https://app.company.com]
          methods: [GET, POST, OPTIONS]
          headers: [Authorization, Content-Type]
          exposed_headers: [X-Request-ID]
          credentials: true
          max_age: 3600

# Consumers (pour JWT / Key Auth)
consumers:
  - username: mobile-app
    jwt_secrets:
      - key: mobile-app-key
        algorithm: RS256
        rsa_public_key: |
          -----BEGIN PUBLIC KEY-----
          ...
          -----END PUBLIC KEY-----

# Plugins globaux (s'appliquent à toutes les routes)
plugins:
  - name: prometheus
    config:
      per_consumer: true
      status_code_metrics: true
      latency_metrics: true
  - name: correlation-id
    config:
      header_name: X-Request-ID
      generator: uuid#counter
      echo_downstream: true
  - name: http-log
    config:
      http_endpoint: http://log-aggregator:5044
      timeout: 1000
      keepalive: 60000

3. Valider et appliquer la configuration

# Valider la syntaxe AVANT de déployer
kong config parse kong.yml

# DB-less : rechargement à chaud via Admin API (pas de downtime)
curl -sX POST http://localhost:8001/config \
  -F config=@kong.yml

# DB : import initial
kong config db_import kong.yml

# Vérifier l'état après rechargement
curl -s http://localhost:8001/status | jq .

4. Démarrer Kong (Docker Compose)

services:
  kong:
    image: kong:3.9          # version LTS 2026
    environment:
      KONG_DATABASE: "off"
      KONG_DECLARATIVE_CONFIG: /etc/kong/kong.yml
      KONG_PROXY_LISTEN: "0.0.0.0:8000, 0.0.0.0:8443 ssl"
      KONG_ADMIN_LISTEN: "127.0.0.1:8001"   # jamais 0.0.0.0 en prod
      KONG_LOG_LEVEL: warn
      KONG_NGINX_WORKER_PROCESSES: auto
      KONG_PLUGINS: bundled              # ou liste explicite
    ports:
      - "8000:8000"    # HTTP proxy
      - "8443:8443"    # HTTPS proxy
    volumes:
      - ./kong.yml:/etc/kong/kong.yml:ro
    healthcheck:
      test: ["CMD", "kong", "health"]
      interval: 10s
      timeout: 5s
      retries: 3

  # Redis pour rate-limiting distribué (multi-noeud obligatoire)
  redis:
    image: redis:7-alpine
    command: redis-server --save "" --appendonly no

5. Opérations courantes via Admin API

# Lister / inspecter
curl -s http://localhost:8001/services | jq '.data[].name'
curl -s http://localhost:8001/routes   | jq '.data[] | {name, paths}'
curl -s http://localhost:8001/plugins  | jq '.data[] | {name, enabled}'

# Désactiver un plugin à chaud (sans redémarrage)
PLUGIN_ID=$(curl -s http://localhost:8001/plugins?name=jwt | jq -r '.data[0].id')
curl -sX PATCH http://localhost:8001/plugins/$PLUGIN_ID \
  -d enabled=false

# Tester une route (proxy sur port 8000)
curl -sI -H "Authorization: Bearer <token>" http://localhost:8000/api/payments

# Recharger la config sans downtime (DB-less)
curl -sX POST http://localhost:8001/config -F config=@kong.yml | jq .

6. Monitoring et observabilité

# Métriques Prometheus (scraper sur :8001/metrics)
curl -s http://localhost:8001/metrics | grep kong_http

# Règle Prometheus à ajouter dans prometheus.yml :
# - job_name: kong
#   static_configs:
#     - targets: ['kong:8001']

# Grafana dashboard ID officiel Kong : 7424

Plugins essentiels — tableau de décision

PluginQuand l'utiliserScope recommandé
rate-limitingToutes les routes publiquesPar route (sinon trop permissif)
rate-limiting-advancedFenêtres glissantes, quotas par consumerPar route / consumer
jwtAuth stateless, microservicesPar route
oauth2Auth déléguée, portail devPar service
key-authAPI B2B simple, M2MPar route
aclRestriction par groupe après authAprès jwt/key-auth
corsAPIs consommées depuis un browserPar route
ip-restrictionWhitelist/blacklist CIDRsPar route/service
request-transformerAjouter/supprimer headers avant upstreamPar route
response-transformerMasquer headers internesPar route
prometheusMétriques latence, codes HTTPGlobal
correlation-idTraçabilité distribuéeGlobal (toujours)
http-log / file-logCentralisation des logsGlobal ou par service
proxy-cacheRéduire la charge upstream (GET)Par route
bot-detectionBloquer les crawlers/botsGlobal

Anti-patterns et pièges

Rate limiting sans Redis en multi-noeud : policy: local compte par noeud Kong, pas globalement. Avec 3 réplicas, un client peut envoyer 3× le quota. Toujours utiliser policy: redis dès qu'il y a plus d'une instance.

Admin API exposée publiquement : KONG_ADMIN_LISTEN: 0.0.0.0:8001 est une faille critique. Restreindre à 127.0.0.1 ou un réseau interne, puis protéger avec ip-restriction ou mTLS.

**Plugin cors avec origins: ["*"] et credentials: true** : combinaison invalide côté navigateur (CORS spec). Toujours lister les origines explicitement si credentials: true.

strip_path mal configuré : si strip_path: false et que le service upstream ne s'attend pas au préfixe /api/payments, toutes les requêtes retournent 404. Valider avec curl -v.

Order des plugins : Kong applique les plugins dans l'ordre de priorité interne (pas l'ordre du YAML). Vérifier avec GET /plugins?size=100 pour confirmer que jwt s'exécute avant acl.

Timeouts trop courts sur des endpoints batch : read_timeout: 60000 (60 s) par défaut. Pour des imports lourds, augmenter explicitement par route avec config.read_timeout dans le plugin request-termination ou via un service dédié.

Rechargement DB-less sans validation préalable : POST /config sans kong config parse peut corrompre l'état en mémoire si le YAML est invalide. Toujours valider d'abord.

Bonnes pratiques 2026