Skip to content

Single Sign On

sarmakska edited this page May 31, 2026 · 1 revision

Single Sign-On

StaffPortal supports single sign-on layered on top of Supabase Auth. It coexists with email and password sign-in and the kiosk PIN, so there is no second session system to manage.

How it works

  1. An administrator maps an email domain to a provider under Admin, Single Sign-On. The mapping is stored in the sso_connections table (domain, provider, display_name, is_active).
  2. At login, the screen calls the beginSso server action with the typed email. The pure helper resolveSso in lib/sso.ts looks up an active connection for the email domain.
  3. If a connection exists, the browser is redirected to the identity provider:
    • OAuth providers (azure, google, github, gitlab) use Supabase signInWithOAuth.
    • SAML 2.0 (saml) uses Supabase signInWithSSO.
  4. The provider returns through /auth/callback, which exchanges the code for a session. For a first-time SSO user it creates a profile and the standard leave balances, then records an sso_login event in the audit log.
  5. If no connection exists, the member signs in with email and password as before.

Provider setup

The identity-provider apps and SAML metadata are configured in the Supabase dashboard, not in this app:

  • OAuth: Authentication, Providers. Enable the provider and add its client ID and secret, and set the redirect URL to <your-app>/auth/callback.
  • SAML: Authentication, SSO. Register the SAML connection for the domain.

Then add the matching row in the app under Admin, Single Sign-On.

Supported providers

Provider value Identity provider Supabase method
azure Microsoft Entra ID signInWithOAuth
google Google Workspace signInWithOAuth
github GitHub signInWithOAuth
gitlab GitLab signInWithOAuth
saml Any SAML 2.0 IdP signInWithSSO

Auditing

Every SSO login writes an sso_login entry to the audit log with the actor and timestamp. See Audit-Log.

Troubleshooting

  • The password form keeps showing. The domain has no active connection. Add one and set it active.
  • Redirect fails at the provider. The redirect URL in the provider app does not match <your-app>/auth/callback.
  • First SSO login lands with no leave balances. The callback bootstrap only runs for non-email providers; confirm the provider value is not email.

Related

Clone this wiki locally