Sign in with your identity provider.
Enterprise SSO connects 24Observe to your existing identity provider over generic OpenID Connect. Any spec-compliant IdP works — Okta, Azure AD, Google Workspace, Auth0, OneLogin. Your team signs in through the provider you already trust, users are provisioned automatically on first login, and offboarding stays where it belongs: in your IdP.
TL;DR
Enterprise SSO connects 24Observe to your existing identity provider over generic OpenID Connect. Any spec-compliant IdP works — Okta, Azure AD, Google Workspace, Auth0, OneLogin. Your team signs in through the pr...
Sign in with your identity provider.
Enterprise SSO connects 24Observe to your existing identity provider over generic OpenID Connect. Any spec-compliant IdP works — Okta, Azure AD, Google Workspace, Auth0, OneLogin. Your team signs in through the provider you already trust, users are provisioned automatically on first login, and offboarding stays where it belongs: in your IdP.
Each organization connects one IdP. Setup is owner-only and lives in the dashboard under Settings → Enterprise SSO (OIDC).
Set it up in 3 steps
- Create an OIDC app at your IdP. Register a new web application
and set its redirect URI to the single fixed 24Observe callback:
https://api.24observe.com/api/v1/auth/sso/callback
The same callback is used for every organization — you only ever register this one URI. - Paste the connection into Settings. Open login.24observe.com → Settings → Enterprise SSO (OIDC) and fill in your Issuer URL, Client ID, and Client secret from the app you just created. Choose a default role, set an optional domain allowlist, flip Enabled on, and save.
- Share the sign-in URL with your team. The dashboard shows a team sign-in URL. Anyone you point at it lands on your IdP, and on success arrives signed in to your org.
Configuration fields
- Issuer URL — your IdP's OIDC issuer, e.g.
https://your-org.okta.com. 24Observe discovers the IdP's endpoints and signing keys from here. - Client ID — the public identifier of the OIDC app you registered.
- Client secret — write-only. It is stored encrypted at rest and never shown again. On update you may leave it blank to keep the existing secret.
- Allowed email domain (optional) — e.g.
acme.com. When set, only identities whose email ends in@acme.commay sign in. Leave blank to allow any identity the IdP authenticates. - Default role — the role granted to users provisioned on first login:
admin,member, orviewer. SSO never grantsowner. - Enabled — the on/off toggle for the connection.
Values to copy into your IdP
The Settings page surfaces two values. Register the first in your IdP app; hand the second to your team.
- Redirect URI — register this exactly, one fixed callback for
every org:
https://api.24observe.com/api/v1/auth/sso/callback
- Team sign-in URL — the entry point your team uses to start a
login:
https://api.24observe.com/api/v1/auth/sso/<your-org-slug>/start
How a login works
- A user visits your team sign-in URL.
- 24Observe responds
302to your IdP's authorization endpoint. - The user authenticates at the IdP and is sent back to the fixed callback.
- We verify the returned
id_tokenagainst the IdP's JWKS — signature, issuer, audience, and nonce all must match. - If an allowed email domain is configured, the identity's email must end in that domain or sign-in is refused.
- We find-or-create the user, ensure they're a member of your org with the configured default role (existing members keep their current role), and issue a 24Observe session.
24Observe never stores the IdP's access or refresh token. We use the
verified id_token to establish identity, then issue our own
session — nothing more.
Azure AD
For Azure AD, use the tenant-specific issuer so audience and issuer validation are unambiguous:
https://login.microsoftonline.com/<tenant-id>/v2.0
The multi-tenant /common endpoint is intentionally not
supported — bind the connection to your tenant.
Management API
The same connection is manageable over the API with an owner PAT or a full-access owner session. The secret is never returned on read.
GET /api/v1/settings/sso— returns the connection without the client secret, plus the teamloginUrl.PUT /api/v1/settings/sso— create or update. Body:{ issuer, clientId, clientSecret?, enabled?, defaultRole?, allowedDomain? }. OmitclientSecretto keep the stored one.DELETE /api/v1/settings/sso— remove the connection.
curl -X PUT https://api.24observe.com/api/v1/settings/sso \
-H 'Authorization: Bearer obs_<owner>' \
-H 'Content-Type: application/json' \
-d '{
"issuer": "https://acme.okta.com",
"clientId": "0oa1b2c3d4e5f6g7h8i9",
"clientSecret": "<from your IdP app>",
"defaultRole": "member",
"allowedDomain": "acme.com",
"enabled": true
}'
# Read it back — note the absent secret and the surfaced loginUrl
curl https://api.24observe.com/api/v1/settings/sso \
-H 'Authorization: Bearer obs_<owner>'
# Response (200)
{
"issuer": "https://acme.okta.com",
"clientId": "0oa1b2c3d4e5f6g7h8i9",
"enabled": true,
"defaultRole": "member",
"allowedDomain": "acme.com",
"loginUrl": "https://api.24observe.com/api/v1/auth/sso/acme/start"
} Security
- The login round-trip is CSRF-protected by an HMAC-signed state cookie paired with a per-login nonce that is checked back against the
id_token. - The client secret is encrypted at rest and is never returned by any read endpoint or shown again in the dashboard.
- The
id_tokenis verified against the IdP's JWKS on every login — signature, issuer, audience, and nonce. - SSO provisions users only into the configured org and can never grant the
ownerrole. Ownership stays a deliberate, human action. - The optional email-domain allowlist gates sign-in to a domain you control.