Plugins et middleware dans l'API Gateway
1) Pourquoi avez-vous besoin de plugins et middleware
API Gateway est le point d'exécution des stratégies d'entreprise. Chaîne de plugins correctement assemblée :- normalise la sécurité (authN/authZ, WAF, CORS),
- protège la durabilité (rate limit, circuit breaker, retry-policy),
- gère le contrat (validation des schémas, transformations),
- donne l'observabilité (métriques, logs, trace),
- réduit les coûts (mise en cache, déduplication, règles canaries).
Clé : latence minimale et séquence d'application claire.
2) Les classes de plugins et ce qu'ils font
1. Identification/authentification
Fournisseurs JWT/JWKS, OAuth2/OIDC, clés API, mTLS (client cert).
Signatures HMAC (webhooks/partenaires), DPoP/PoP à la limite.
2. Autorisation
RBAC/ABAC/OPA/Cedar (PDP) avec cache de solution local.
BOLA-guard : vérifie 'tenant '/' owner' dans les titres/contexte.
3. Protection réseau et protocole
WAF (OWASP CRS), antibot (rate/behavioral), filtres Geo/IP/ASN, profils TLS.
CORS, en-têtes CSP, filtres Fetch-Metadata, CORP/COOPÉRATIVE/COEP.
4. Durabilité
Limitation des taux (token bucket/GCRA), quotas et concurrence.
Circuit breaker, timeouts, concurrency adaptive, load shedding.
Retry-policy avec per-try timeout et gitter.
5. Transformation et validation
Recensement des chemins/en-têtes, body-rewrite, JSON/XML ↔, gRPC ↔ HTTP.
Validation des schémas (OpenAPI/JSON Schema/Protobuf), normalisation de l'ID.
6. Mise en cache et performances
Réponse/fragment cache, ETag/If-None-Match, compression, brotli.
Request collapsing (coalescing) pour les mêmes clés.
7. Observation et audit
Métriques RED/USE, logigation des solutions (429/403/5xx), trace (W3C Trace-Context/OpenTelemetry), sampling (tail/adaptive).
Vérifie les titres de sécurité et les versions des stratégies.
8. Cycle de vie et exploitation
Canary/blue-green, feature-flags, solutions shadow (loger, ne pas appliquer), migration de version.
3) Ordre d'application (chaîne recommandée)
[Ingress TLS]
→ Early-Deny (ASN/Geo, IP allow/deny)
→ mTLS / Client Cert Auth
→ JWT/OAuth2 AuthN (JWKS cache)
→ OPA/ABAC AuthZ (solution cache)
→ Rate Limit / Concurrency
→ Circuit / Timeout / Retries (пер-try)
→ Schema Validation (request)
→ Transform (headers/path/body) / CORS
→ Caching (lookup)
→ Upstream Proxy (app)
← Caching (store) / Compression
← Response Transform / Schema Validation (response)
← Logging / Tracing / Metrics / Security Headers
Principe : avant - moins cher/plus fatal (deny, auth, limites), plus tard - « cosmétique » (transformations, cache).
4) Performance et cardinalité
Suivez O (1) étapes sans requêtes externes dans le chemin chaud.
Tous les « appels externes » des plugins (PDP/JWKS) - via des TTL courts et asynchronous refresh.
Les étiquettes/labels pour les métriques sont une cardinalité limitée ('tenant', 'plan', 'route', mais pas 'user _ id').
Plugins « lourds » (WAF, body-bou) - inclure sélectivement par route.
5) Exemples de configurations
5. 1 Envoy : JWT + RateLimit + OPA + Retraits (pseudo)
yaml static_resources:
listeners:
- name: public_listener filter_chains:
- filters:
- name: envoy. filters. network. http_connection_manager typed_config:
route_config:
name: main virtual_hosts:
- name: api domains: ["api. example. com"]
routes:
- match: { prefix: "/v1/payments" }
route:
cluster: payments timeout: 350ms retry_policy:
retry_on: connect-failure,reset,5xx,gateways num_retries: 1 per_try_timeout: 200ms http_filters:
- name: envoy. filters. http. jwt_authn typed_config:
providers:
oidc:
issuer: https://auth. example. com/
remote_jwks:
http_uri: { uri: https://auth. example. com/.well-known/jwks. json, cluster: jwks, timeout: 2s }
cache_duration: 300s forward: true
- name: envoy. filters. http. ext_authz # OPA/Cedar PDP typed_config:
http_service:
server_uri: { uri: http://opa:8181, cluster: opa, timeout: 50ms }
authorization_request: { allowed_headers: { patterns: [{ exact: "authorization" }, { exact: "x-tenant" }] } }
- name: envoy. filters. http. ratelimit typed_config:
domain: public-api rate_limit_service:
grpc_service: { envoy_grpc: { cluster_name: rl } }
- name: envoy. filters. http. router
5. 2 NGINX/OpenResty : HMAC + Lua + Redis (pseudo)
nginx lua_shared_dict jwks 10m;
lua_shared_dict limits 10m;
server {
listen 443 ssl http2;
Early deny by ASN/Geo if ($bad_asn) { return 403; }
HMAC signature check (webhooks/partners)
set_by_lua_block $sig_ok {
return verify_hmac_signature(ngx. var. http_x_signature, ngx. var. request_time, ngx. var. request_body)
}
if ($sig_ok = 0) { return 401; }
Token bucket in Redis access_by_lua_block {
local key = ngx. var. binary_remote_addr.. ":".. ngx. var. request_uri local allowed, retry_after = ratelimit_allow(key, 50, 100)
if not allowed then ngx. header["Retry-After"] = retry_after return ngx. exit(429)
end
}
proxy_read_timeout 300ms;
proxy_connect_timeout 100ms;
proxy_pass http://app_backend;
}
5. 3 Kong : plugins sur l'itinéraire
yaml services:
- name: payments url: http://payments:8080 routes:
- service: payments paths: ["/v1/payments"]
plugins:
- name: jwt config: { key_claim_name: kid, secret_is_base64: false, run_on_preflight: false }
- name: opa config: { server_url: "http://opa:8181/v1/data/authz/allow", timeout: 50 }
- name: rate-limiting config: { second: 50, policy: redis, redis_host: redis, fault_tolerant: true }
- name: correlation-id config: { header_name: "traceparent" }
- name: response-transformer config: { add: { headers: ["Strict-Transport-Security:max-age=31536000"] } }
5. 4 Apache APISIX: JWT + Limit + Proxy-Mirror (shadow)
yaml routes:
- uri: /v1/wallets/
plugins:
openid-connect:
client_id: wallet discovery: "https://auth. example. com/.well-known/openid-configuration"
scope: "openid"
limit-count:
count: 100 time_window: 60 key_type: "var"
key: "remote_addr"
proxy-mirror: # shadow traffic host: "http://shadow-backend:8080"
upstream_id: 1
5. 5 Traefik : La chaîne Middleware
yaml http:
middlewares:
hsts-headers:
headers:
stsSeconds: 31536000 stsIncludeSubdomains: true ratelimit:
rateLimit:
average: 50 burst: 100 routers:
api:
rule: "Host(`api. example. com`) && PathPrefix(`/v1`)"
service: app middlewares:
- hsts-headers
- ratelimit
6) Polyvalence et versions des politiques
Clé de routage : '{tenant, plan, région, route, version}'.
Les plugins lisent 'tenant' de mTLS SAN/JWT-marque/en-tête → appliquent des limites/quotas/règles per-tenant.
Versez les stratégies ('policy _ version'), changez les règles et faites des rollout canariens.
7) Test et rollout
Avant la sortie
Tests contractuels de la chaîne (tableau « si ») : auth→deny, auth→allow, rate→429, schema→422.
Charge : Burst × 10, plateaux longs, modèles « sales » (slow-POST).
Chaos : dégradation PDP/JWKS/Redis - doit être fail-closed/dégradation à un minimum de sécurité.
Sortie
'Report-Only '/shadow-mode (nous logions les solutions sans application).
Canary 1-5 % du trafic + comparaison des métriques (p95/p99, 4xx/5xx/429).
Rollback automatique par SLO/alerts.
8) Observabilité et métriques
Métriques :- `http_requests_total{route,tenant,plan,status}`
- `request_duration_seconds_bucket{route}` (p95/p99)
- `rate_limited_total{policy}`, `retry_total{reason}`, `circuit_state`
- `authn_fail_total{reason}`, `authz_denied_total{action}`
- `schema_validation_fail_total{route}`
- Traces : spans per-filter, attributs 'policy _ version', 'tenant', 'limit _ key'.
- Logs (en sample) : solutions deny/429/5xx avec causes et "trace _ id'.
- Dashboards : Exec-résumé, per-route, per-tenant, politiciens « chauds ».
9) Sécurité et exploitation
Tous les secrets (HMAC, JWKS privé, clés API) sont dans KMS/Vault, pas dans les fichiers config.
Politique deny-by-default pour les itinéraires sensibles.
Court TTL JWKS/cache PDP, mises à jour asynchrones avec backoff.
Migration des schémas de transformation - convertie ; « cassant » - via dual-write.
Limitez le body-size (DoS) et la profondeur JSON.
10) Anti-modèles
L'ensemble universel de plugins tout compris sur chaque itinéraire → des millisecondes et des factures supplémentaires.
Les dépendances externes des plugins sans cache/temporisation → les temporisations en cascade.
Absence d'ordre des filtres : d'abord transformation/logique, puis limites - incorrect.
La cardinalité élevée des étiquettes métriques (raw 'user _ id '/' ip').
Mélange authN/authZ dans des modèles de transformation (solutions implicites dans Lua/Jinja).
Logage des secrets/tokens.
Un Redis/cluster global pour toutes les limites sans chardage/réserve.
11) Spécificités d'iGaming/Finance
Règles de compétence/de compétence du père : KYC/AML, sanctions, limites de paiement responsables.
Politiques strictes pour les itinéraires de paiement : brefs délais, une répétition, idempotence ('Idempotency-Key').
Séparation des périmètres pour le SDK PSP/KYC (domaines individuels/chaînes de plugins).
Audit des logs de décision immuables (conclusions, blocages, refus de sanction).
12) Chèque-liste prod-prêt
- L'ordre des filtres est défini : authN → authZ → limites → circuit/timeout → schema → bou → cache.
- Ensemble de plugins d'itinéraire ; lourd - seulement là où il faut.
- JWKS/PDP avec TTL et cache courts ; taymauth et stratégie fallback.
- Taux/Quota/Concurrency - clés conçues, stockage de chardonnages.
- Jeu de métriques RED/USE, trace OTel, sampling tail/adaptive.
- Mode Canary + shadow, auto-rollback par SLO.
- Secrets dans KMS/Vault ; les configi sont versionnables, avec des migrations.
- Limites de body/headers ; protection contre l'oversize/slow-POST.
- Documentation pour les clients : codes 401/403/409/422/429/5xx, « Retry-After », exemples de titres.
13) TL; DR
Construisez la chaîne « Échec précoce → authentification/autorisation → limites/stabilité → validation → transformation/cache → télémétrie ». Activez uniquement les plugins per-route nécessaires, mettez en cache les solutions externes (JWKS/PDP), définissez les délais et les stratégies de retri, contrôlez la cardinalité des métriques. Release via shadow/canary, garder des secrets dans KMS/Vault et mesurer l'impact de chaque plugin sur p95/p99.