Files
ObsiGate/docs/features/fusion-acc32-validation-locale-217.md
T
Spark 68d3dd85a9
CI / lint (push) Successful in 3m34s
CI / security (push) Successful in 2m17s
CI / test (push) Successful in 5m38s
CI / build (push) Successful in 2m15s
CI / e2e (push) Successful in 18m31s
feat: validation locale du jeton draco_session — repli SSO dans get_current_user (#217)
2026-10-20 23:47:45 -04:00

2.1 KiB

#217 — Validation locale du jeton draco_session (Fusion ACC-3.2)

Statut : ✅ livré le 2026-10-21 (2.72.0)

Contexte

Suite de l'émettrice SSO (#216, ACC-3.1). Ici, ObsiGate joue son rôle de consommatrice : get_current_user accepte le cookie partagé draco_session à défaut de jeton natif valide. C'est la brique qui servira aussi à l'API de l'agent commun (ACC-4) pour authentifier les requêtes SSO. Les validateurs des autres applications sont leurs tickets respectifs (Flowdeck #21, TikTak #213 — TikTak 0.52.0).

Correspondance sub → compte local

ObsiGate est émettrice ET consommatrice : le sub du jeton est son identifiant d'utilisateur — la résolution est directe, par id, dans draco_session.user_for_draco() :

  • signature/expiration/révocation vérifiées par verify_token (#216) ;
  • compte actif exigé ;
  • garde-fou BUG-028 appliqué à l'identique : un jeton draco émis avant le dernier changement de mot de passe (password_changed_at) est refusé ;
  • le dict utilisateur retourné porte _token_vaults (droits du compte), _token_scope = "full" et _draco_sub (traçabilité).

Branchement

Dans backend/auth/middleware.py, chaque sortie « non authentifié » du chemin natif (aucun jeton, jeton illisible, jti natif révoqué, compte introuvable/inactif, jeton antérieur au changement de mot de passe) passe par _draco_fallback(). Sûreté du repli après déconnexion globale : le logout révoque aussi le jti draco et efface le cookie (#216), donc un ancien cookie rejoué est refusé par verify_token.

Limite connue

Le repli authentifie les appels d'API. Le bootstrap d'une session complète du SPA (jetons natifs émis à partir du seul cookie draco) n'est pas couvert : pour ObsiGate, émettrice, la connexion native EST la connexion SSO — le cas d'usage du repli est la continuité d'API quand le jeton natif a expiré avant le cookie partagé, et les consommateurs machine de l'API.

Tests

tests/test_draco_session.py (+4) : /api/auth/me avec le seul cookie draco (200, bon utilisateur), jti révoqué refusé, sub inconnu refusé, inactivité sans secret configuré.