Prérequis
- Plan Enterprise (vérifié sur la route
/api/auth/sso/[tenantSlug]— les autres plans reçoivent une erreur 403) - Domaine configuré (white-label optionnel mais recommandé)
- Accès administrateur à l'IdP (Okta, Azure AD, Google Workspace, Ping, OneLogin, etc.)
SAML 2.0
Configuration
Settings > SSO > Add Provider > SAML
Champs :
- Display name — nom affiché sur le bouton "Sign in with..."
- Metadata XML URL OU Metadata XML collé — fourni par l'IdP
- SP-initiated ou IdP-initiated — Studeia supporte les deux
- Allowed domains — restreint les e-mails (anti-shadow accounts)
Endpoints exposés
- ACS (Assertion Consumer Service) :
/api/auth/sso/[tenantSlug]/saml/callback - SP metadata :
/api/institution/sso/metadata
Validation
La réponse SAML est validée via node-saml :
- Vérification de la signature XML (anti-falsification)
- Validation des namespaces XML SAML (anti-XXE)
- Vérifications NotBefore/NotOnOrAfter
- Restriction d'audience
OIDC
Configuration
Settings > SSO > Add Provider > OIDC
Champs :
- Discovery URL —
https://idp.com/.well-known/openid-configuration(récupération automatique) - Client ID + Client Secret (chiffré AES-256-GCM)
- Scopes — par défaut :
openid profile email - PKCE — toujours activé (méthode de challenge S256)
Flux
- L'étudiant clique "Sign in with [IdP]" →
/api/auth/sso/[tenantSlug]/oidc - Redirection vers l'IdP avec PKCE challenge + state signé HMAC + nonce dans Redis (TTL 15min anti-replay)
- L'IdP authentifie → callback
/api/auth/sso/[tenantSlug]/oidc/callback - Studeia valide le state + nonce, échange le code contre des tokens (PKCE verifier)
- Endpoint Userinfo → JIT provisioning (crée l'utilisateur s'il n'existe pas) → session Supabase
SCIM 2.0
14 endpoints RFC 7644
GET /api/scim/v2/ServiceProviderConfig
GET /api/scim/v2/ResourceTypes
GET /api/scim/v2/Schemas
GET /api/scim/v2/Users (liste, avec filtre)
POST /api/scim/v2/Users (création)
GET /api/scim/v2/Users/{id}
PUT /api/scim/v2/Users/{id} (remplacement complet)
PATCH /api/scim/v2/Users/{id} (partiel — compat. Microsoft Graph)
DELETE /api/scim/v2/Users/{id} (soft-delete : User.status=suspended)
GET /api/scim/v2/Groups (liste)
POST /api/scim/v2/Groups
GET /api/scim/v2/Groups/{id}
PUT /api/scim/v2/Groups/{id}
PATCH /api/scim/v2/Groups/{id}
DELETE /api/scim/v2/Groups/{id}
Configuration dans Azure AD (exemple)
- Azure Portal > Enterprise Applications > Studeia > Provisioning
- Provisioning Mode : Automatic
- Tenant URL :
https://votreapp.studeia.com/api/scim/v2 - Secret Token : généré dans Studeia dans Settings > SSO > SCIM Token (Bearer, chiffré en base de données)
- Test Connection
- Mappings : attributs par défaut (compatible Microsoft Graph)
- Settings > Scope : "Sync only assigned users and groups"
- Démarrer le provisionnement
Group → Course mapping
Permet l'inscription automatique lorsque l'IdP ajoute un utilisateur à un groupe :
- Configurez le mapping dans Settings > SSO > Groups
- Pour chaque SsoGroup, choisissez le Course cible
- Lorsque SCIM ajoute un membre au groupe → Studeia crée une Enrollment active dans le cours
- Lorsqu'il le retire → l'inscription est annulée (status=cancelled)
- Groupes importants (>50 membres) : traitement via BullMQ (queue
scim-group-sync), réponse 202 + jobId
Sécurité
Tokens
- Bearer token SCIM : chiffré AES-256-GCM dans
TenantSsoConfig.scimToken— JAMAIS en texte clair - Tokens OAuth (intégration Google Workspace) : même standard
- State OAuth : HMAC-SHA256 avec
OAUTH_STATE_SECRET+ nonce Redis (TTL 15min)
JIT provisioning
allowedDomainsvalide l'e-mail avant de créer l'utilisateur- Attributs de l'IdP mappés via
SsoAttributeMapping - Rôle par défaut configurable (
studentouteacher)
Audit
ScimAuditLog enregistre :
- Toute opération SCIM (Create/Update/Delete) avec horodatage + IP + acteur (IdP) + utilisateur/groupe affecté + payload (expurgé)
- AdminAuditLog pour les modifications de SsoConfig par l'administrateur institutionnel
Limitations
- LDAP direct (sans SAML/OIDC) non supporté nativement — feuille de route
- Déprovisionnement just-in-time via SAML SLO (Single Logout) partiel — il est recommandé d'utiliser SCIM pour un déprovisionnement fiable
- Authentification multi-facteurs déléguée à l'IdP (Studeia ne gère pas son propre MFA lorsque le SSO est actif)
- Imbrication de groupes (groupes dans des groupes) partiellement supportée — il est recommandé d'aplatir la structure dans l'IdP