Obexal Docs

Docs/Authentification/Authentification multifacteur

Authentification multifacteur (MFA)

TOTP, codes e-mail, codes de récupération, vérification step-up et MFA obligatoire par organisation ou par groupe : aucun facteur primaire ne contourne la MFA.

Obexal traite la MFA comme un invariant côté serveur, pas comme une option d'interface : dès qu'un compte possède un second facteur actif, aucun facteur primaire ne peut ouvrir de session sans lui.

Les seconds facteurs en bref

FacteurTypeValidité
TOTPApplication d'authentification (RFC 6238, 6 chiffres, période de 30 s)Code courant, 1 période de dérive d'horloge tolérée
Code e-mailCode numérique à usage unique envoyé à l'adresse vérifiée10 minutes
Codes de récupération10 codes de secours à usage uniqueJusqu'à usage ou régénération

Il n'y a pas de facteur SMS, par choix : l'envoi de SMS ferait transiter des données d'authentification par des agrégateurs hors UE et reste exposé au SIM swapping, Obexal l'exclut donc par décision souveraine.

Le point de passage MFA

Tous les facteurs primaires aboutissent au même point de décision côté serveur : mot de passe, e-mail sans mot de passe, login social, SAML et LDAP. Si le compte a un facteur MFA actif, aucune session n'est ouverte ; l'API renvoie un défi à la place :

{ "mfaRequired": true, "mfaToken": "kJ2m...", "methods": ["totp"] }

Le client le complète avec le second facteur :

curl -sS -X POST https://accounts.obexal.com/v1/auth/mfa \
  -H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' \
  -d '{"mfaToken":"kJ2m...","code":"123456"}'
# 200 -> {"user":{...}} et le cookie de session est posé

Le défi est à usage unique et stocké haché, expire après 5 minutes (10 minutes pour les codes e-mail, le temps que le message arrive), autorise au plus 5 tentatives, et la vérification est limitée en débit par IP. Le TOTP est prioritaire : un utilisateur qui possède les deux facteurs reçoit un défi TOTP. La seule exception délibérée au point de passage est le passkey, lui-même un facteur primaire fort et résistant au phishing.

Note

Les exemples utilisent accounts.obexal.com ; remplacez-le si votre organisation se connecte sur un domaine personnalisé.

Enrôler et gérer le facteur TOTP

L'enrôlement exige une session et suit une transition de « pending » vers « active » :

# 1. Enrôlement : crée un facteur PENDING, renvoie le secret à scanner (montré ici seulement).
curl -sS -b cookies.txt -X POST https://accounts.obexal.com/v1/mfa/totp/enroll \
  -H "X-CSRF-Token: $CSRF"
# 200 -> {"secret":"JBSWY3DPEHPK3PXP","otpauthUri":"otpauth://totp/Obexal:a@b.eu?..."}

# 2. Activation : un code courant valide fait passer le facteur en ACTIVE.
curl -sS -b cookies.txt -X POST https://accounts.obexal.com/v1/mfa/totp/activate \
  -H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' -d '{"code":"123456"}'
# 200 -> {"recoveryCodes":["...", "..."]}  (10 codes, montrés une seule fois)

Le secret TOTP est chiffré au repos. La désactivation du facteur (POST /v1/mfa/totp/disable) exige un code TOTP courant valide : une session détournée ne peut pas retirer silencieusement le second facteur. GET /v1/mfa liste les facteurs du compte et leur statut.

Le code e-mail comme second facteur

Le facteur « code e-mail » peut être enrôlé explicitement : POST /v1/mfa/email/enroll envoie un code à l'adresse vérifiée du compte et renvoie un mfaToken ; POST /v1/mfa/email/activate avec {"mfaToken","code"} active le facteur ; POST /v1/mfa/email/disable le retire.

Il est aussi appliqué par défaut comme politique de plateforme : une connexion par mot de passe d'un utilisateur sans TOTP reçoit un défi par code e-mail, si bien que le mot de passe seul n'ouvre jamais de session. Si le message tarde, demandez un nouveau code :

curl -sS -X POST https://accounts.obexal.com/v1/auth/mfa/resend \
  -H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' \
  -d '{"mfaToken":"kJ2m..."}'
# 200 -> {"mfaToken":"<nouveau token>","codeLength":6}

Le renvoi est limité en débit par IP et chaque renvoi invalide le token de défi précédent.

Les codes de récupération

L'activation du TOTP génère 10 codes de récupération à usage unique, renvoyés en clair une seule fois et stockés hachés. Chacun peut compléter un défi MFA à la place d'un code TOTP ({"mfaToken":"...","recoveryCode":"..."}), par exemple après la perte du téléphone.

POST /v1/mfa/recovery-codes/regenerate (session requise, TOTP actif requis) remplace le lot entier : les codes précédents deviennent immédiatement invalides.

La vérification step-up avant les actions sensibles

Une session valide ne suffit pas toujours. Les endpoints sensibles exigent une re-vérification fraîche du second facteur :

curl -sS -b cookies.txt -X POST https://accounts.obexal.com/v1/mfa/step-up \
  -H "X-CSRF-Token: $CSRF" -H 'Content-Type: application/json' -d '{"code":"123456"}'
# 204 -> la session est marquée « MFA fraîche » pendant 5 minutes

Sans step-up frais, les endpoints sensibles (par exemple modifier l'identité ou les plafonds de politique d'un agent IA, ou faire tourner le secret d'un agent) répondent 403 step_up_required. Un code de récupération est accepté à la place d'un code TOTP. Règle anti-verrouillage : un utilisateur sans facteur MFA n'est pas bloqué par cette garde, puisqu'il ne pourrait jamais réussir le step-up.

Imposer la MFA à une organisation ou à un groupe

Les administrateurs peuvent rendre la MFA obligatoire :

  • Par organisation : dans la console, réglages de l'organisation, activez l'exigence de MFA (API : le champ requireMfa de PATCH /v1/admin/tenant).
  • Par groupe : positionnez requireMfa à la création ou à la modification d'un groupe ; chaque membre est alors soumis au mandat.
curl -sS -X POST https://accounts.obexal.com/v1/admin/groups \
  -H "Authorization: Bearer $OBEXAL_API_TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"Finance","requireMfa":true}'

À la connexion, un utilisateur soumis au mandat qui n'a encore aucun facteur obtient une session marquée mfaEnrollmentRequired: true, et l'interface de connexion hébergée force l'enrôlement avant toute chose. Les déploiements auto-hébergés peuvent en plus poser MFA_ENROLLMENT_STRICT=true : le serveur refuse alors les requêtes authentifiées (403 mfa_enrollment_required) tant qu'aucun facteur n'est enrôlé, en n'autorisant que les endpoints d'enrôlement, me, logout et csrf. Voir la configuration.

Les règles d'accès conditionnel peuvent aussi exiger la MFA dynamiquement, selon le réseau, l'horaire ou le pays.