SSO Configuration
What this covers
Tessallite supports SAML 2.0 and OpenID Connect (OIDC) for single sign-on. This page explains how SSO works, how to configure each protocol, how to set up group-to-role mappings, and what happens when a user signs in via SSO for the first time.
How SSO fits into the authentication chain
Tessallite authenticates users through a chain of backends. Each tenant can enable one or more of: local (username/password), ldap, gcp_iam, saml, and oidc. The login page adapts to show the available options — when saml or oidc is enabled, a Sign in with SSO button appears alongside the standard credential form.
SAML and OIDC are redirect-based. The user's browser is sent to the identity provider (IdP) for authentication. After successful authentication, the browser is redirected back to Tessallite, which validates the response, creates or updates the local user record, and issues a JWT for the session.
SAML 2.0 setup
Step 1 — Register Tessallite as a Service Provider
Tessallite publishes its SP metadata at:
GET /api/v1/auth/saml/metadata
Download this XML and upload it to your IdP (Auth0, Google Workspace, Okta, AD FS, or any SAML 2.0 IdP). The metadata contains the entity ID and the Assertion Consumer Service (ACS) URL.
Step 2 — Configure the IdP in Tessallite
In the tenant settings, provide:
| Setting | Purpose |
|---|---|
SAML_IDP_METADATA_URL | URL to the IdP's SAML metadata (Tessallite fetches it automatically). Use this OR the XML field below — not both. |
SAML_IDP_METADATA_XML | Paste the IdP metadata XML directly. Use when the metadata URL is not accessible from the Tessallite host. |
SAML_SP_ENTITY_ID | The entity ID Tessallite uses to identify itself. Must match what is registered in the IdP. |
Step 3 — Map attributes
The IdP sends user attributes in the SAML assertion. Tessallite reads three:
| Setting | Default | What it maps to |
|---|---|---|
SAML_ATTR_EMAIL | NameID | The user's email address (used as the primary identifier). |
SAML_ATTR_DISPLAY_NAME | (none) | The user's display name. |
SAML_ATTR_GROUPS | (none) | A multi-valued attribute containing group memberships. Required for group-to-role mapping. |
Defaults work for Auth0 and Google Workspace. Other IdPs may use different attribute names — check your IdP's attribute configuration.
SAML endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/auth/saml/metadata | GET | Returns SP metadata XML for IdP registration. |
/api/v1/auth/saml/login | GET | Initiates the SSO flow (redirects to IdP). |
/api/v1/auth/saml/acs | POST | Receives the SAML assertion from the IdP. |
OIDC setup
Step 1 — Register Tessallite with the IdP
Create an OAuth 2.0 / OIDC client in your IdP. Set the redirect URI to:
GET /api/v1/auth/oidc/callback
Note the client ID and client secret.
Step 2 — Configure the IdP in Tessallite
| Setting | Purpose |
|---|---|
OIDC_ISSUER | The issuer URL. Tessallite fetches .well-known/openid-configuration from this URL to discover endpoints. |
OIDC_CLIENT_ID | The client ID from step 1. |
OIDC_CLIENT_SECRET | The client secret from step 1. Stored Fernet-encrypted at rest. |
OIDC_SCOPES | OAuth scopes to request. Default: openid email profile. |
OIDC_GROUPS_CLAIM | The claim name in the ID token containing group memberships. Default: groups. |
OIDC endpoints
| Endpoint | Method | Purpose |
|---|---|---|
/api/v1/auth/oidc/login | GET | Initiates the authorization-code flow (redirects to IdP). |
/api/v1/auth/oidc/callback | GET | Receives the authorization code, exchanges it for tokens. |
Group-to-role mapping
Both SSO backends extract group memberships from the IdP response (SAML assertion attribute or OIDC ID token claim). Group-to-role mappings tell Tessallite which Tessallite role to assign for each IdP group.
How it works
- On each SSO login, Tessallite reads the user's groups from the IdP response.
- It looks up every group name in the
idp_group_role_mappingstable. - For each match, it creates or updates a
UserAccessBindingentry with the mapped role and project scope. - If none of the user's groups match any mapping, the user inherits the tenant's JIT default role.
Managing mappings
Navigate to Admin > Settings > Group Mappings. Each mapping has three fields:
- IdP group name — the exact group name as sent by the IdP (case-sensitive).
- Project — the project to scope the role to. Leave blank for a tenant-wide mapping.
- Role —
admin,modeler, orviewer.
A group can map to different roles in different projects. A single user who belongs to multiple groups receives the union of all matching roles.
The API is GET/POST/PUT/DELETE /api/v1/admin/group-mappings (tenant admin only).
JIT user creation
When a user authenticates via SSO for the first time and no local user record exists, Tessallite automatically creates one. The new user's:
- Email comes from the SAML assertion or OIDC ID token.
- Display name comes from the mapped attribute/claim (if configured).
- Auth source is set to
samloroidc. - Role is determined by group-to-role mappings, falling back to the JIT default role.
Users with a non-local auth source cannot change their password via Tessallite — the identity provider manages their credentials.
Best practices
- Test with one user first. Enable SSO, sign in yourself, and verify the attribute mapping before rolling out to the team.
- Keep local auth enabled as a fallback. Until SSO is stable, keep
localin theAUTH_BACKENDSlist so administrators can still sign in with credentials if the IdP is unreachable. - Set
SAML_ATTR_GROUPSorOIDC_GROUPS_CLAIMearly. Group-to-role mapping only works when the IdP sends group information. Some IdPs require explicit configuration to include groups in the assertion or token. - Use tenant-wide mappings sparingly. A tenant-wide
adminmapping gives the group admin access to every project. Prefer project-scoped mappings for least-privilege.
Troubleshooting
- "Sign in with SSO" button does not appear. Check that
samloroidcis listed in theAUTH_BACKENDStenant setting and that the IdP configuration fields are non-empty. - "Invalid assertion" error after redirect. The SP entity ID in Tessallite does not match what is registered in the IdP, or the ACS URL is wrong. Compare the SP metadata XML with the IdP's configuration.
- User created but has no project access. The user's IdP groups do not match any entry in group-to-role mappings, and the JIT default role is
viewer(which may have no project bindings). Add the appropriate mapping.