Google Workspace and personal accounts.
SSO (Single Sign-On)
Configure OAuth-based single sign-on with Google, Microsoft, GitHub, Facebook, or any OIDC provider
Soosh supports SSO via OAuth 2.0 / OIDC. Providers are platform-wide: a super admin sets them up once, and users of every organization sign in through them and land in their own organization. SSO only signs in people an organization has already added; it never creates accounts.
Supported Providers
Section titled “Supported Providers”Microsoft
Azure AD / Entra ID via the common endpoint. Only for accounts that are already linked; see Linking accounts.
GitHub
GitHub.com accounts. Pulls primary verified email if private.
Facebook accounts with email permission.
Custom (OIDC)
Any OIDC-compatible provider — Okta, Auth0, Keycloak, Authentik, etc. Requires you to supply the auth/token/userinfo URLs.
How It Works
Section titled “How It Works”-
User clicks “Sign in with <provider>” on the login page. The list of buttons is driven by which platform providers are enabled via
GET /api/auth/sso/providers(public endpoint, no secrets exposed). -
Frontend hits
/api/auth/sso/{provider}/init. The server generates a random state nonce, stores{provider, nonce, expires_at}in Redis with a 5-minute TTL, and returns the provider’s authorization URL. -
User authenticates with the provider and grants consent.
-
Provider redirects to
/api/auth/sso/{provider}/callback?code=...&state=.... The server:- Validates and immediately deletes the state from Redis (one-shot, prevents replay).
- Exchanges the authorization code for an access token.
- Calls the provider’s userinfo endpoint to get
id,email,name, and whether the email is verified. - Checks the email domain against
allowed_domainsif configured. - Looks up the user by email. Unknown emails, disabled users, super admins, and orgs with the
ssofeature turned off are rejected. - Checks or creates the link between the user and this provider identity (see Linking accounts).
- Logs the user into their own default organization.
- Sets httpOnly JWT cookies and redirects to
/auth/sso/callbackin the SPA.
Configuration
Section titled “Configuration”Settings live under Platform → Sign-in (SSO), visible to super admins only. All providers share the same core fields; Custom adds three more.
| Field | Required | Notes |
|---|---|---|
client_id |
yes | OAuth client ID from the provider’s developer console. |
client_secret |
yes | Stored encrypted at rest using app.encryption_key. Cannot be retrieved after save — only re-set. |
is_enabled |
— | Master switch. Disabled providers don’t appear on the login page. |
allowed_domains |
— | Comma-separated email domains, e.g. acme.com,acme.co.in. Empty = any domain accepted. |
auth_url |
custom only | OAuth 2.0 authorization endpoint. |
token_url |
custom only | OAuth 2.0 token endpoint. |
user_info_url |
custom only | OIDC userinfo endpoint. Must return sub (or id), email, and name (or preferred_username). |
Provider redirect URI
Section titled “Provider redirect URI”When you create the OAuth app at the provider, set the redirect URI (a.k.a. callback URL) to:
https://<your-host>/api/auth/sso/{provider}/callbackReplace {provider} with google, microsoft, github, facebook, or custom. If you serve Soosh at a sub-path (server.base_path = "/soosh"), include it: https://example.com/soosh/api/auth/sso/google/callback.
Linking accounts
Section titled “Linking accounts”Organization admins add users by email under Settings → Users, as usual. The first time that person signs in with a provider, Soosh links the provider identity to the user, but only if the provider verified the email:
| Provider | Verified email comes from |
|---|---|
verified_email in userinfo |
|
| GitHub | the verified-emails API (/user/emails) |
| Facebook only returns confirmed emails | |
| Custom (OIDC) | email_verified: true in userinfo |
| Microsoft | never: Graph’s mail can be set by any tenant admin (“nOAuth”), so Microsoft cannot link new accounts |
After that, the link is pinned. The same provider identity signs in without further checks. A different identity, from the same provider or another one, cannot take the account over while the linked provider is enabled, even with a verified email. Each user has one link; if its provider is removed or disabled, the user can link another with a verified email.
Super admins can’t sign in with SSO; they keep their own sign-in method.
Organizations
Section titled “Organizations”- One set of provider apps serves every organization, so you register a single OAuth app per provider.
- A user who belongs to several organizations lands in their default one and can switch from the UI.
- To turn SSO off for one organization, disable its
ssofeature under Platform → Organizations → (org) → Features. Its users are then rejected at the callback; other organizations are unaffected.
Security
Section titled “Security”| Concern | Mitigation |
|---|---|
| Client secret leak | Stored AES-256 encrypted using app.encryption_key. Set this in production — without it, secrets are stored in plaintext. |
| CSRF / replay on callback | State nonce stored in Redis (5-min TTL) and deleted on first use. Replays fail. |
| Brute force on callback | rate_limit.sso_max_attempts (default 10/min/IP) caps both init and callback. Set rate_limit.trust_proxy = true if behind a reverse proxy. |
| Account takeover by email | New links need a provider-verified email; existing links are pinned to one provider identity; super admins are excluded. |
| Disabled accounts | Users with is_active = false are rejected at the end of the SSO flow. |
Custom OIDC Providers
Section titled “Custom OIDC Providers”For Okta, Auth0, Keycloak, Authentik, etc., choose Custom and supply:
| Field | Example (Keycloak) |
|---|---|
auth_url |
https://kc.example.com/realms/main/protocol/openid-connect/auth |
token_url |
https://kc.example.com/realms/main/protocol/openid-connect/token |
user_info_url |
https://kc.example.com/realms/main/protocol/openid-connect/userinfo |
Soosh requests the openid email profile scopes and expects the userinfo response to contain at least one of: sub or id, plus email, plus name or preferred_username. Most OIDC providers return this out of the box.
Provider-specific notes
Section titled “Provider-specific notes”Configure the OAuth 2.0 client at console.cloud.google.com/apis/credentials. Set the Authorized redirect URI to your Soosh callback. Standard Google sign-in flow — no extra setup.
Microsoft
Section titled “Microsoft”Uses Azure AD’s common endpoint. Register the app at entra.microsoft.com → App registrations. Email is read from mail, falling back to userPrincipalName. Because neither is verified, Microsoft only signs in users linked to a Microsoft identity earlier.
GitHub
Section titled “GitHub”Register an OAuth App at github.com/settings/developers. Soosh requests the user:email scope and always uses the user’s primary verified email from /user/emails.
Register the app at developers.facebook.com/apps. Add the Facebook Login product. Note that Facebook may not return an email if the user has no verified email on file — the SSO will fail with “email not provided” in that case.
Common Issues
Section titled “Common Issues”| Symptom | Likely cause |
|---|---|
User not found. Ask your organization admin to add you. |
No user has this email. An organization admin adds them under Settings → Users. |
This account is not linked to this identity provider… |
The provider didn’t verify the email (always the case for Microsoft), the account is linked to a different identity, or it’s a super admin. |
SSO is disabled for your organization |
The user’s organization has the sso feature turned off. |
Email domain not allowed |
The user’s email domain isn’t in allowed_domains. Either add their domain or remove the restriction. |
Invalid or expired state |
The state nonce expired (>5 min between init and callback) or was already used. Have the user start the login again. |
Failed to authenticate with provider |
The OAuth code exchange failed — usually a redirect URI mismatch or an invalid client secret. Re-check both at the provider. |
email not provided by SSO provider |
Provider returned no email. For GitHub, ensure the user has a verified email; for Facebook, ensure email permission was granted. |
Account is disabled |
User exists but is_active = false. Re-enable under Settings → Members. |
| Provider button missing on login page | The provider isn’t enabled under Platform → Sign-in (SSO). |