Provision users from Okta via SCIM
DQ Cloud exposes a SCIM 2.0 endpoint at https://<your-host>/scim/v2 so Okta can push user and group lifecycle events directly. With this in place, joining or leaving a team in Okta provisions or deprovisions the user in DQ Cloud without an admin touching the settings page.
Goal
Connect Okta to DQ Cloud so:
- A new joiner assigned to the DQ Cloud app in Okta lands as a
usersrow +org_membershipsrow in your org, defaulted to theeditorrole. - A leaver removed from the app loses their org membership (and any workspace memberships in that org). Their global account stays put — they may still belong to other tenants on the same deployment.
- An Okta group push lands a DQ Cloud workspace; group members become workspace members.
Prereqs
- Org-owner or admin role in DQ Cloud.
- Okta with permission to create SCIM app integrations.
- DQ Cloud reachable from Okta over HTTPS (Okta cannot read from
localhost).
1. Mint a SCIM bearer in DQ Cloud
SCIM endpoints authenticate with a long-lived dqs_ bearer token, minted per IdP.
- Settings → SCIM provisioning → Add token.
- Give it a name (
okta-prodis conventional) and click Create. - Copy the
dqs_...value — it is shown exactly once. If you lose it, revoke this row and create another.
Under the hood, this calls:
curl -X POST https://dq.example.com/api/v1/organizations/<org-id>/scim-tokens \
-H "Authorization: Bearer <your-jwt>" \
-H "Content-Type: application/json" \
-d '{"name": "okta-prod"}'
Step-up authentication is required — you will be re-prompted for your password before the token is minted (HARDEN-24).
2. Create the SCIM app in Okta
- In Okta, Applications → Browse App Catalog → SCIM 2.0 Test App (OAuth Bearer Token) (or your existing SCIM-aware DQ Cloud app integration).
- General Settings: set the Application label to "DQ Cloud" and finish the create wizard with default values.
- Go to the Provisioning tab and click Configure API Integration.
- Check Enable API integration and fill in:
- Base URL:
https://dq.example.com/scim/v2 - API Token: the
dqs_...you copied above - Username for unique-attribute check:
userName
- Base URL:
- Click Test API Credentials. Okta calls
GET /scim/v2/ServiceProviderConfig; a green check means the bearer is good. If it fails, double-check that the token starts withdqs_and that you haven't accidentally revoked it. - Save.
3. Enable the provisioning actions
In the Provisioning tab, switch on the following under To App:
- Create Users — Okta will
POST /scim/v2/Usersfor every assignment. - Update User Attributes — every Okta profile change calls
PATCH /scim/v2/Users/{id}. - Deactivate Users — Okta sends
PATCH ... active=false, which DQ Cloud treats as "remove org membership".
Sync Password should stay off — DQ Cloud uses SSO (or, for self-hosted, email + password) for authentication; SCIM only does provisioning.
4. Map Okta attributes
The default Okta-to-DQ-Cloud mapping covers everything the test matrix asserts. If you need to adjust:
| Okta profile field | SCIM attribute | DQ Cloud column |
|---|---|---|
user.email | userName, emails[type=work].value | users.email |
user.firstName | name.givenName | first token of users.full_name |
user.lastName | name.familyName | remainder of users.full_name |
| Okta lifecycle status | active | presence of org_memberships row |
DQ Cloud normalises userName to lowercase before storing — if you push the same person to two tenants with different casing, they will still land on the same global users row.
5. Assign users
In Okta, Assignments → Assign → either individual users or a group. Okta runs through:
GET /scim/v2/Users?filter=userName eq "<email>"— to check if the user already exists.- If 0 results:
POST /scim/v2/Userswith the full payload. - If 1 result: skips create and treats the user as already-provisioned.
DQ Cloud is idempotent on userName within an org: re-pushing an existing user returns HTTP 409 with scimType=uniqueness, which Okta logs and continues past.
6. (Optional) Push groups → workspaces
In Push Groups → + Push Groups, select the Okta groups to mirror. DQ Cloud maps:
- One Okta group ↔ one DQ Cloud workspace.
- Group members ↔
workspace_membershipsrows (default roleeditor). - Renaming the Okta group →
PATCH /Groups/{id}updates the workspacedisplayNameandslug.
If a member is in the pushed group but not yet provisioned to the org as a user, DQ Cloud auto-provisions the org_memberships row at the same time so the workspace membership has somewhere to attach.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Okta "Test API Credentials" returns 401 | Bearer was revoked or copy-pasted with whitespace. Mint a new one in DQ Cloud and update the integration. |
Provisioning a user returns 409 uniqueness | The same userName already has an org_membership row. This is normal for re-assignments. |
Okta reports 409 when pushing a group | A workspace with the same displayName already exists in the org — delete the dupe (or rename it) and retry. |
PATCH returns 400 invalidPath | Okta sent a path we don't model (rare; usually a custom attribute mapping). Open an issue against FEATURE-90 with the failing payload. |
Member value ids in a group push look like Okta uids, not DQ Cloud UUIDs | The Okta admin enabled "Push group memberships" before the users themselves were pushed. Run a full user sync first. |
Revoking the connector
When you decommission the Okta integration:
- Disable provisioning in Okta (Provisioning tab → Edit → uncheck all actions).
- In DQ Cloud, Settings → SCIM provisioning → Revoke next to the token row. Revoking is immediate — the next SCIM call from Okta returns 401 within ~5 s (the auth cache TTL).
Related
- Configure single sign-on — pair SCIM provisioning with SAML/OIDC sign-in for the full enterprise flow.
- Multi-tenancy concept — orgs, workspaces, and role semantics SCIM lands on.
- FEATURE-90 — the tracking ticket.