About Okta
Okta is a cloud identity and access management (IAM) platform for managing users, groups, and application access. Serval connects to Okta using OAuth 2.0 client credentials against an Okta API Services app. Once connected, Serval can:- Keep your Okta users, groups (with members), applications, and sign-in activity in sync with Serval in the background.
- Grant and revoke access by adding users to and removing them from Okta groups.
- Call any Okta Management API endpoint from workflows, including a set of prebuilt Okta workflows you can install.
private_key_jwt).
Data sync: Scheduled background syncs of users, groups and memberships, applications and their assigned groups, and last-login activity. Optionally, Okta event hooks push user and group changes to Serval in real time.
Get your credentials
Serval connects to an Okta API Services app using OAuth 2.0 client credentials. Depending on your Serval deployment, the Okta connect dialog offers Use Serval App (install Serval from the Okta Integration Network, which generates a Client ID and Client Secret for you) and Custom Application (create your own Okta API Services app using an RSA private key). In both cases you must grant the required scopes on the Okta app and assign the app an admin role so those scopes can actually act on resources.- OIN install (recommended)
- Custom app - private key
Open the Serval listing
Configure and authorize the integration
Copy the Client Secret immediately
Assign an admin role
Continue in Serval
Connect in Serval
Enter your credentials into the Serval connect form. For an OIN installation, use the generated Client Secret. For a custom API Services app, use the RSA private JWK. Serval automatically selects the authentication method based on what you paste into the Client Secret field.API Domain (required)
Client ID (required)
Client Secret (required)
{; do not paste a PEM key beginning with -----BEGIN PRIVATE KEY-----.Scopes (required)
Verifying the connection
After connecting, review List Okta Apps, List Okta Users, and List Okta Groups for the syncs you plan to use. Manage Okta Groups verifies write access by creating and deleting a temporary group. If you intentionally omitted a scope, its check reports “Missing required scope in Serval: <scope>”; that failure does not prevent features covered by your other scopes from working.Health checks and troubleshooting messages
Health checks and troubleshooting messages
- If Serval couldn’t get a token at all: “Serval could not obtain an Okta access token with the stored credentials — the Okta API itself was never called.”
- On a permission error: “The correct scope is configured in Serval, but the OAuth application may need admin consent or additional admin roles in Okta.”
- On an Okta server error: “Okta returned a server error. This is likely a temporary issue with Okta’s API - please try again later.”
What the Okta integration enables
Scopes and what they unlock
Serval requests every scope in the connect form’s Scopes field when it gets a token, and each one must also be granted on the Okta app. The default set isokta.apps.read, okta.apps.manage, okta.users.read, okta.users.manage, okta.groups.read, okta.groups.manage, and okta.logs.read. Remove the ones you don’t need.
What Serval syncs
Each sync has its own toggle on your Okta integration’s Settings tab in Serval. Only organization admins can change the User Sync and Last Login Sync settings.managerId, manager_id, or manager (in that order), and the manager email from managerEmail, ManagerEmail, manager_email, or managerEmailAddress, falling back to a manager ID field that contains an email address. To change how users sync, install the Okta User Ingestion workflow and attach it to your Okta integration as a custom user sync.
Groups you just created: When you pick a linked Okta group for a role and the group isn’t listed yet, use the “Group missing? Import it straight from your identity provider:” option to import it immediately instead of waiting for the next sync. The lookup matches groups whose name starts with what you typed.
Installable workflows
Browse workflow bundles
Browse workflow bundles
Real-time sync with event hooks
By default, Serval learns about changes in Okta on the sync schedule above, so a change can take hours to appear. With an Okta event hook configured, Okta notifies Serval when a user or group changes, and Serval re-fetches just that user or group - changes typically appear in Serval within seconds. This is optional and additive: the scheduled syncs keep running either way and catch anything the hook misses. Event hooks use the scopes your user and resource syncs already use; no extra scopes are needed. One hook carries both user and group events, but Serval only acts on events for syncs you’ve turned on - user events need User Sync, group events need Resource Sync.Copy the webhook details from Serval
Create the event hook in Okta
- URL: the Webhook URL copied from Serval.
- Authentication field:
X-Webhook-Secret - Authentication secret: the Secret copied from Serval.
- Custom header fields: leave empty.
Subscribe to events
- User created (
user.lifecycle.create) - User activated (
user.lifecycle.activate) - User deactivated (
user.lifecycle.deactivate) - User suspended (
user.lifecycle.suspend) - User unsuspended (
user.lifecycle.unsuspend) - User’s Okta profile updated (
user.account.update_profile)
- Group created (
group.lifecycle.create) - Group profile updated (
group.profile.update) - User added to group (
group.user_membership.add) - User removed from group (
group.user_membership.remove)
- Group imported from a directory (
system.import.group.create) - Group deleted from a directory (
system.import.group.delete) - Group imported or updated from an app (
app.user_management.user_group_import.upsert_success) - Directory group member imported or removed (
app.user_management)
- Events that name one user or group refresh exactly that user or group. Any other
user.*orgroup.*event you subscribe to works the same way. - Directory group deletes remove the group from Serval only after Okta confirms it no longer exists.
- App import events (
app.user_managementandapp.user_management.user_group_import.upsert_success) that don’t name a single group are batched for about 30 seconds, then Serval runs one incremental sync of recently changed groups and their members. Only successful events count; ones Okta marks as failed are ignored. - Directory import create and delete events (
system.import.group.createandsystem.import.group.delete) must name the group as aUserGrouptarget. If the target is missing, nothing refreshes until the next scheduled group sync. - Native group deletion (
group.lifecycle.delete) isn’t acted on from the hook; the next scheduled group sync removes the group. - Directory group renames (
system.import.group.update) can’t be sent through Okta event hooks. Serval picks them up on the next incremental group sync.
Verify the hook
Gotchas and troubleshooting
Okta returns HTTP 401 invalid_client and says private_key_jwt is required
Okta returns HTTP 401 invalid_client and says private_key_jwt is required
okta.* management scopes cannot authenticate to the Org Authorization Server with a Client ID and Client Secret. In the app’s Client Credentials settings, select Public key / Private key, generate and save an RSA key, and paste the complete private JWK object into Serval’s Client Secret field. When editing an existing Serval connection, do not leave the field blank: a blank value preserves the previously stored client secret.A health check fails on permissions even though the scope is set in Serval
A health check fails on permissions even though the scope is set in Serval
Everything fails after adding a scope in Serval
Everything fails after adding a scope in Serval
invalid_scope) and every sync, health check, and workflow fails. Grant the scope in Okta, or remove it from the Serval scope list.Granting or revoking access fails with "No user found with email"
Granting or revoking access fails with "No user found with email"
EMEA (okta-emea.com) domains fail at request time
EMEA (okta-emea.com) domains fail at request time
The API Domain is rejected or requests go to the wrong host
The API Domain is rejected or requests go to the wrong host
Private key authentication isn't being used (or fails)
Private key authentication isn't being used (or fails)
{ and include the private-key parameters and the kid matching the public key registered on the same Okta app. A PEM value beginning with -----BEGIN PRIVATE KEY----- is treated as a plain client secret and can produce an HTTP 401 (invalid_client) response. A non-RSA JWK fails token generation with “key is not an RSA private key”. If the Okta interface exposes only PEM, contact support@serval.com without attaching the key.Tokens are rejected after enabling private key auth
Tokens are rejected after enabling private key auth
invalid_dpop_proof.Editing the connection and the stored secret
Editing the connection and the stored secret
invalid_client after you change the Client ID, re-enter both the Client ID and the secret.Disconnecting Serval doesn't revoke access in Okta
Disconnecting Serval doesn't revoke access in Okta
Requests are being throttled / rate limited
Requests are being throttled / rate limited
A custom workflow paging the System Log never finishes
A custom workflow paging the System Log never finishes
sortOrder=ASCENDING with no until), Okta’s /api/v1/logs endpoint keeps returning a “next” link, even when no new events are available. A one-time export should stop when it receives an empty page; a continuous poller should wait and resume from that link. Bounded queries with both since and until have a final page with no “next” link. Always follow the returned links rather than constructing page cursors yourself.Event hook verification fails in Okta
Event hook verification fails in Okta
The event hook is verified but changes don't appear in Serval
The event hook is verified but changes don't appear in Serval
- Confirm the hook is subscribed to the events listed in Real-time sync with event hooks - a verified hook with no matching subscriptions delivers nothing useful.
- Confirm User Sync (for user events) or Resource Sync (for group events) is on in Serval. Events for a sync that’s off are accepted but ignored.
- Check Okta’s System Log for failed event hook deliveries. If deliveries fail with HTTP 401, the secret doesn’t match: re-copy the Secret from Serval and update the hook’s authentication secret.
Need help? Contact support@serval.com for assistance with your Okta integration.

