Identité et accès
Gestion de l'identité et contrôle d'accès dans les architectures distribuées : authentification, autorisation, JWT, OAuth2 et modèles comme RBAC.
Pourquoi l’identité est le premier pilier de la sécurité
Dans tout système distribué, la première question à laquelle il faut répondre à chaque requête est : qui es-tu et que peux-tu faire ? Sans une gestion solide de l’identité et de l’accès, le reste des mesures de sécurité perd tout son sens.
L’identité n’est pas seulement un “login et un mot de passe”. C’est un système complet qui englobe la façon dont les identifiants sont vérifiés, la façon dont les permissions sont représentées, la façon dont les décisions d’accès se propagent entre services, et la façon dont elles sont révoquées lorsque c’est nécessaire.
Authentification vs autorisation
Ces deux concepts sont souvent confondus, mais ce sont des responsabilités distinctes :
Authentification (AuthN)
Répond à la question : qui es-tu ?
- Vérifie l’identité de l’utilisateur ou du service
- Se base sur des identifiants : mot de passe, token, certificat, biométrie
- Produit un artefact d’identité (typiquement un token)
- Se produit une fois au début de la session (ou lors du renouvellement du token)
Autorisation (AuthZ)
Répond à la question : que peux-tu faire ?
- Vérifie les permissions de l’utilisateur authentifié
- Se base sur des rôles, des permissions, des politiques ou des attributs
- S’évalue à chaque opération nécessitant un accès
- Peut être aussi simple qu’un rôle ou aussi complexe que des politiques basées sur des attributs
Usuario → [Autenticación] → "Eres Juan, rol: editor"
Juan → [Autorización] → "¿Puede Juan editar este recurso?" → Sí/No
JSON Web Tokens (JWT)
JWT est le standard le plus utilisé pour représenter des claims d’identité dans les architectures distribuées.
Structure d’un JWT
Un JWT comporte trois parties séparées par des points :
header.payload.signature
{
"header": {
"alg": "RS256",
"typ": "JWT"
},
"payload": {
"sub": "user-456",
"email": "maria@ejemplo.com",
"role": "admin",
"permissions": ["read:users", "write:users", "read:orders"],
"iat": 1705312200,
"exp": 1705314000,
"iss": "auth-service",
"aud": "api-gateway"
}
}
Claims importants
| Claim | Signification |
|---|---|
sub | Subject — identifiant unique de l’utilisateur |
iss | Issuer — qui a émis le token |
aud | Audience — à qui il est destiné |
exp | Expiration — quand il expire |
iat | Issued At — quand il a été émis |
role | Rôle de l’utilisateur (claim personnalisé) |
permissions | Permissions spécifiques (claim personnalisé) |
Avantages du JWT dans les microservices
- Stateless : chaque service peut vérifier le token sans consulter une base de données centrale
- Propagation : le token voyage dans l’en-tête
Authorizationentre services - Autonome : il inclut toute l’information nécessaire pour prendre des décisions d’accès
Risques et mitigations
- Token volé : utiliser des durées d’expiration courtes (15 à 30 minutes)
- Claims obsolètes : le token peut contenir des permissions déjà révoquées ; utiliser des refresh tokens et des listes de révocation
- Taille excessive : ne pas inclure de données inutiles dans le payload
OAuth 2.0
OAuth 2.0 est un framework d’autorisation qui permet à des applications tierces d’accéder à des ressources au nom d’un utilisateur, sans exposer ses identifiants.
Flux principaux
Authorization Code (avec PKCE)
Le flux le plus sûr, recommandé pour les applications web et mobiles :
sequenceDiagram
participant U as Usuario
participant App as Aplicación
participant AS as Authorization Server
participant API as Resource Server
U->>App: Clic en "Iniciar sesión"
App->>AS: Redirect a /authorize (+ code_challenge)
AS->>U: Muestra pantalla de login
U->>AS: Ingresa credenciales
AS->>App: Redirect con authorization code
App->>AS: POST /token (code + code_verifier)
AS-->>App: Access token + refresh token
App->>API: Request con access token
API-->>App: Datos protegidos
Client Credentials
Pour la communication service à service, sans utilisateur impliqué :
Servicio A → POST /token (client_id + client_secret) → Access token
Servicio A → Request a Servicio B con access token
Quand utiliser OAuth 2.0
- Intégration avec des fournisseurs d’identité externes (Google, GitHub, Azure AD)
- Applications qui doivent accéder à des API au nom de l’utilisateur
- Scénarios où le consentement explicite de l’utilisateur est requis
Modèles de contrôle d’accès
RBAC — Role-Based Access Control
Le modèle le plus courant. Les permissions sont assignées à des rôles, et les rôles sont assignés aux utilisateurs.
Usuario → Rol → Permisos
Ejemplo:
María → admin → [crear_usuario, eliminar_usuario, ver_reportes]
Juan → editor → [editar_contenido, ver_reportes]
Ana → viewer → [ver_reportes]
Avantages : simple à comprendre, facile à auditer, suffisant pour la plupart des applications.
Limites : gère mal les permissions conditionnelles (“peut modifier uniquement ses propres ressources”).
ABAC — Attribute-Based Access Control
Les permissions sont évaluées en fonction d’attributs de l’utilisateur, de la ressource et du contexte :
Política: "Un usuario puede editar un documento SI:
- usuario.departamento == documento.departamento
- Y documento.estado != 'publicado'
- Y hora_actual está dentro del horario laboral"
Avantages : extrêmement flexible, gère des cas complexes.
Limites : plus difficile à implémenter, auditer et déboguer.
Recommandation pratique
Commencez par RBAC. Ne migrez vers ABAC que si vous avez des exigences d’accès conditionnel que RBAC ne peut pas résoudre. Beaucoup de systèmes combinent les deux : RBAC pour la structure de base et des règles ABAC pour des cas spécifiques.
Propagation de l’identité entre services
Dans une architecture de microservices, l’identité doit se propager de service en service :
Frontend → API Gateway → BFF → Servicio A → Servicio B
[verifica] [propaga JWT] [propaga JWT]
Stratégies de propagation
-
Token passthrough : le même JWT de l’utilisateur est transmis entre services. Simple, mais le token peut avoir plus de permissions que nécessaire.
-
Token exchange : chaque service demande un nouveau token avec un scope réduit pour le service suivant. Plus sûr, mais plus complexe.
-
Service mesh avec mTLS : l’identité du service est vérifiée au niveau réseau, et l’identité de l’utilisateur voyage dans le JWT. Combine les deux couches.
Bonnes pratiques
- Centralisez l’authentification dans un service dédié (Auth Service ou Identity Provider)
- Utilisez des tokens de courte durée avec des refresh tokens
- Ne stockez pas les tokens dans localStorage — utilisez des cookies httpOnly ou la mémoire
- Implémentez la révocation de tokens pour les cas de compromission
- Enregistrez tous les événements d’authentification à des fins d’audit
- Utilisez toujours HTTPS — ne transmettez jamais d’identifiants en clair
- Appliquez le principe du moindre privilège : chaque service et utilisateur ne dispose que des permissions dont il a besoin
Résumé
La gestion de l’identité et de l’accès est la base sur laquelle repose toute la sécurité du système. JWT fournit un mécanisme stateless pour propager l’identité entre services, OAuth 2.0 standardise les flux d’autorisation, et des modèles comme RBAC et ABAC définissent comment sont prises les décisions d’accès. La clé est de concevoir ces mécanismes dès le départ, et non de les ajouter comme un correctif ultérieur.