Skip to Content

Limitation de Débit

Auris applique des limites de débit sur tous les endpoints API pour protéger la plateforme des abus, prévenir les attaques de credential stuffing et garantir une allocation équitable des ressources entre les tenants. Ce guide explique les niveaux de limitation de débit, comment lire les headers de limites, comment gérer les réponses 429 Too Many Requests dans ton application et comment configurer les limites.

Niveaux de Limitation de Débit

Auris applique des limites de débit différentes selon la sensibilité et le coût des ressources de chaque endpoint. Il y a quatre niveaux :

Niveau Auth (Strict)

S’applique aux endpoints d’authentification qui gèrent les credentials :

  • POST /api/auth/login (connexion email/mot de passe)
  • POST /api/auth/signup (inscription utilisateur)
  • POST /api/auth/token (échange et refresh de tokens)
  • POST /api/auth/magic-link (démarrage magic link)
  • POST /api/auth/passwordless/* (flux passwordless)
  • POST /api/oauth/authenticate (soumission formulaire connexion hébergée)

Ces endpoints ont les limites les plus restrictives car ils sont la cible principale des attaques de credential stuffing et brute-force.

Limites par défaut : Quelques requêtes par minute par IP, avec des limites supplémentaires par compte sur les endpoints de connexion.

Niveau Sensitive (Modéré)

S’applique aux opérations critiques pour la sécurité qui ne devraient pas être appelées fréquemment :

  • POST /api/user/2fa/* (inscription et vérification 2FA)
  • POST /api/auth/forgot-password (démarrage reset mot de passe)
  • POST /api/auth/change-password (changement de mot de passe)
  • POST /api/user/phone/* (vérification numéro de téléphone)

Limites par défaut : Requêtes modérées par minute par IP et par utilisateur.

Niveau API (Standard)

S’applique aux endpoints API authentifiés généraux :

  • GET/POST/PATCH/DELETE /api/users/*
  • GET/POST/PATCH/DELETE /api/roles/*
  • GET/POST/PATCH/DELETE /api/organizations/*
  • GET/POST/PATCH/DELETE /api/applications/*
  • Tous les autres endpoints CRUD authentifiés

Limites par défaut : Requêtes standard par minute par utilisateur authentifié.

Niveau Public (Souple)

S’applique aux endpoints ouverts qui ne nécessitent pas d’authentification :

  • GET /.well-known/openid-configuration (OIDC Discovery)
  • GET /.well-known/jwks.json (JWKS)
  • GET /api/public/* (pages de statut public, pages de vérification)
  • POST /api/scim/v2/* (provisioning SCIM avec bearer token)

Limites par défaut : Limites généreuses, basées uniquement sur l’IP.

Lecture des Headers de Limitation de Débit

Chaque réponse depuis un endpoint avec limitation de débit inclut des headers standard indiquant l’état actuel de la fenêtre de limitation :

HeaderTypeDescription
X-RateLimit-LimitEntierNombre maximum de requêtes autorisées dans la fenêtre courante
X-RateLimit-RemainingEntierNombre de requêtes restantes avant d’atteindre la limite
X-RateLimit-ResetTimestamp UnixQuand la fenêtre courante se réinitialise (secondes depuis l’epoch)
Retry-AfterEntierSecondes avant de pouvoir réessayer (présent uniquement dans les réponses 429)

Exemple de headers de réponse sur une requête réussie :

HTTP/1.1 200 OK X-RateLimit-Limit: 100 X-RateLimit-Remaining: 87 X-RateLimit-Reset: 1737014400 Content-Type: application/json

Exemple de headers quand la limite de débit est atteinte :

HTTP/1.1 429 Too Many Requests X-RateLimit-Limit: 100 X-RateLimit-Remaining: 0 X-RateLimit-Reset: 1737014400 Retry-After: 47 Content-Type: application/json { "ok": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Trop de requêtes. Réessaie dans 47 secondes." } }

Gestion des Réponses 429

Quand ton application reçoit une réponse 429 Too Many Requests, elle devrait effectuer un backoff et réessayer après le délai spécifié dans le header Retry-After.

Retry de Base avec Backoff

async function callAurisApi( url: string, options: RequestInit, maxRetries = 3 ): Promise<Response> { for (let attempt = 0; attempt <= maxRetries; attempt++) { const response = await fetch(url, options) if (response.status !== 429) { return response } // Lire le header Retry-After const retryAfter = parseInt(response.headers.get('Retry-After') || '60', 10) if (attempt === maxRetries) { throw new Error( `Rate limité après ${maxRetries} tentatives. Réessaie dans ${retryAfter}s.` ) } console.warn( `Rate limité (tentative ${attempt + 1}/${maxRetries}). ` + `Nouvelle tentative dans ${retryAfter} secondes...` ) await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000)) } throw new Error('Inattendu : boucle de retry épuisée') }

Backoff Exponentiel avec Jitter

Pour les systèmes de production à fort trafic, utilise le backoff exponentiel avec jitter pour éviter les problèmes de “thundering herd” quand plusieurs clients atteignent les limites simultanément :

async function callWithExponentialBackoff( url: string, options: RequestInit, maxRetries = 5 ): Promise<Response> { for (let attempt = 0; attempt <= maxRetries; attempt++) { const response = await fetch(url, options) if (response.status !== 429) { return response } if (attempt === maxRetries) { throw new Error('Limite de débit dépassée : tentatives maximales atteintes') } const retryAfter = response.headers.get('Retry-After') let delay: number if (retryAfter) { delay = parseInt(retryAfter, 10) * 1000 } else { // Backoff exponentiel : 1s, 2s, 4s, 8s, 16s const baseDelay = Math.pow(2, attempt) * 1000 const jitter = Math.random() * baseDelay * 0.5 delay = baseDelay + jitter } await new Promise((resolve) => setTimeout(resolve, delay)) } throw new Error('Inattendu : boucle de retry épuisée') }

Pattern Circuit Breaker

Pour les applications qui effectuent de nombreux appels API, implémente un circuit breaker pour arrêter complètement d’envoyer des requêtes quand les limites de débit sont atteintes de façon constante :

class AurisCircuitBreaker { private failureCount = 0 private lastFailure = 0 private state: 'closed' | 'open' | 'half-open' = 'closed' private readonly threshold = 5 private readonly resetTimeout = 60000 // 1 minute async call(fn: () => Promise<Response>): Promise<Response> { if (this.state === 'open') { if (Date.now() - this.lastFailure > this.resetTimeout) { this.state = 'half-open' } else { throw new Error('Circuit breaker ouvert. Requêtes en pause.') } } const response = await fn() if (response.status === 429) { this.failureCount++ this.lastFailure = Date.now() if (this.failureCount >= this.threshold) { this.state = 'open' console.error( `Circuit breaker ouvert après ${this.threshold} limites de débit atteintes. ` + `Pause des requêtes pour ${this.resetTimeout / 1000}s.` ) } throw new Error('Rate limité') } // Succès — réinitialise le breaker this.failureCount = 0 this.state = 'closed' return response } }

Limites Par Compte sur les Endpoints Auth

En plus des limites de débit basées sur l’IP, les endpoints d’authentification appliquent des limites par compte qui fonctionnent en combinaison avec le système de protection brute-force :

SeuilAction
Connexions consécutives échouées dans la fenêtre d’observationCompteur incrémenté
Le compteur atteint le seuil de blocage (défaut : 5)Compte bloqué pour une durée croissante
1er blocage5 minutes
2ème blocage30 minutes
3ème blocage24 heures

Ces limites sont par compte utilisateur et persistent entre les adresses IP. Une attaque distribuée depuis plusieurs IP contre le même compte déclenche quand même le blocage.

Le blocage par compte est séparé de la limitation de débit basée sur l’IP. Une seule IP peut être rate-limitée tandis que le compte cible reste débloqué (si le compteur d’échecs n’a pas atteint le seuil), et vice versa.

Consulte le guide Protection contre les Attaques pour les détails complets sur la configuration de la protection brute-force.

Comportement de Retry Automatique du SDK

Le SDK @auris/js inclut une gestion intégrée des limites de débit pour les opérations sur les tokens :

  • Refresh token : Si une demande de refresh token reçoit un 429, le SDK attend la durée Retry-After et réessaie une fois automatiquement
  • Redirects de connexion : Le flux de connexion hébergée est rendu côté serveur et n’est pas soumis aux limites de débit côté client
  • Appels API via client Management : Le client Management ne réessaie pas automatiquement — ton application devrait implémenter la logique de retry
import { AurisClient } from '@auris/js' const auris = new AurisClient({ domain: 'auth.votreentreprise.com', clientId: 'votre-client-id', autoRefresh: true, // Le SDK gère le refresh avec retry intégré }) // Le retry du refresh token est automatique const token = await auris.getAccessToken()

Pour le client Management (M2M), implémente ta propre logique de retry :

import { AurisClient } from '@auris/js' const management = new AurisClient.Management({ domain: 'auth.votreentreprise.com', clientId: 'm2m-client-id', clientSecret: 'm2m-client-secret', }) // Les appels au client Management devraient utiliser ton wrapper de retry const users = await callWithExponentialBackoff( 'https://auth.votreentreprise.com/api/users', { headers: { Authorization: `Bearer ${await management.getToken()}`, 'x-tenant': 'votre-tenant-id', }, } )

Configuration dans la Console

Les paramètres de limitation de débit sont visibles dans la Console Auris sous Paramètres puis Limitation de Débit. La Console affiche la configuration actuelle pour chaque niveau en lecture seule.

Les paramètres affichés incluent :

  • Limites par niveau — Requêtes par fenêtre pour chaque niveau (auth, sensitive, api, public)
  • Durée de la fenêtre — La taille de la fenêtre glissante pour chaque niveau
  • État actuel — Si la limitation de débit est active

Les valeurs de limitation de débit sont configurées au niveau infrastructurel et affichées dans la Console à titre de référence. Pour demander des modifications des seuils de limitation pour ton tenant, contacte ton administrateur Auris ou modifie la configuration de l’environnement.

Surveillance Proactive des Limites de Débit

Plutôt que d’attendre les réponses 429, surveille proactivement le header X-RateLimit-Remaining pour limiter ton taux de requêtes avant d’atteindre les limites :

class RateLimitAwareClient { private remaining = Infinity private resetAt = 0 async request(url: string, options: RequestInit): Promise<Response> { // Si nous savons que nous sommes à la limite, attendre de façon proactive if (this.remaining <= 1 && Date.now() / 1000 < this.resetAt) { const waitMs = (this.resetAt - Date.now() / 1000) * 1000 console.log(`Attente proactive de ${waitMs}ms pour éviter la limite de débit`) await new Promise((resolve) => setTimeout(resolve, waitMs)) } const response = await fetch(url, options) // Mettre à jour l'état de limitation depuis les headers de réponse const limit = response.headers.get('X-RateLimit-Remaining') const reset = response.headers.get('X-RateLimit-Reset') if (limit !== null) this.remaining = parseInt(limit, 10) if (reset !== null) this.resetAt = parseInt(reset, 10) return response } }

Bonnes Pratiques

Respecte toujours Retry-After. Quand tu reçois un 429, le header Retry-After te dit exactement combien de temps attendre. Ne réessaie pas avant cette période.

Utilise le backoff exponentiel avec jitter. Pour les opérations bulk ou les scénarios à fort débit, le retry linéaire simple peut provoquer des pics de trafic quand plusieurs clients réessaient au même moment. Le jitter distribue les retries dans le temps.

Implémente un circuit breaker pour les chemins critiques. Si ton application dépend des appels API Auris dans le chemin des requêtes (ex. vérifications de permissions), utilise un circuit breaker pour échouer élégamment plutôt que de mettre en file d’attente les requêtes pendant la limitation.

Mets en cache les réponses quand c’est possible. Réduis les appels API en mettant en cache les profils utilisateur, les listes de rôles et les vérifications de permissions. Le SDK @auris/react utilise TanStack Query en interne avec un staleTime par défaut qui réduit les appels API redondants.

Utilise les opérations batch quand disponibles. Utilise des endpoints bulk (ex. opérations bulk SCIM, écritures bulk FGA) plutôt que des appels API individuels pour accomplir le même travail avec moins de requêtes.

Surveille les headers de limitation en production. Enregistre la valeur X-RateLimit-Remaining et définis des alertes quand elle tombe en dessous d’un seuil. Cela te donne un avertissement anticipé avant que les utilisateurs commencent à voir des erreurs 429.

Guides Associés