Skip to content

Okta outbound user lifecycle (Floh → Okta)

Push create, update, and deactivate from Floh into an Okta directory using the built-in okta connector and the Okta Management API.

Not the generic scim connector. Okta orgs do not serve https://<org>.okta.com/scim/v2 (that URL returns 404). Okta is a SCIM client when provisioning to apps; Floh inbound SCIM is documented in Okta setup for Floh.

Topic Document
Connector reference Okta directory connector
Inbound (Okta → Floh) Okta setup for Floh
Other IdPs (SCIM) Outbound SCIM connector
Entitlements / role_grant Roles & entitlements

What Floh sends to Okta

Floh command Okta Management API Effect
createUser POST /api/v1/users New user (activate defaults to true)
updateUser POST /api/v1/users/{id} Profile update
deactivateUser POST /api/v1/users/{id}/lifecycle/deactivate Deprovision
getUser GET /api/v1/users/{idOrLogin} Lookup
checkUserActive GET /api/v1/users/{id} status === ACTIVE

Implementation: packages/server/src/modules/connectors/handlers/okta-support/user-commands.ts.


1. Okta prerequisites

  1. Developer or production org — same org as OIDC is fine; this is separate from inbound SCIM.

  2. API tokenSecurity → API → Tokens → Create token. Use a token that can create, read, update, and deactivate users (super-admin token is typical in dev).

  3. Org URL (not the Admin Console host):

https://<your-org>.okta.com

Example: https://integrator-5887742.okta.comnot https://integrator-5887742-admin.okta.com.

  1. Floh egress to *.okta.com over HTTPS.

2. Create the Floh okta connector instance

UI: Connectors → New Connector → Built-in → type okta

Field Value
orgUrl https://<your-org>.okta.com
apiToken Okta API token (secret)

Test: run test (GET /api/v1/users?limit=1 with SSWS auth).


3. Field mapping

Floh createUser param Okta profile Notes
userName (required) login Work email
email email Defaults to userName
givenName / familyName firstName / lastName Default User / Account if omitted
displayName displayName Optional
department / title department / title Optional
active ?activate= query Default true
sendEmail ?sendEmail=true Default false
linkExistingOnConflict Default true (idempotent create)

4. Manual smoke test (Commands tab)

Create

{
  "command": "createUser",
  "userName": "scim-test@example.com",
  "givenName": "SCIM",
  "familyName": "Test",
  "email": "scim-test@example.com",
  "active": true,
  "sendEmail": false
}

Confirm the user in Directory → People.

Update

{
  "command": "updateUser",
  "id": "<okta-user-id-from-create>",
  "displayName": "SCIM Test Updated",
  "title": "Engineer"
}

Deactivate

{
  "command": "deactivateUser",
  "id": "<okta-user-id>"
}

Verify

{
  "command": "checkUserActive",
  "id": "<okta-user-id>"
}

Expect isActive: false after deactivate.


5. Workflow example (onboarding)

Use a connector workflow step with your okta instance and command createUser. Map workflow variables into userName, givenName, familyName, and email. Store the returned userId in a run variable for later steps.

Offboarding: deactivateUser with id set to the Okta user id saved at provision time.


6. Entitlements caveat

deactivateUser requires the Okta id (00u…), not the login email. Until entitlement deprovision passes entitlement_instance.external_id into connector config, resolve the id with getUser (userName) before deactivate in workflows.


7. Troubleshooting

Symptom Likely cause Fix
404 on connector test Used scim connector or /scim/v2 base URL Switch to okta connector and orgUrl only
404 with correct okta connector Rare — wrong org hostname Use https://<org>.okta.com without -admin
401 / 403 Token lacks permissions Create token with user lifecycle permissions
Duplicate login on create User already exists Enable linkExistingOnConflict (default) or use getUser first

curl sanity check (replace org and token):

curl -sS -o /dev/null -w "%{http_code}\n" \
  -H "Authorization: SSWS YOUR_TOKEN" \
  -H "Accept: application/json" \
  "https://integrator-5887742.okta.com/api/v1/users?limit=1"

Expect 200, not 404.