Single sign-on and provisioning
Sondar signs people in through your identity provider — Okta, Microsoft Entra ID, Google Workspace, OneLogin, JumpCloud, Keycloak, Auth0, or anything else that speaks OpenID Connect or SAML 2.0. Both are in Community: logging in safely is not a paid feature.
SCIM 2.0 provisioning lets the identity provider create, update, deactivate and delete Sondar accounts and push groups, so off-boarding someone at the IdP removes their Sondar access too. It is in Pro.
What was tested, and how: OIDC and SAML sign-in end to end against Keycloak 26.0.8 — a real browser, the IdP’s real login, the signed response it really sends. SCIM with the request bodies Okta and Microsoft Entra ID document for their SCIM clients, against a running Sondar. It has not yet been run against a live Okta or Entra tenant; if yours does something this page does not describe, that is a defect we want to hear about.
Where it is configured
Section titled “Where it is configured”Configure → Users & Authentication → Access Control → Login Method:
- Third Party Login — choose OpenID Connect or SAML 2.0 (alongside LDAP, CAS and custom login).
- Provisioning — SCIM.
Only one third-party sign-in method is active at a time. Turning one on switches the others off and keeps their settings, so switching back is one click.
The sign-in page then shows Sign in with your provider’s name and, under it, Sign in with a Sondar account instead — the way in for local accounts, including the administrator, if the identity provider is ever unavailable. Keep at least one local administrator for that.
OpenID Connect
Section titled “OpenID Connect”Register Sondar at your IdP as a confidential web application using the authorization code flow, with the redirect URI the settings page shows:
https://<your-sondar-host>/sso/callbackThen fill in:
| field | what it is |
|---|---|
| Button label | shown as Sign in with …, e.g. Okta |
| Issuer URL | the issuer; Sondar reads <issuer>/.well-known/openid-configuration and refuses a document that names a different issuer |
| Client ID, Client secret | from the IdP; the secret is never shown again (it reads back as ******, and saving ****** keeps it) |
| Scopes | default openid profile email |
| Username claim | the claim that becomes the Sondar username; default preferred_username (use email or upn if that is what your IdP fills in). Pick a claim your IdP’s administrators set and users cannot edit: it is what links a person to an account that exists but has not signed in yet (a SCIM-provisioned one, or one from a previous IdP). If it is email and the IdP marks the address unverified, the sign-in is refused |
| Email claim | default email |
| Groups claim | the claim listing the user’s groups, e.g. groups; empty for none |
| Group to role mapping | one group=role per line |
| Default role | the role every user gets |
| Create accounts on first sign-in | off: only accounts that already exist (created by single sign-on, or provisioned over SCIM) can sign in |
Sondar uses PKCE (S256), a state bound to the browser that started the sign-in,
and a nonce, and verifies the ID token’s signature (RS256/384/512, ES256/384/512)
against the IdP’s published keys, its issuer, audience, expiry and nonce. A
signing-key rotation at the IdP is picked up on the next sign-in.
SAML 2.0
Section titled “SAML 2.0”Register Sondar at your IdP as a service provider with the values the settings page shows, or point the IdP at the metadata URL:
| value | |
|---|---|
| Assertion consumer service URL | https://<your-sondar-host>/api/v1/account/sso/saml/acs (HTTP-POST) |
| Service provider entity ID | your Sondar’s address, unless you set another |
| Metadata URL | https://<your-sondar-host>/api/v1/account/sso/saml/metadata |
The IdP must sign the response or the assertion (or both), with RSA-SHA256 or stronger: a SHA-1 or MD5 signature or digest is refused with a message naming the algorithm (older ADFS and Shibboleth set-ups still default to SHA-1). Do not encrypt the assertion: Sondar refuses an encrypted one with a sentence saying so. The sign-in is started by Sondar (SP-initiated); an IdP-initiated sign-in is not accepted, because nothing would prove the browser asked for it.
Then fill in the Button label, the Identity provider entity ID, its Identity provider sign-on URL (HTTP-Redirect binding), its Identity provider signing certificate (PEM; paste two during a key rotation and either verifies), the attribute names, and the same Group to role mapping, Default role and Create accounts on first sign-in as for OIDC:
| field | default |
|---|---|
| Username attribute | empty: the NameID is the username. As for OIDC, use a value your IdP administers — a persistent NameID or the user’s login — not one users can change |
| Email attribute | e.g. email |
| Groups attribute | e.g. groups |
Sondar checks the signature covers the element it signs (so a second, unsigned
assertion wrapped around a signed one is refused), that exactly one assertion is
present, the audience, the recipient, the response’s InResponseTo, and the
validity window with two minutes of clock skew. Each response can be used once.
Which account a person signs in to
Section titled “Which account a person signs in to”Sondar links an IdP identity to an account by the IdP’s stable subject (the
OIDC sub, the SAML NameID), not by username, so a username reused at the IdP
does not reach someone else’s account.
| situation | result |
|---|---|
| already linked | that account |
| no account of that username | created with the default role, if Create accounts on first sign-in is on |
| an account of that username created by single sign-on (OIDC, SAML or CAS) or SCIM, not yet linked to another identity of this IdP | linked — this covers moving to a new IdP, or between OIDC, SAML and CAS |
| a local password, LDAP or built-in account of that username | refused: it is never taken over. An administrator renames or removes one of them |
CAS sign-in follows the same rules, linking by the CAS username (CAS has no separate subject). CAS single logout is supported: when a user signs out at the CAS server, it calls Sondar back at the service URL and Sondar ends the session that sign-in opened: at once on the server that receives the call, and on the others within about 15 seconds. Register the service with the default back-channel logout type, and give it a fully qualified host name — CAS sends no logout call to a host without a domain.
With a group to role mapping, roles are re-applied from the IdP’s groups at every sign-in, so removing someone from a group at the IdP takes effect at their next sign-in.
When a sign-in is refused, the sign-in page says why:
| message | meaning |
|---|---|
| This sign-in has already been used or was never started here. | a reload of the callback, a replayed response, or a sign-in started on another Sondar |
| This sign-in was started in a different browser; start again here. | the browser finishing it is not the one that started it |
| This sign-in took too long and expired; start again. | more than ten minutes at the IdP |
| A Sondar account named … already exists and was not created by single sign-on, so it is not taken over. | see the table above |
| The ID token’s nonce does not match …, The Assertion has expired, … check both clocks | the IdP’s answer failed a check; the sentence names which |
| The identity provider says this email address is not verified … | the username comes from an email the IdP has not verified; verify it there, or choose another username claim |
| The IdP signs with …rsa-sha1, which Sondar refuses as insecure | switch the IdP’s signing algorithm to RSA-SHA256 |
SCIM provisioning (Pro)
Section titled “SCIM provisioning (Pro)”Configure → Users & Authentication → Access Control → Login Method → Provisioning:
- Generate token. It is shown once — copy it then. Sondar keeps only a hash of it; a lost token is replaced, not recovered. Replacing or revoking it takes effect on every node within seconds.
- Turn Provisioning on and choose the role for new users.
- At your IdP, give the SCIM base URL the page shows
(
https://<your-sondar-host>/api/v1/scim/v2) and the token as an HTTPAuthorization: Bearerheader. In Okta this is the app’s SCIM connector base URL with HTTP Header authentication, anduserNameas the unique identifier; in Entra ID it is the enterprise application’s Provisioning → Tenant URL and Secret Token.
What the IdP can then do:
| at the IdP | in Sondar |
|---|---|
| assign a user | an account is created with the role for new users; it signs in through single sign-on |
| change name or email | the account’s display name, full name and email follow |
| deactivate (unassign, suspend) | the account is frozen: its open sessions end (at once on the server that handled the request, within about 15 seconds on the others) and its API tokens stop working |
| reactivate | it can sign in again |
| delete | the account, its API tokens and its collect tokens are deleted |
| push a group | a group of that name appears under Identity provider in Sondar’s groups |
| change a group’s members | membership follows |
Groups grant roles in Sondar, not at the IdP. On Configure → Users & Authentication → User & Role → Roles, use the + in a role’s User group column to add the pushed group, and every member holds that role — built-in roles included. A membership or role change reaches people already signed in within about fifteen seconds. (Pushed groups also appear in Group Management and in the Users list’s group tree.)
What SCIM can touch. Only accounts an identity provider owns — those created by SCIM or by single sign-on. Local password, LDAP, CAS and built-in accounts, including the administrator, are invisible to it, and a provisioned user may not take one of their names. A leaked token is serious, but it cannot delete your way back in.
Usernames. Up to 50 characters: letters, digits, and _ . @ + -, starting
with a letter or digit — email addresses fit. A username cannot be changed once
created, because it owns the person’s searches, dashboards and alerts; an IdP
that renames a user is refused with a message saying to deprovision the old
name and provision the new one.
When Pro is not active — after a trial or subscription ends — provisioning keeps working in one direction: it can still deactivate and delete users and remove group members, and cannot create, change or add anything. An expired license is never the reason someone who left still has an account.
Supported: Users and Groups (create, read, replace, PATCH, delete), filters
(eq ne co sw ew gt ge lt le pr, and or not, value paths such as
emails[type eq "work"]), paging, attributes and excludedAttributes,
/ServiceProviderConfig, /ResourceTypes and /Schemas. Not supported:
bulk operations, sorting, ETags, password sync (a pushed password is ignored and
never stored), nested groups, and storing enterprise-extension attributes (they
are accepted and ignored, so they do not fail the user).