Single Sign-On
Connect Zelaxy to your identity provider so your team signs in with their existing corporate credentials over OIDC or SAML 2.0.
Single Sign-On (SSO) hands authentication off to the identity provider (IdP) your company already runs — Microsoft Entra ID, Google Workspace, Okta, ADFS, and anything else that speaks OpenID Connect or SAML 2.0. Instead of every teammate maintaining a separate Zelaxy password, they authenticate once against your directory and land straight in their workspace.
Zelaxy stores one provider record per email domain. When someone signs in, their domain decides which IdP handles the request.
The sign-in flow
Here is what happens end to end once a provider is live:
A teammate opens the Zelaxy login page and chooses Sign in with SSO, then types their work email (for example dana@company.com).
Zelaxy reads the domain (company.com), finds the matching provider, and forwards the browser to your identity provider.
Your IdP authenticates the person — password, MFA, hardware key, whatever your policy requires — and posts the result back to Zelaxy's callback URL.
Zelaxy verifies the response, creates the account if it is new, attaches it to your organization, and drops the person into the workspace.
First-time sign-ins are provisioned automatically at the member role — no invite step — as long as organizations are enabled on the deployment. Email and password login keeps working alongside SSO; Zelaxy does not currently force a domain onto SSO exclusively.
Before you begin
Who is allowed to configure SSO depends on how Zelaxy is running:
| Deployment | Requirement |
|---|---|
| Zelaxy Cloud | An Enterprise plan, and you must be an owner or admin of the organization. |
| Self-hosted | The SSO_ENABLED environment variable is set (details under Self-hosting). |
You also need admin access to your identity provider so you can register an application and copy its credentials.
Add a provider
Everything is configured from Hub → Settings → Single Sign-On (under the Organization group).
Pick a protocol
Choose OIDC if your IdP supports OpenID Connect (Entra ID, Google Workspace, Okta, Auth0, Keycloak, and most modern directories). Choose SAML 2.0 for SAML-only systems such as ADFS or Shibboleth.
Fill in the shared fields
Both protocols need three things:
- Provider ID — a short slug (
azure-ad,okta,company-sso) using lowercase letters, numbers, and dashes. It becomes part of the callback URL, so pick it before you register anything with your IdP. - Issuer URL — for OIDC this is the IdP's issuer; for SAML it is the identifier your IdP knows Zelaxy by (the service-provider entity ID). Must be HTTPS.
- Domain — the email domain that routes to this provider, e.g.
company.com.
Add the protocol-specific fields
Fill in either the OIDC or the SAML block — see the field reference below.
Register the callback URL with your IdP
The form shows a read-only Callback URL. Copy it and add it to your identity provider's allowed redirect / assertion-consumer list before saving. The shape depends on the protocol:
https://app.zelaxy.in/api/auth/sso/callback/<provider-id>https://app.zelaxy.in/api/auth/sso/saml2/callback/<provider-id>Save and try it
Save the provider, sign out, and use Sign in with SSO with an address on your domain. A correct setup bounces you to your IdP and back into Zelaxy.
Self-hosted instances serve the callback from their own origin — swap https://app.zelaxy.in for the value of NEXT_PUBLIC_APP_URL.
Field reference
OIDC
| Field | Notes |
|---|---|
| Client ID | The application/client identifier issued by your IdP. |
| Client Secret | The matching secret. Editing a provider keeps the stored secret unless you type a new one. |
| Scopes | Comma-separated. Defaults to openid,profile,email. |
Zelaxy resolves the authorization, token, userinfo, and JWKS endpoints from the issuer's /.well-known/openid-configuration document, so you never enter them by hand.
SAML 2.0
| Field | Notes |
|---|---|
| Entry Point URL | Where Zelaxy sends authentication requests (the IdP's SSO service URL). |
| Certificate | The Base-64 encoded X.509 signing certificate used to verify assertions. |
| Require signed assertions | Enforces a valid IdP signature on every assertion. Leave on unless your IdP cannot sign. |
| Audience / Entity ID | Optional override for the expected SAML audience. |
Connect your identity provider
Microsoft Entra ID — OIDC
- In the Azure portal open Microsoft Entra ID → App registrations → New registration.
- Under Redirect URI, select Web and paste
https://app.zelaxy.in/api/auth/sso/callback/azure-ad. - Open Certificates & secrets → New client secret and copy the secret value right away — Azure hides it afterwards.
- From Overview, note the Application (client) ID and the Directory (tenant) ID.
Then, in Zelaxy:
| Field | Value |
|---|---|
| Protocol | OIDC |
| Provider ID | azure-ad |
| Issuer URL | https://login.microsoftonline.com/<tenant-id>/v2.0 |
| Domain | company.com |
| Client ID | Application (client) ID |
| Client Secret | The secret value |
Swap <tenant-id> for your Directory (tenant) ID. Entra app registration docs →
Google Workspace — OIDC
- In the Google Cloud Console open APIs & Services → Credentials → Create Credentials → OAuth 2.0 Client ID.
- Set the application type to Web application.
- Under Authorized redirect URIs, add
https://app.zelaxy.in/api/auth/sso/callback/google-workspace. - Copy the generated Client ID and Client Secret.
Then, in Zelaxy:
| Field | Value |
|---|---|
| Protocol | OIDC |
| Provider ID | google-workspace |
| Issuer URL | https://accounts.google.com |
| Domain | company.com |
| Client ID | From Google Cloud Console |
| Client Secret | From Google Cloud Console |
To keep sign-in limited to your Workspace, set the OAuth consent screen User type to Internal. That restricts the app to accounts inside your Google Workspace organization. Google OIDC docs →
Okta — OIDC
- In the Okta admin console open Applications → Create App Integration.
- Select OIDC - OpenID Connect, then Web Application.
- Set the Sign-in redirect URI to
https://app.zelaxy.in/api/auth/sso/callback/okta. - Grant access to the right users or groups under Assignments, then copy the Client ID and Client Secret from the app's General tab.
Then, in Zelaxy:
| Field | Value |
|---|---|
| Protocol | OIDC |
| Provider ID | okta |
| Issuer URL | https://<your-org>.okta.com/oauth2/default |
| Domain | company.com |
| Client ID | From the Okta app |
| Client Secret | From the Okta app |
The issuer above uses Okta's built-in default authorization server. If you run a custom one, replace default with its name. Okta OIDC wizard docs →
ADFS — SAML 2.0
- In AD FS Management open Relying Party Trusts → Add Relying Party Trust, choose Claims aware, and enter the data manually.
- Set the Relying party identifier (entity ID) to
https://app.zelaxy.in— this must match the Issuer URL you enter in Zelaxy. - Add a SAML Assertion Consumer Service endpoint using HTTP POST at
https://app.zelaxy.in/api/auth/sso/saml2/callback/adfs. - Export the Token-signing certificate as Base-64 encoded X.509 (.CER) and paste its contents into the Certificate field.
- Note your Federation Service endpoint, typically
https://adfs.company.com/adfs/ls.
Then, in Zelaxy:
| Field | Value |
|---|---|
| Protocol | SAML |
| Provider ID | adfs |
| Issuer URL | https://app.zelaxy.in |
| Domain | company.com |
| Entry Point URL | https://adfs.company.com/adfs/ls |
| Certificate | Contents of the exported .cer |
Linking to existing accounts
When a person signs in through SSO and an account already exists for that email — say they signed up earlier with a password — Zelaxy links the two automatically, provided the IdP marks the email as verified (email_verified) or the provider is trusted. Mainstream OIDC providers assert this claim, so linking is transparent.
Some IdPs, mostly on the SAML side, leave the claim out. In that case, trust the provider explicitly by adding its Provider ID to SSO_TRUSTED_PROVIDER_IDS (self-hosted) and restarting. Without it, sign-in fails with an account not linked error.
Self-hosting
Self-hosted deployments swap the plan check for environment variables.
# Turn SSO on
SSO_ENABLED=true
NEXT_PUBLIC_SSO_ENABLED=true
# Enable organizations so SSO users are added to your org on first sign-in
ORGANIZATIONS_ENABLED=true
NEXT_PUBLIC_ORGANIZATIONS_ENABLED=true
# Trust extra providers for automatic account linking (comma-separated Provider IDs).
# Use when your IdP omits email_verified — typically SAML.
SSO_TRUSTED_PROVIDER_IDS=partner-saml,legacy-oidcMake sure the schema is up to date so the sso_provider table exists:
cd apps/zelaxy && bun run db:push # or apply the 0009_sso_provider migrationProviders can be created from the same Settings UI, or seeded from the command line — handy for first-boot automation and CI.
Register an OIDC provider
SSO_ENABLED=true \
NEXT_PUBLIC_APP_URL=https://your-instance.com \
SSO_PROVIDER_TYPE=oidc \
SSO_PROVIDER_ID=okta \
SSO_ISSUER=https://your-org.okta.com/oauth2/default \
SSO_DOMAIN=company.com \
SSO_USER_EMAIL=admin@company.com \
SSO_OIDC_CLIENT_ID=your-client-id \
SSO_OIDC_CLIENT_SECRET=your-client-secret \
bun run apps/zelaxy/scripts/register-sso-provider.tsRegister a SAML provider
SSO_ENABLED=true \
NEXT_PUBLIC_APP_URL=https://your-instance.com \
SSO_PROVIDER_TYPE=saml \
SSO_PROVIDER_ID=adfs \
SSO_ISSUER=https://your-instance.com \
SSO_DOMAIN=company.com \
SSO_USER_EMAIL=admin@company.com \
SSO_SAML_ENTRY_POINT=https://adfs.company.com/adfs/ls \
SSO_SAML_CERT="-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----" \
bun run apps/zelaxy/scripts/register-sso-provider.tsThe SSO_USER_EMAIL account has to exist already — it becomes the owner of the provider record. On success the script prints the callback URL to hand to your IdP.
Remove a provider
SSO_USER_EMAIL=admin@company.com \
SSO_PROVIDER_ID=okta \
bun run apps/zelaxy/scripts/deregister-sso-provider.tsDrop SSO_PROVIDER_ID to remove every provider owned by that user.
Troubleshooting
| Symptom | Likely cause and fix |
|---|---|
| SSO button never redirects; "no provider" message | No provider is registered for that email domain. Confirm the Domain field matches the address. |
| IdP rejects the redirect / ACS URL | The callback URL registered at the IdP does not match. It must be the exact Provider-ID URL Zelaxy shows. |
| Account not linked on sign-in | The IdP omits email_verified. Add the Provider ID to SSO_TRUSTED_PROVIDER_IDS and restart. |
| SAML assertion fails validation | The certificate is wrong or expired. Re-export the IdP's current signing certificate and paste it again. |
| SSO tab is missing in Settings | The feature flag is off (NEXT_PUBLIC_SSO_ENABLED), or on Cloud the org lacks an Enterprise plan / admin rights. |