L'authentification d'API est le mécanisme par lequel le serveur vérifie l'identité du caller (humain ou machine) avant de traiter une requête. En 2026, sept mécanismes coexistent dans l'écosystème API selon le contexte d'usage : API Keys (le plus simple), HTTP Basic Auth (legacy), JWT (JSON Web Tokens, stateless dominant), OAuth 2.0 et OIDC (standard utilisateur fédéré), mTLS (cryptographique fort), HMAC signatures (webhooks et machine-to-machine léger), SAML 2.0 (legacy enterprise SSO). Chaque mécanisme a ses cas d'usage, ses forces et ses limites : aucun n'est universellement supérieur. Le choix dépend du type de client (humain vs machine), du niveau de sensibilité, des contraintes opérationnelles (gestion certificats, rotation), et de l'écosystème existant. Cet article cartographie les 7 mécanismes principaux avec patterns d'implémentation, critères de choix par cas d'usage, comparatif synthétique, et pièges fréquents observés. Les standards référencés sont les RFCs IETF (RFC 6749 OAuth 2.0, RFC 7519 JWT, RFC 8705 mTLS) et les spécifications OpenID Foundation (OpenID Connect Core 1.0, FAPI 2.0).
Authentification vs autorisation : la clarification fondamentale
Confusion source de nombreuses vulnérabilités. Distinction non négociable.
| Concept | Question répondue | Mécanismes | Outputs |
|---|---|---|---|
| Authentification (authn) | Qui es-tu ? | API key, JWT, OAuth, mTLS, HMAC, SAML | Identité prouvée (user ID, claims) |
| Autorisation (authz) | As-tu le droit ? | RBAC, ABAC, ReBAC, scopes, ACL | Décision permit/deny |
Une API correctement sécurisée vérifie systématiquement les deux à chaque requête :
# Pattern correct
@app.get("/api/orders/{order_id}")
def get_order(
order_id: int,
current_user: User = Depends(authenticate), # AUTHN : qui es-tu ?
):
order = db.query(Order).filter(Order.id == order_id).first()
if not order:
raise HTTPException(404)
# AUTHZ : as-tu le droit sur cet objet précis ?
if order.owner_id != current_user.id and "admin" not in current_user.roles:
raise HTTPException(403)
return orderConfondre les deux mène aux vulnérabilités BOLA (Broken Object Level Authorization, API1:2023 OWASP), BFLA (API5:2023), BOPLA (API3:2023) qui dominent les incidents API documentés en 2024-2026.
Mécanisme 1 — API Keys
Le mécanisme le plus simple. Une chaîne secrète partagée entre le client et le serveur, transmise dans chaque requête.
Pattern d'implémentation
# Header standard (recommandé)
GET /api/v1/products HTTP/1.1
Host: api.example.test
X-API-Key: sk_live_4eC39HqLyjWDarjtT1zdp7dc
# Alternative : query parameter (déconseillé : apparaît dans logs URL)
GET /api/v1/products?api_key=sk_live_4eC39HqLyjWDarjtT1zdp7dc HTTP/1.1Validation côté serveur
from fastapi import FastAPI, Header, HTTPException
import hashlib
import secrets
app = FastAPI()
# API keys stockées hashées en base (jamais en clair)
API_KEYS_DB = {
"sha256_hash_de_la_cle_1": {"client_id": "partner_a", "rate_limit": 1000},
"sha256_hash_de_la_cle_2": {"client_id": "partner_b", "rate_limit": 100},
}
def verify_api_key(x_api_key: str = Header(...)):
if not x_api_key:
raise HTTPException(401, "Missing API key")
key_hash = hashlib.sha256(x_api_key.encode()).hexdigest()
if key_hash not in API_KEYS_DB:
raise HTTPException(401, "Invalid API key")
return API_KEYS_DB[key_hash]
@app.get("/api/v1/products")
def list_products(client = Depends(verify_api_key)):
return {"client_id": client["client_id"], "products": [...]}Quand utiliser
- APIs internes faible criticité avec rotation régulière (90 jours).
- Tier gratuit / démo APIs publiques (avec rate limiting strict).
- Identification de partenaires B2B sans authentification utilisateur fine.
- Intégrations webhook simples.
Quand éviter
- Authentification utilisateur (préférer OAuth + JWT).
- Accès données sensibles (préférer JWT scoped + courte expiration).
- Production critique (préférer mTLS).
Bonnes pratiques
- Génération via PRNG cryptographique (
secrets.token_urlsafe(32)Python,crypto.randomBytes(32)Node). - Stockage hashé côté serveur (SHA-256 minimum, idéalement Argon2).
- Préfixe identifiant le tier ou type (
sk_live_pour Stripe production,sk_test_pour test). - Rotation programmée (90 jours typique).
- Détection de fuite (scan secrets dans repos Git, monitoring usage anormal).
Mécanisme 2 — HTTP Basic Authentication (legacy)
Standardisé dans RFC 7617. Username:password encodés en Base64 dans le header.
GET /api/v1/products HTTP/1.1
Host: api.example.test
Authorization: Basic dXNlcjpwYXNzd29yZA==Décode dXNlcjpwYXNzd29yZA== = user:password.
Quand utiliser
Quasi jamais en API moderne. Cas restants :
- Compatibilité avec outils legacy.
- Pré-prod / debug avec credentials non productifs.
- HTTP Basic combiné à TLS et IP allowlist pour services internes simples.
Pourquoi éviter
- Credentials transmis en clair (juste Base64-encodé) à chaque requête.
- Pas d'expiration ni de scope.
- Username/password en clair côté client.
- Aucune protection contre replay si TLS cassé.
Toute API moderne devrait utiliser JWT, OAuth ou API key plutôt que Basic Auth. Si Basic obligatoire pour compatibility, exiger TLS 1.3 + IP allowlist + rotation password trimestrielle.
Mécanisme 3 — JWT (JSON Web Tokens)
Standard RFC 7519. Format de token stateless dominant en 2026 pour API authentication.
Structure
Trois parties séparées par des points : <header>.<payload>.<signature>.
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImtleS0yMDI2In0
.
eyJzdWIiOiJ1c2VyXzEyMyIsImVtYWlsIjoidXNlckBleGFtcGxlLnRlc3QiLCJyb2xlcyI6WyJ1c2VyIl0sImlhdCI6MTcxNDExODQwMCwiZXhwIjoxNzE0MTIyMDAwLCJpc3MiOiJodHRwczovL2lkcC5leGFtcGxlLnRlc3QiLCJhdWQiOiJhcGkuZXhhbXBsZS50ZXN0In0
.
RS256_signature_base64urlHeader décodé :
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-2026"
}Payload décodé (claims) :
{
"sub": "user_123",
"email": "user@example.test",
"roles": ["user"],
"iat": 1714118400,
"exp": 1714122000,
"iss": "https://idp.example.test",
"aud": "api.example.test"
}Signature : RS256 du header.payload concaténé avec la clé privée RSA du IdP.
Validation côté API
import jwt
from jwt import PyJWKClient
# Récupération des clés publiques via JWKS endpoint (RFC 7517)
jwks_client = PyJWKClient("https://idp.example.test/.well-known/jwks.json")
def verify_jwt(token: str) -> dict:
try:
# Récupère la clé publique correspondant au kid du header
signing_key = jwks_client.get_signing_key_from_jwt(token)
# Décode et valide
payload = jwt.decode(
token,
signing_key.key,
algorithms=["RS256"], # CRUCIAL : whitelist explicite
issuer="https://idp.example.test",
audience="api.example.test",
options={
"verify_signature": True,
"verify_exp": True,
"verify_iat": True,
"verify_iss": True,
"verify_aud": True,
"require": ["exp", "iat", "iss", "aud", "sub"],
}
)
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(401, "Token expired")
except jwt.InvalidTokenError as e:
raise HTTPException(401, f"Invalid token: {e}")Pièges JWT critiques
| Piège | Problème | Défense |
|---|---|---|
Confiance dans alg du header | Attaquant peut envoyer alg:none ou faire algorithm confusion | Whitelist algorithms côté serveur |
| Pas de validation audience | Token volé d'une autre app peut être réutilisé | Vérifier aud matche l'API |
| Pas de validation issuer | Token forgé peut être accepté | Vérifier iss matche l'IdP attendu |
| Données sensibles en payload | Payload est juste base64url, pas chiffré | Pas de password, secret, PII en payload |
| Expirations longues | Token compromis utilisable longtemps | 5 à 60 min pour access tokens |
| Pas de rotation des clés | Compromission clé = perte sécurité | Rotation annuelle minimum, JWKS endpoint |
Quand utiliser JWT
- API consommée par utilisateurs humains via applications web, mobile, SPA.
- Microservices internes avec authentification stateless.
- Federation cross-service avec OIDC.
- Cas où la performance compte (validation crypto sans appel DB).
Quand éviter
- Cas requérant révocation immédiate avant expiration sans tooling.
- APIs avec très haute sensibilité où mTLS est plus approprié.
Mécanisme 4 — OAuth 2.0 et OpenID Connect
Pour utilisateurs humains et federation, OAuth 2.0 (RFC 6749) est le standard. OIDC (OpenID Connect) ajoute la couche d'authentification standardisée par-dessus OAuth.
En bref
- OAuth 2.0 = framework d'autorisation. Permet à une app d'accéder à des ressources au nom d'un user.
- OIDC = couche d'authentification au-dessus d'OAuth. Permet de prouver l'identité du user.
- JWT = format de token souvent utilisé par OAuth/OIDC.
Flow le plus utilisé en 2026 : Authorization Code + PKCE
┌────────────┐ ┌────────┐ ┌──────┐
│ User Agent │ │ IdP │ │ App │
│ (Browser) │ │ (Auth0,│ │ API │
└────────────┘ │ Okta, │ └──────┘
│ Keycloak)
└────────┘
│ 1. Click login app │ │
├──────────────────────────────────────────────────────────────────────►
│ │ │
│ 2. Redirect to IdP authorize endpoint │ │
│ (avec code_challenge PKCE) │ │
◄──────────────────────────────────────────────────────────────────────┤
│ │ │
│ 3. User authentifie + consent │ │
├───────────────────────────────────────────►│ │
│ │ │
│ 4. Redirect avec authorization code │ │
◄───────────────────────────────────────────┤ │
│ │ │
│ 5. Exchange code for tokens │ │
│ (avec code_verifier PKCE) │ │
├──────────────────────────────────────────────────────────────────────►
│ │ │
│ 6. Access token + Refresh token + ID │ │
│ token (OIDC) │ │
◄──────────────────────────────────────────────────────────────────────┤
│ │ │
│ 7. API call with Bearer access token │ │
├──────────────────────────────────────────────────────────────────────►
│ │ │
│ 8. Validate JWT, return data │ │
◄──────────────────────────────────────────────────────────────────────┤L'API ne participe pas au flow d'authentification : elle reçoit juste un access token (souvent JWT) qu'elle valide.
Client Credentials flow (machine-to-machine)
Pour authentification de service à service :
curl -X POST https://idp.example.test/oauth2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=service-a" \
-d "client_secret=<secret>" \
-d "scope=read:orders write:orders"Ce flow est détaillé en profondeur dans l'article dédié OAuth 2.0.
Mécanisme 5 — mTLS (Mutual TLS)
Standardisé RFC 8705 pour OAuth (OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens). Authentification cryptographique via certificats X.509 côté client ET serveur.
Principe
Le client et le serveur s'authentifient mutuellement pendant le handshake TLS via leurs certificats X.509 respectifs. L'authentification est liée au transport (couche 4-5), inaccessible aux scripts d'application.
Configuration côté serveur (Nginx exemple)
server {
listen 443 ssl http2;
server_name api.example.test;
# Certificat serveur classique
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Configuration mTLS : exiger client cert
ssl_client_certificate /etc/nginx/ssl/ca.crt;
ssl_verify_client on;
ssl_verify_depth 2;
# Reverse proxy vers backend
location / {
proxy_pass http://backend:8080;
# Transmettre les infos du cert client au backend
proxy_set_header X-Client-Cert-DN $ssl_client_s_dn;
proxy_set_header X-Client-Cert-Verify $ssl_client_verify;
proxy_set_header X-Client-Cert-Fingerprint $ssl_client_fingerprint;
}
}Quand utiliser mTLS
- Microservices internes (service mesh Istio, Linkerd avec auto-mTLS).
- Partner B2B haute sensibilité (FAPI 2.0 banking, PSD2 open banking).
- IoT devices avec identité forte requise.
- Environnements zero-trust où l'authentification au niveau transport est obligatoire.
Compromis
| Avantage | Inconvénient |
|---|---|
| Authentification cryptographique très forte | Complexité opérationnelle (PKI à gérer) |
| Inaccessible aux scripts (couche transport) | Rotation certificats lourde |
| Résiste au phishing | Pas adapté aux clients web/mobile end-users |
| Performant (handshake TLS standard) | Difficile à debugger |
Mécanisme 6 — HMAC signatures
Pattern dominant pour webhooks. Le sender signe le payload avec une clé secrète partagée.
Implémentation type Stripe
Côté sender (votre service qui envoie le webhook) :
import hmac
import hashlib
import time
import json
WEBHOOK_SECRET = "whsec_4eC39HqLyjWDarjtT1zdp7dc"
def send_webhook(url: str, event: dict):
payload = json.dumps(event)
timestamp = int(time.time())
# Signature : HMAC-SHA256 de "timestamp.payload"
signed_payload = f"{timestamp}.{payload}"
signature = hmac.new(
WEBHOOK_SECRET.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
headers = {
"Content-Type": "application/json",
"X-Signature-Timestamp": str(timestamp),
"X-Signature": f"sha256={signature}",
}
requests.post(url, data=payload, headers=headers)Côté receiver (le partenaire qui reçoit le webhook) :
def verify_webhook(request, secret: str, max_age: int = 300):
timestamp = request.headers.get("X-Signature-Timestamp")
signature_header = request.headers.get("X-Signature")
if not timestamp or not signature_header:
raise HTTPException(401, "Missing signature headers")
# Anti-replay : refuser les anciens timestamps (> 5 min)
if abs(time.time() - int(timestamp)) > max_age:
raise HTTPException(401, "Timestamp too old")
# Reconstruction signature attendue
payload = request.body.decode()
signed_payload = f"{timestamp}.{payload}"
expected_signature = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
# Comparaison constant-time pour éviter timing attacks
received_signature = signature_header.replace("sha256=", "")
if not hmac.compare_digest(expected_signature, received_signature):
raise HTTPException(401, "Invalid signature")
return json.loads(payload)Bonnes pratiques HMAC
- Toujours inclure un timestamp dans le payload signé (anti-replay).
- Refuser les timestamps trop anciens (5 minutes max).
- Comparer les signatures en constant-time (
hmac.compare_digest) pour éviter les timing attacks. - Clé secrète unique par tenant ou par webhook endpoint, rotable indépendamment.
- SHA-256 minimum (jamais SHA-1).
Patterns observés
- Stripe :
Stripe-Signatureheader avec HMAC-SHA256 + timestamp. - GitHub :
X-Hub-Signature-256header avec HMAC-SHA256. - Slack :
X-Slack-Signatureavec HMAC-SHA256 + timestamp. - Twilio :
X-Twilio-Signatureavec HMAC-SHA1 (legacy, idéalement migration vers SHA-256).
Mécanisme 7 — SAML 2.0 (legacy enterprise)
Standard OASIS 2005. Format XML pour SSO enterprise. Toujours massivement déployé en 2026 dans les contextes corporate legacy.
Cas d'usage 2026
- SSO enterprise vers applications web (Salesforce, SAP, Microsoft 365, applications internes anciennes).
- Federation B2B traditionnelle entre grandes entreprises.
- Compliance dans certains secteurs réglementés qui imposent SAML.
Pourquoi SAML pour API moderne est rare
- Format XML lourd et verbeux comparé à JWT.
- Complexité d'implémentation (signatures XML, encryption, assertions).
- Mauvaise adaptation aux clients mobiles et SPA (redirections POST complexes).
- OIDC (qui est conceptuellement le successeur SAML pour le mobile/web moderne) plus adapté.
Quand encore utiliser SAML
- Intégration enterprise legacy où le service distant ne supporte que SAML.
- Migration progressive SAML vers OIDC (coexistence transitoire).
Pour tout nouveau projet API en 2026, OIDC est préféré à SAML.
Comparaison synthétique : quand utiliser quoi
Tableau de décision rapide.
| Mécanisme | Cas d'usage idéal | Force | Limite |
|---|---|---|---|
| API Keys | APIs internes, partenaires simples, démos publiques | Simplicité maximale | Pas de scopes ni d'expiration intrinsèque |
| HTTP Basic | Pré-prod, debug, cas legacy avec TLS + IP allowlist | Standard universel | Credentials transmis à chaque requête |
| JWT | API utilisateur via SPA/mobile, microservices, OAuth backends | Stateless, scopes, expirations | Révocation pré-expiration complexe |
| OAuth 2.0 + OIDC | Authentification utilisateur fédérée standard | Standard universel, fédération | Complexité d'implémentation |
| mTLS | Microservices service mesh, B2B FAPI, IoT | Cryptographique fort | PKI à gérer |
| HMAC | Webhooks, machine-to-machine léger | Simple, intégrité prouvée | Pas de fédération identité |
| SAML 2.0 | SSO enterprise legacy, federation B2B traditionnelle | Maturité enterprise | Lourd, mal adapté mobile/SPA |
Décision par scénario
API publique avec utilisateurs humains via SPA / mobile : OAuth 2.0 Authorization Code + PKCE → JWT pour l'API.
API B2B avec partenaires entreprises : OAuth 2.0 Client Credentials → JWT pour l'API. Optionnellement mTLS si haute sensibilité.
Microservices internes : mTLS via service mesh (Istio, Linkerd) + JWT applicatifs si scopes fins requis.
Webhooks vers partenaires : HMAC SHA-256 avec timestamp anti-replay.
API publique simple (tier gratuit, démo, partenaire identification) : API key avec rate limiting et rotation.
Intégration enterprise SSO legacy : SAML 2.0 si imposé par le partenaire, sinon OIDC.
Patterns d'implémentation pratiques
Cinq patterns récurrents en production 2026.
Pattern 1 — JWT avec refresh tokens
Pour SPA et mobile : access token JWT court (15 min) + refresh token long (7 jours). Renewal automatique transparent pour l'utilisateur.
// Renewal automatique en TS
async function callApi(url: string) {
let accessToken = getStoredAccessToken();
let response = await fetch(url, {
headers: { Authorization: `Bearer ${accessToken}` }
});
if (response.status === 401) {
// Tentative de renewal
accessToken = await refreshAccessToken();
storeAccessToken(accessToken);
// Retry
response = await fetch(url, {
headers: { Authorization: `Bearer ${accessToken}` }
});
}
return response;
}
async function refreshAccessToken(): Promise<string> {
const refreshToken = getStoredRefreshToken();
const response = await fetch("/api/auth/refresh", {
method: "POST",
body: JSON.stringify({ refreshToken }),
});
const data = await response.json();
return data.accessToken;
}Pattern 2 — Token introspection pour révocation immédiate
Si la révocation immédiate avant expiration est requise (compte compromis, logout), pattern OAuth 2.0 Token Introspection (RFC 7662) :
# API valide chaque token via call à l'IdP au lieu de validation locale JWT
def verify_token_via_introspection(token: str):
response = requests.post(
"https://idp.example.test/oauth2/introspect",
data={"token": token},
auth=(API_CLIENT_ID, API_CLIENT_SECRET),
)
introspection = response.json()
if not introspection.get("active"):
raise HTTPException(401, "Token revoked or invalid")
return introspectionTrade-off : performance (call HTTP par requête) vs révocation immédiate. Compromis usuel : validation JWT locale + cache Redis avec TTL court (1-5 min) + denylist de tokens révoqués.
Pattern 3 — JWT avec scopes pour autorisation
Le payload JWT inclut des scopes qui définissent les permissions :
{
"sub": "user_123",
"scope": "read:orders write:orders read:profile",
"iat": 1714118400,
"exp": 1714122000
}Côté API :
def require_scope(*required_scopes):
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
token = extract_token()
payload = verify_jwt(token)
granted_scopes = set(payload.get("scope", "").split())
for scope in required_scopes:
if scope not in granted_scopes:
raise HTTPException(403, f"Missing scope: {scope}")
return await func(*args, **kwargs)
return wrapper
return decorator
@app.delete("/api/orders/{order_id}")
@require_scope("write:orders")
async def cancel_order(order_id: int):
passPattern 4 — Service mesh mTLS automatique
Pour microservices interne sur Kubernetes avec Istio :
# Istio : enforce mTLS strict sur tout le namespace
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICTAvec cette policy, tout le trafic entre Pods est automatiquement mTLS, sans modification de code applicatif. Istio gère la PKI interne via ses certificate manager (auto-rotation, distribution sidecars).
Pattern 5 — API gateway centralise l'authentification
L'API gateway (Kong, Apigee, AWS API Gateway, Azure API Management) valide les tokens à l'edge, transmet l'identité au backend via headers signés :
Client → API Gateway → Backend Service
API Gateway :
1. Valide JWT (signature, expiration, audience)
2. Extrait user_id depuis sub claim
3. Transmet vers backend :
- X-User-ID: user_123
- X-User-Roles: user,manager
- X-User-Email: user@example.testBackend service fait confiance aux headers (signés ou via réseau privé). Avantage : validation centralisée, backend simplifié. Risque : si backend exposé en parallèle de la gateway, headers spoofables. Toujours bind backend privé.
Pièges fréquents
Cinq erreurs récurrentes observées dans les implémentations 2024-2026.
Algorithm confusion sur JWT. Acceptation de plusieurs algorithmes de signature, l'attaquant peut forcer un algorithme faible (HS256 au lieu de RS256) et utiliser la clé publique comme HMAC secret. Solution : whitelist algorithm strict côté validation.
JWT en query string. Token apparaît dans les logs serveur, proxy logs, navigateur history. Solution : toujours en header Authorization: Bearer ....
Pas de rotation de clés JWT. Compromission de la clé privée IdP = perte de sécurité tant que pas de rotation. Solution : JWKS endpoint avec rotation au moins annuelle, idéalement automatique.
API keys en clair dans le code source. Commit accidentel dans Git, exposition publique. Solution : secrets scanning (gitleaks) en pre-commit + CI, vault pour stockage prod.
HMAC sans timestamp anti-replay. Webhook capturé peut être rejoué indéfiniment. Solution : timestamp obligatoire dans payload signé, refus si trop ancien.
Points clés à retenir
- L'authentification d'API en 2026 dispose de 7 mécanismes principaux : API Keys (simple), HTTP Basic (legacy), JWT (stateless dominant), OAuth 2.0 + OIDC (utilisateur fédéré), mTLS (cryptographique fort), HMAC (webhooks), SAML 2.0 (legacy enterprise).
- Authentification (qui es-tu) et autorisation (as-tu le droit) sont distincts. Une API correctement sécurisée vérifie systématiquement les deux à chaque requête. Confondre = vulnérabilités BOLA, BFLA, BOPLA.
- JWT est le format dominant 2026 pour API utilisateurs. Pièges critiques : whitelist algorithm, validation aud/iss, expirations courtes, rotation des clés via JWKS.
- mTLS pour microservices internes (service mesh Istio/Linkerd auto-mTLS) et B2B haute sensibilité (FAPI 2.0). HMAC SHA-256 pour webhooks. OAuth 2.0 Client Credentials pour machine-to-machine partner.
- API gateway centralise validation tokens à l'edge et simplifie le backend. Mais ne dispense pas des défenses applicatives (autorisation, BOLA, business logic).
Pour aller plus loin
- OAuth 2.0 expliqué : flows, tokens, PKCE, sécurité - deep-dive complet OAuth 2.0 et OAuth 2.1.
- Qu'est-ce que la sécurité des API - vue d'ensemble de la discipline API security incluant authentification.
- Qu'est-ce que l'IAM - cadre IAM dont l'authentification API est une composante.
- Qu'est-ce que Keycloak - IdP open source qui implémente tous ces mécanismes.





