Skip to main content
Okta’s SCIM push sends requests from Okta’s cloud into Genesis, so it needs a public HTTPS route to Genesis. When Genesis runs on a private network with no inbound route from the internet, use the Okta directory sync instead: Genesis reads Okta over an outbound HTTPS connection, the same way it already reaches Okta for sign-in.

What the sync does

  • Every user assigned to the Genesis app in Okta, directly or through a group, becomes a Genesis user before their first sign-in. Name and email changes in Okta are copied over on the next run.
  • A user who already signed in before the first sync, and is assigned to the app in Okta, keeps their existing account: the sync adopts it, matched by email, and manages it from then on.
  • A user who is unassigned from the app, suspended or deactivated in Okta is deactivated in Genesis.
  • Roles come from the same group-to-role mapping Genesis applies at sign-in (GENESIS_GROUP_ROLE_MAPPING_FILE or GENESIS_GROUP_ROLE_MAPPING), using each user’s Okta group names. You do not change that mapping, and sign-in and the sync always agree. A user removed from every mapped group loses the mapped roles, as long as every group named in the mapping exists in Okta. Roles assigned by hand that are not in the mapping are left alone.
  • Synced users behave exactly like SCIM-provisioned users.
The sync runs every 12 hours once enabled. An administrator can also run it at any time with Sync from Okta on Settings → Users.

Set up Okta

  1. In the Okta Admin Console, go to Applications → Applications → Create App Integration and choose API Services. Name it, for example, Genesis directory sync.
  2. Under Client Credentials, set client authentication to Public key / Private key and add a key. Either let Okta generate one and keep the private key, or register the public half of a key you generated (RSA, or EC P-256). Note the key ID if the app has more than one key.
  3. You can leave Require Demonstrating Proof of Possession (DPoP) on; Genesis supports it.
  4. On Okta API Scopes, grant okta.users.read, okta.groups.read and okta.apps.read.
  5. On Admin roles, assign the Read-only Administrator role.
  6. Note the service app’s Client ID, and the ID of the Genesis app your users sign in with. The app ID is in that app’s Admin Console URL (.../admin/app/.../instance/<app id>/...).

Configure Genesis

On Settings → Users, click Set up Okta sync (users with the Manage Users permission see it). Fill in the Okta org URL, the service app’s client ID, the ID of the Genesis app in Okta, and the key ID if the service app has several keys, then paste the service app’s PEM private key as it is, line breaks included. Genesis checks the URL and the key before it saves anything, stores the key as a Genesis secret, and never shows it again. When changing other settings, leave the private-key box blank to keep the stored key; to replace it, paste a new one. To configure Genesis without the UI, for example on Kubernetes, set these environment variables instead: On Kubernetes, put the private key in a Secret and expose it as OKTA_DIRECTORY_SYNC_PRIVATE_KEY; Genesis stores it as a managed secret on first start. A key pasted on one line with literal \n sequences is accepted. Genesis needs outbound HTTPS to the Okta org. Turn on the 12-hour schedule with okta_directory_sync.enabled in Settings → Advanced Settings or the environment variable above; a change to enabled or interval_seconds takes effect at the next restart. Keep GENESIS_SCIM_REQUIRE_PROVISIONED_USERS=false. When it is true, SCIM owns the roles of provisioned users, so the sign-in mapping stops applying to them and roles can no longer be edited by hand.

Run the first sync

Once the connection settings are saved, Sync from Okta appears on Settings → Users and in the setup dialog. It reports how many users were created, updated and deactivated. The same run is available from the API:
GET /api/config/scim/okta-sync returns whether the sync is configured and enabled, which settings are missing, and the result of the last run since the server started.

Safety checks

  • Genesis reads everything it needs from Okta before it changes anything. If any Okta request fails, the run changes nothing and reports the Okta error.
  • If Okta returns no assigned users, or a run would deactivate more than max_deactivation_percent (default 20%) of the provisioned users and more than five users, the run creates and updates users but deactivates nobody, and reports why. When the deactivations are intended, run the sync once with {"allow_mass_deactivation": true}.
  • Users who signed in but are not assigned to the Genesis app in Okta, such as a break-glass administrator, are never touched by the sync.

Troubleshooting