Skip to main content

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 users row + org_memberships row in your org, defaulted to the editor role.
  • 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.

  1. Settings → SCIM provisioning → Add token.
  2. Give it a name (okta-prod is conventional) and click Create.
  3. 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

  1. In Okta, Applications → Browse App Catalog → SCIM 2.0 Test App (OAuth Bearer Token) (or your existing SCIM-aware DQ Cloud app integration).
  2. General Settings: set the Application label to "DQ Cloud" and finish the create wizard with default values.
  3. Go to the Provisioning tab and click Configure API Integration.
  4. 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
  5. 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 with dqs_ and that you haven't accidentally revoked it.
  6. Save.

3. Enable the provisioning actions

In the Provisioning tab, switch on the following under To App:

  • Create Users — Okta will POST /scim/v2/Users for 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 fieldSCIM attributeDQ Cloud column
user.emailuserName, emails[type=work].valueusers.email
user.firstNamename.givenNamefirst token of users.full_name
user.lastNamename.familyNameremainder of users.full_name
Okta lifecycle statusactivepresence 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:

  1. GET /scim/v2/Users?filter=userName eq "<email>" — to check if the user already exists.
  2. If 0 results: POST /scim/v2/Users with the full payload.
  3. 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_memberships rows (default role editor).
  • Renaming the Okta group → PATCH /Groups/{id} updates the workspace displayName and slug.

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.

Trouble­shooting

SymptomLikely cause
Okta "Test API Credentials" returns 401Bearer was revoked or copy-pasted with whitespace. Mint a new one in DQ Cloud and update the integration.
Provisioning a user returns 409 uniquenessThe same userName already has an org_membership row. This is normal for re-assignments.
Okta reports 409 when pushing a groupA workspace with the same displayName already exists in the org — delete the dupe (or rename it) and retry.
PATCH returns 400 invalidPathOkta 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 UUIDsThe 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:

  1. Disable provisioning in Okta (Provisioning tab → Edit → uncheck all actions).
  2. 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).