Aller au contenu

Auth First-Party Onboarding

Document de référence transverse pour la cible auth HeyMoov.

Statut: cible de chantier Date de mise à jour: 2026-05-02

Sources spécialisées:

  • backend: heymoov-api/reference/auth_first_party_onboarding_plan.md
  • mobile: heymoov-mobile/docs/Passkeys.md
  • web: heymoov-web/docs/Auth.md

Décisions

  • Le login nominal est first-party HeyMoov.
  • Les passkeys sont la méthode primaire.
  • Le mot de passe reste un fallback optionnel.
  • Il n'y a pas de magic link de login.
  • Un compte peut être créé sans mot de passe.
  • Le lien email d'onboarding ou de recovery ne connecte jamais directement.
  • Hydra reste transitoire pour la webapp legacy, puis sera supprimé.
  • Aucun besoin OAuth/OIDC externe n'est retenu pour la cible actuelle.

Parcours cible

Signup direct

  1. Le visiteur saisit email, type de compte et les informations minimales demandées.
  2. Le backend crée une account_onboarding_intent.
  3. Un email de finalisation est envoyé.
  4. Le lien ouvre l'écran d'onboarding.
  5. L'utilisateur choisit son pseudo et crée un credential:
  6. passkey en priorité;
  7. mot de passe si passkey indisponible ou refusée.
  8. Le backend crée le compte actif, consomme l'intent et ouvre une session.

Waitlist

Le parcours waitlist garde deux étapes produit:

  1. inscription sur liste d'attente;
  2. confirmation email de l'inscription;
  3. invitation admin;
  4. finalisation onboarding depuis le lien d'invitation.

La cible supprime le second email d'activation. L'invitation admin ouvre directement l'onboarding credential.

Invitations utilisateur et adhérent structure

Les invitations ne créent plus un compte inactif à activer ensuite. Elles créent ou résolvent une intention d'onboarding, puis la finalisation credential crée le compte actif et applique le contexte métier de l'invitation.

Account onboarding intent

account_onboarding_intents devient l'objet pivot des créations de compte.

Champs attendus:

  • id
  • flow: direct_signup, waitlist_invite, user_invite, structure_adherent_invite
  • email
  • account_type
  • source_kind
  • source_id
  • token_hash
  • expires_at
  • consumed_at
  • webauthn_user_handle
  • created_user_id
  • created_person_id

Règles:

  • le token clair n'est jamais stocké;
  • une intent est single-use;
  • une intent expirée ne peut pas être finalisée;
  • le pseudo est choisi au moment de finaliser le credential;
  • la finalisation crée un user actif;
  • aucune génération de mot de passe aléatoire n'est autorisée.

Contrats API publics

Les noms exacts peuvent être ajustés pendant l'implémentation, mais la capacité fonctionnelle est verrouillée.

Onboarding

  • POST /v1/public/onboarding/resolve
  • POST /v1/public/onboarding/passkey/options
  • POST /v1/public/onboarding/passkey/verify
  • POST /v1/public/onboarding/password/complete

resolve valide le token et retourne le contexte d'affichage sans créer de session.

passkey/verify et password/complete consomment l'intent, créent le compte actif et retournent la session correspondant à la surface courante:

  • mobile: SessionEnvelope;
  • web: cookie BFF __Host-sid + réponse session minimale.

Recovery

  • POST /v1/public/account-recovery/request
  • POST /v1/public/account-recovery/resolve
  • POST /v1/public/account-recovery/passkey/options
  • POST /v1/public/account-recovery/passkey/verify
  • POST /v1/public/account-recovery/password/complete

Le lien de recovery donne uniquement le droit de recréer un credential. Il ne vaut pas authentification et ne doit pas ouvrir de session tant qu'un nouveau credential n'a pas été créé et vérifié.

Après recovery réussi:

  • toutes les sessions existantes sont révoquées;
  • les anciennes passkeys sont désactivées;
  • le nouveau credential est créé;
  • une nouvelle session est ouverte;
  • un email de sécurité est envoyé.

Step-up

Les opérations sensibles doivent accepter un step-up par passkey ou par mot de passe.

Opérations concernées:

  • changement email;
  • changement mot de passe;
  • suppression de credential;
  • actions de sécurité compte;
  • toute opération future demandant une preuve récente.

Sessions

Mobile

La session mobile reste first-party et opaque:

  • accessToken opaque court;
  • refreshToken opaque rotatif;
  • sessionId et deviceId backend;
  • aucun JWT mobile comme source de vérité.

Web

La cible web est un BFF first-party pur:

  • cookie __Host-sid opaque, HttpOnly, Secure;
  • cookie CSRF séparé;
  • pas de JWT applicatif durable dans le navigateur;
  • endpoint session/me ou bootstrap équivalent pour hydrater l'UI;
  • idle timeout et expiration absolue côté serveur;
  • rotation de session après login, recovery et step-up sensible.

Le UI JWT actuel reste uniquement un artefact transitoire des flows web legacy Hydra. Il ne fait pas partie de la cible.

Passkeys

Les passkeys sont des credentials de compte, pas des credentials strictement mobile.

La cible backend doit permettre:

  • création passkey pendant onboarding;
  • création passkey depuis une session existante;
  • login passkey mobile;
  • login passkey web via WebAuthn navigateur;
  • step-up passkey;
  • recovery passkey.

Les challenges WebAuthn doivent être liés au contexte:

  • login;
  • authenticated register;
  • onboarding register;
  • recovery register;
  • step-up.

Hydra

Hydra n'est plus la cible du login first-party HeyMoov.

Pendant la transition:

  • les flows Hydra web existants peuvent continuer à fonctionner;
  • la webapp peut migrer progressivement vers le login first-party;
  • aucun nouveau parcours produit ne doit dépendre d'Hydra;
  • le backend doit isoler les nouvelles sessions first-party des artefacts Hydra.

Cible finale:

  • suppression des routes Hydra utilisées seulement par HeyMoov first-party;
  • suppression des secrets et clients Hydra si aucun besoin OAuth/OIDC externe n'apparaît;
  • conservation éventuelle d'un bridge OIDC uniquement si un besoin externe formel est créé.

Sécurité

Contraintes minimales:

  • tokens onboarding et recovery: 30 minutes, single-use;
  • challenges WebAuthn: 5 minutes, single-use;
  • rate-limit par IP, email et couple IP/email;
  • audit logs sur login, onboarding, recovery, step-up et suppression credential;
  • notifications email sur recovery et changements de credential;
  • révocation globale via revoked_after ou mécanisme équivalent;
  • pas de réutilisation d'un token consommé;
  • pas de différence de réponse permettant d'énumérer les emails.

Migration

Le chantier se fait par étapes.

  1. Introduire les objets et services first-party sans casser les flows existants.
  2. Migrer mobile onboarding et recovery.
  3. Introduire web first-party en parallèle du web Hydra.
  4. Migrer les pages web publiques et l'admin.
  5. Supprimer les flows activation/password legacy.
  6. Decommission Hydra quand la webapp n'en dépend plus.

L'environnement étant en dev, les anciens liens d'activation peuvent être rompus et remplacés par de nouveaux liens d'onboarding.