Prerequisites
- Enterprise plan (verified in
/api/auth/sso/[tenantSlug]route — other plans return 403) - Configured domain (white-label optional but recommended)
- IdP admin access (Okta, Azure AD, Google Workspace, Ping, OneLogin, etc)
SAML 2.0
ACS endpoint: /api/auth/sso/[tenantSlug]/saml/callback. SP metadata: /api/institution/sso/metadata. SAML Response validated via node-saml (XML signature, namespace, NotBefore/NotOnOrAfter).
OIDC
Authorization Code + PKCE (S256). State HMAC-signed + Redis nonce (15min TTL anti-replay). Userinfo endpoint → JIT provisioning → Supabase session.
SCIM 2.0
14 RFC 7644 endpoints. Bearer token encrypted AES-256-GCM. Configure in IdP > Provisioning. Supports CRUD, soft-delete (DELETE → User.status=suspended, never DB delete), bulk operations.
Group → Course mapping
When SCIM adds member to group → Studeia creates active Enrollment in course. Large groups (>50 members) processed via BullMQ (scim-group-sync queue), Response 202 + jobId.
Security
- SCIM Bearer token: encrypted AES-256-GCM in TenantSsoConfig.scimToken
- OAuth state: HMAC-SHA256 + Redis nonce
- JIT validation via
allowedDomains(anti-shadow accounts) - ScimAuditLog logs every operation with redacted payload
Limitations
- Direct LDAP (no SAML/OIDC) not natively supported — roadmap
- SAML SLO (Single Logout) partial — recommend SCIM for reliable deprovisioning
- MFA delegated to IdP
- Group nesting partially supported — recommend flatten in IdP