Format des tokens de session : Paseto v4 public
source : docs/adr/0005-token-format-paseto-v4.md · versionné · MADR-lite
ADR-0005 — Format des tokens de session : Paseto v4 public
- Statut : Accepted
- Date : 2026-04-24
- Décideurs : Core team OmbrysWeb
- Issue GitHub : #25
- Références : cahier des charges § 5.1, § 6.1 ; ADR-0002 (crypto strategy)
- Dépend de : ADR-0001, ADR-0002
Contexte
Après authentification WebAuthn réussie (cf. ADR-0002, issue #23), auth-svc émet un token porté par le frontend pour les requêtes subséquentes vers les autres micro-services. Ce token est le support de la session applicative courte (15 min, cf. crypto-spec § 4.1), avec :
iss,sub,iat,nbf,expstandards,sididentifiant unique de session,dididentifiant device / Passkey utilisé,assuranceniveau (baseaprès login normal,stepupaprès re-auth biométrique).
Deux formats sérieux étaient en lice : JWT EdDSA (EdDSA sur courbe Ed25519, RFC 8037) et Paseto v4 public.
Options
JWT (RFC 7519) avec EdDSA
Pour : - Format standard largement déployé, librairies partout. - Claims flexibles, extensible sans perte de compatibilité. - EdDSA est sûre et rapide (Ed25519).
Contre : - Le header embarque alg, ce qui historiquement a permis des attaques : - alg: none (libs bogguées), - confusion RS256/HS256 (clé publique interprétée comme clé symétrique), - confusion RSA/EC. - Même quand la lib valide strictement, le mécanisme même de choix d'algo est un poids cognitif et une source de CVE récurrentes. - Pas de cryptographic binding entre le header typ et le reste. Une implémentation laxiste peut accepter un token "ressemblant".
Paseto v4 public (version 4, purpose public)
Pour : - Pas de négociation d'algorithme. Le purpose v4.public fixe Ed25519 exclusivement. Aucun header modifiable par l'attaquant. - Le préfixe de version/purpose (v4.public.) est authentifié et vérifié avant toute interprétation des claims. - Les "footer" et "implicit assertion" (IA) permettent de bind des métadonnées publiques (ex : version du schema de claims) à la signature, sans les chiffrer. - Spécifiquement conçu par des spécialistes pour éviter les erreurs JWT. - Signatures Ed25519, même perf que JWT EdDSA.
Contre : - Moins de librairies (en Rust : rusty_paseto mature mais unique acteur sérieux). - Adoption moins large que JWT → un intégrateur tiers peut ne pas connaître. - Évolution du format demande un bump de version (déjà bump 1→2→3→4).
Décision
Paseto v4 public pour les tokens de session utilisateur.
- Implémentation Rust via
rusty_paseto(prelude haut niveau côté serveur ; le frontend Next.js vérifie uniquement via appel àauth-svc— il ne décode jamais lui-même, donc pas de lib Paseto côté navigateur). - Seed Ed25519 32 octets stocké dans Vault (
kv/services/auth-svc/token-seed), rotation tous les 30 jours ou sur incident. - Clé publique distribuée aux autres micro-services via SPIFFE workload identity + endpoint interne
auth-svc:/v1/keys/current+/v1/keys/previous(pour supporter la rotation). - Claims portés définis dans
ombrys_tokens::SessionClaims. - Footer v1 portant
{"kid": "seed-<epoch>"}pour router la vérification vers la bonne clé pendant une rotation.
Conséquences
Positives
- Surface d'attaque très réduite comparée à JWT — zéro ambiguïté d'algorithme.
- Zero allocation côté lib, perf excellente.
- Claims standards préservés → migration future vers JWT (si nécessaire) triviale.
- Le déploiement s'appuie déjà sur Ed25519 pour le journal d'audit et pour SPIFFE SVID JWT.
Négatives
- Pas de lib Paseto mainstream côté iOS/Android natif (problème pour le client mobile v2). Mitigation : wrapper Rust via UniFFI quand on attaquera le mobile.
- Écosystème plus petit → revue sécurité plus cruciale sur la lib.
Neutres
- Les tokens PASETO commencent par
v4.public.— facilement reconnaissables dans les logs, ce qui aide à la détection de fuites (règlesgitleakscustom).
Suivi
- Rotation du seed : procédure documentée dans
docs/operations/key-rotation.md(à rédiger en M2). - Revue sécurité : audit externe M6 couvre explicitement la chaîne de tokens.
- Évolution : si Paseto ajoute
v5avec PQ natif, ADR de révision. Pour l'instant les tokens courts ne nécessitent pas de PQ (menace « harvest now, decrypt later » négligeable sur des tokens de 15 min).
Changelog
- 2026-04-24 : rédaction initiale, statut Accepted.