SCIM & SSO
Elido routes enterprise sign-in and user provisioning through WorkOS : SSO covers SAML and OIDC against any major IdP (Okta, Azure AD/Entra, Google Workspace, …) and SCIM covers user lifecycle (create / update / suspend) sourced from the same IdP.
You configure each independently — most teams enable SSO first, then bolt on SCIM once the IdP is wired.
SSO
1. Provision a connection in WorkOS
In the WorkOS dashboard, create an Organization for your customer, then create a Connection (SAML or OIDC) and complete the IdP-side metadata exchange. WorkOS gives you back two IDs:
org_01H...— the Organizationconn_01H...— the Connection
2. Bind them to the workspace
curl -X PUT \
https://api.elido.app/v1/workspaces/1/sso \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"organization_id": "org_01H...",
"connection_id": "conn_01H...",
"domain": "acme.com",
"enabled": true
}'| Field | Notes |
|---|---|
organization_id | Starts with org_. |
connection_id | Starts with conn_. Must be globally unique when enabled. |
domain | Email domain that maps to this connection — alice@acme.com is routed here. Must be globally unique when enabled. |
enabled | Master toggle. |
3. How sign-in resolves
The login page is a single email box. On submit, the web app calls a public discovery endpoint:
GET /v1/sso/discover?domain=acme.com
→ { "connection_id": "conn_01H...", "organization_id": "org_01H..." }If a record exists, the user is bounced to WorkOS for the SAML/OIDC dance. On callback, Elido looks the workspace up by connection ID:
GET /v1/sso/by-connection?id=conn_01H...
→ { "workspace_id": 1 }A Kratos identity is found-or-created by email, a session is minted,
and the user lands on /dashboard. Both lookup endpoints are public —
they have to be, since the caller hasn’t authenticated yet.
Reset
curl -X DELETE \
https://api.elido.app/v1/workspaces/1/sso \
-H "Authorization: Bearer $ELIDO_TOKEN"SCIM
SCIM is a separate WorkOS feature — a Directory bound to the same
Organization as your SSO connection. Once it’s created you’ll have
a directory_xxx ID and a webhook signing secret.
1. Configure
curl -X PUT \
https://api.elido.app/v1/workspaces/1/scim \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"directory_id": "directory_01H...",
"organization_id": "org_01H...",
"webhook_secret": "whsec_a1b2c3...",
"default_role": "viewer"
}'| Field | Notes |
|---|---|
directory_id | WorkOS directory ID. Globally unique. |
organization_id | Optional — match the SSO config when set. |
webhook_secret | HMAC secret used to sign incoming events. Required. |
default_role | Role assigned to provisioned users: owner, admin, editor, viewer. Defaults viewer. |
2. Point WorkOS at Elido
In the WorkOS Directory settings, paste:
Webhook URL: https://api.elido.app/v1/scim/webhookWorkOS signs every event with WorkOS-Signature: t=<ts>,v1=<hmac>.
Elido verifies the HMAC against webhook_secret and rejects
mismatches with 401.
3. What gets synced
| Event | Effect |
|---|---|
dsync.user.created | User row created if missing (by email); workspace membership added with default_role. Emits member.invited. |
dsync.user.updated | Profile fields refreshed. |
dsync.user.deleted | Marks SCIM state suspended; removes workspace membership. Emits member.removed. |
Synced attributes from event.data: id, directory_id,
organization_id, first_name, last_name, emails[*], state.
Newly-provisioned users have an empty Kratos identity until they finish onboarding (set a password, enroll a passkey, or sign in via SSO). They show up in the dashboard list immediately so admins can verify provisioning landed.
Group → role mapping
Not yet — every synced user gets default_role. Group claims may be
exposed in a future release; for now, use custom roles + manual
elevation for users who need more than the default.
List synced users
curl https://api.elido.app/v1/workspaces/1/scim/users \
-H "Authorization: Bearer $ELIDO_TOKEN"Returns every directory user with email, state, the WorkOS
directory_user_id, and the linked Elido user_id (or null if not
yet linked).
Toggle without losing config
curl -X PATCH \
https://api.elido.app/v1/workspaces/1/scim/enabled \
-H "Authorization: Bearer $ELIDO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'Useful when troubleshooting an IdP-side change without revoking the webhook secret.
Endpoint reference
| Method | Path | Auth |
|---|---|---|
GET / PUT / DELETE | /v1/workspaces/{ws}/sso | admin |
GET | /v1/sso/discover?domain=... | public |
GET | /v1/sso/by-connection?id=... | public |
GET / PUT / DELETE | /v1/workspaces/{ws}/scim | admin |
PATCH | /v1/workspaces/{ws}/scim/enabled | admin |
GET | /v1/workspaces/{ws}/scim/users | admin |
POST | /v1/scim/webhook | WorkOS HMAC |