RFC 7519 · JSON Web Signature

Introduction aux JWT

JSON Web Token (JWT) est un standard ouvert (RFC 7519) pour représenter des revendications (claims) sous forme de chaîne compacte et utilisable dans des URL. Il est très répandu avec OAuth 2.0 et OpenID Connect, mais le format est générique : toute partie disposant du bon matériel de vérification peut contrôler la signature et interpréter les claims — dans les limites de la gestion des clés et des horloges.

Cette page détaille la construction d’un JWT, la lecture de chaque partie, et les garanties que vous pouvez — et ne pouvez pas — attendre du seul jeton.

01

Sérialisation compacte et encodage

Sous la forme habituelle (JSON Web Signature, JWS), un JWT comporte trois segments séparés par des points : en-tête, charge utile (payload) et signature. Les deux premiers segments sont des objets JSON encodés en Base64URL (pas la Base64 « classique ») : le rembourrage est souvent omis et les caractères sont adaptés aux URL, ce qui permet d’envoyer le jeton dans des en-têtes ou des chaînes de requête.

L’encodage Base64URL n’est pas du chiffrement. L’en-tête et le payload sont lisibles par quiconque possède la chaîne. La signature prouve que les deux premiers segments ont été produits par une entité maîtrisant la clé de signature ; elle ne les rend pas confidentiels.

02

Structure d’un JWT

Chaque segment a un rôle précis dans la forme compacte JWS :

Header

Contient en général typ (type, souvent « JWT ») et alg (algorithme de signature). On peut y trouver kid (identifiant de clé) pour choisir la bonne clé publique dans un JWKS, ou d’autres métadonnées requises par votre environnement.

Payload

Objet JSON contenant les claims : sujet, fenêtre de validité, audience, champs métier, etc. Des objets imbriqués sont possibles lorsque l’émetteur les définit.

Signature

Valeur cryptographique portant sur les octets « header.payload » (les deux segments encodés et le point entre eux), avec l’algorithme indiqué dans l’en-tête et soit un secret partagé (HMAC), soit une clé privée asymétrique (RSA, ECDSA, EdDSA).

03

Les claims : le contenu du payload

Les claims sont des paires nom/valeur. Leur sens dépend du contexte, mais la RFC 7519 définit des noms enregistrés afin que les bibliothèques et les API les interprètent de façon cohérente.

Claims enregistrés (registered)

Exemples fréquents : iss (émetteur), sub (sujet), aud (audience), exp (expiration), nbf (pas avant), iat (émis à), jti (identifiant du jeton). exp et nbf sont des horodatages Unix ; les valider correctement suppose une horloge de confiance côté vérificateur.

Claims publics

Des noms peuvent être enregistrés auprès de l’IANA (« JSON Web Token Claims ») pour favoriser l’interopérabilité entre implémentations. Ce ne sont toujours que des conventions tant que producteurs et consommateurs ne s’accordent pas sur la sémantique.

Claims privés

Noms convenus entre l’émetteur et le consommateur (rôles internes, identifiant de locataire, etc.). Évitez les collisions avec les noms enregistrés si les deux extrémités ne sont pas entièrement sous votre contrôle.

04

Algorithmes en bref

La valeur alg dans l’en-tête détermine le calcul de la signature. Le choix du modèle conditionne qui peut vérifier le jeton et comment les secrets sont distribués.

  • HMAC (HS*) : un secret partagé signe et vérifie. Simple pour un service unique, mais chaque vérificateur doit connaître le secret.
  • RSA ou ECDSA/EdDSA : l’émetteur signe avec une clé privée ; les vérificateurs utilisent la clé publique (souvent via un JWKS). Adapté aux microservices et aux clients qui ne doivent pas détenir le secret de signature.
  • L’algorithme « none » ne doit pas être accepté en production : une mauvaise configuration pourrait autoriser des jetons non signés. Rejetez explicitement les algorithmes inconnus ou désactivés.
05

Sécurité : confiance, confidentialité et validation

Une signature valide atteste que le jeton a été émis par le détenteur de la clé de signature et que l’en-tête et le payload n’ont pas été modifiés. Cela ne chiffre pas le contenu.

Ne placez jamais de mots de passe, clés API ou autres secrets longue durée dans le payload. Pour des données confidentielles en plus de la signature, utilisez TLS en transit et envisagez le JWT chiffré (JWE) — un autre format et un autre flux.

Les serveurs doivent valider la signature avec la clé ou le JWKS attendu, vérifier exp (et en général nbf), appliquer aud et iss lorsque votre architecture s’appuie dessus, et privilégier des durées de vie courtes avec rafraîchissement lorsque c’est pertinent.

06

Utilisations courantes

Les JWT servent souvent à :

  • Représenter l’identité authentifiée et les décisions d’autorisation (jetons d’accès « bearer », jetons d’identité en OpenID Connect)
  • Propager l’identité ou un pouvoir délégué entre services dans un système distribué
  • Modéliser une session ou un état « connecté » côté client, avec stockage sécurisé et stratégie de rafraîchissement
  • Porter des scopes OAuth 2.0 ou des claims personnalisés pour les passerelles API et les serveurs de ressources
07

Limites pratiques

Quelques contraintes utiles lorsque vous concevez avec des JWT :

  • Taille : les jetons voyagent souvent dans les en-têtes HTTP ; un payload volumineux augmente la latence et peut heurter les limites des proxys.
  • Révocation : un JWT purement stateless ne peut pas être invalidé instantanément sans mécanisme supplémentaire (listes de blocage, introspection, durées de vie très courtes).
  • Décalage d’horloge : la validation de exp et nbf suppose des horloges raisonnablement synchronisées entre émetteurs et vérificateurs.