Okta is a cloud identity and access management platform; Serval connects to it to read and manage users, groups, and applications, run access reviews, and automate identity lifecycle tasks.
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 reach any Okta Management API capability - reading and managing users, groups, and applications, running access reviews, and automating identity lifecycle tasks. Serval also continuously brings your Okta directory into Serval in the background so users, groups, and applications stay up to date.Authentication: OAuth 2.0 client credentials - either a client secret (client_secret_basic) or a private key JWT (private_key_jwt).Data sync: On-demand access to the full Okta Management API from workflows, plus a built-in background directory sync of users, groups (with members), and applications (with their assigned groups).
Any Okta Management API capability can be used from a workflow, with automatic retries on transient errors, pagination handling, and rate-limit awareness.
User lifecycle management
Create users, look up a user by email, deactivate users, and suspend users (which clears their active sessions first, then suspends them). Requires the user read and/or manage scopes.
Group management and membership
Create groups, look up a group by exact name, list all groups, and add or remove a user from a group. Requires the group read and/or manage scopes.
Background directory sync
Continuously brings Okta users, groups (with members), and applications (with their assigned groups) into Serval on a schedule - groups refresh fully every 48 hours with a delta sync every 4 hours; users and apps sync on the standard schedule.
Access management and provisioning
Grants and revokes access by adding or removing users from Okta groups (using the “Member” entitlement). Requires the group manage scope.
Serval connects to an Okta API Services app using OAuth 2.0 client credentials. You can either install Serval from the Okta Integration Network (OIN), which generates credentials for you, or create your own custom Okta API Services app. 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. Full provider guidance lives in Okta’s client credentials grant guide.
Add the integration, review the requested API scopes, and authorize it. Okta generates a Client ID and a Client Secret for your org.
3
Copy the Client Secret immediately
The Client Secret is shown only once. Copy it right away - you will not be able to view it again later.
4
Assign an admin role
Under your admin-role assignments, give the app an admin role such as Super Administrator, a combination like Group / Organization / Application Administrator, or a least-privilege custom role with a resource set. Scopes plus the admin role together govern what Serval can do.
1
Create an API Services app
In the Okta admin console, create a new app integration of type API Services, name it (for example, “Serval”), and save it.
2
Grant API scopes
Grant the required scopes to the app - at minimum the read scopes for users, groups, and apps; add the manage scopes to let Serval take action. Okta groups these under the User, Group, Application, and SystemLog tags.
3
Assign an admin role
Under your admin-role assignments, assign the app an admin role (Super Administrator, a set such as Group / Organization / Application Administrator, or a custom role plus resource set).
A scope alone is not enough. Scopes gate which parts of the API are available; the admin role gates which resources Serval can actually touch.
4
Copy the credentials
Copy the Client ID (shown at the top of the app integration page) and the Client Secret to paste into Serval.
1
Create an API Services app
In the Okta admin console, create a new app integration of type API Services, name it (for example, “Serval”), and save it.
2
Disable DPoP
In the app’s general settings, uncheck the “Require Demonstrating Proof of Possession (DPoP)” option.
Serval does not support DPoP / proof-of-possession. If it is left enabled, token use will be rejected.
3
Switch to public/private key authentication and add a key
Set client authentication to the public-key / private-key method, add a key, generate it, and copy the key. Save it when prompted.
The key is not saved until you confirm it - verify it persisted before leaving the page. The key must be an RSA key.
4
Grant API scopes and assign an admin role
Grant the required scopes and assign the app an admin role under your admin-role assignments, exactly as for the client-secret path.
5
Copy the credentials
Copy the Client ID (shown at the top of the app integration page) and the full generated key to paste into Serval.
Enter your credentials into the Serval connect form. The same fields are used whether you authenticate with a client secret or a private key - Serval automatically picks the right method based on what you paste into the Client Secret field.
1
API Domain (required)
Your Okta domain without the leading “https://” - for example, “yourcompany.okta.com”. Enter the bare host with no scheme and no “-admin” suffix.
Do not paste the admin console URL. If your console shows “yourcompany-admin.okta.com”, strip the “-admin” and enter “yourcompany.okta.com”. An invalid domain shows: “Must be a valid Okta domain (e.g., yourcompany.okta.com)”.
2
Client ID (required)
The OAuth 2.0 client ID from your Okta application - exactly 20 alphanumeric characters. An invalid value shows: “Must be a valid Okta client ID (20 alphanumeric characters)”.
3
Client Secret (required)
This field is masked. Paste either your plain OAuth 2.0 client secret or the full private key you generated in Okta. Serval automatically uses the private-key method when you paste a key, and the client-secret method otherwise.
When editing an existing connection, you can leave this field blank to keep the stored secret unchanged. The stored secret is always shown masked, never in clear text.
4
Scopes (required)
A comma-separated list of OAuth scopes. Serval pre-fills a default set covering app, user, and group read and manage plus log read. These scopes must also be granted on the Okta app itself. Not all of the pre-filled scopes are required - you can remove any scopes you don’t need.
An empty list is rejected. Each scope must follow the expected format, otherwise you will see: “Each scope must follow the format okta.<resource>.<operation> or okta.<resource>.<subresource>.<operation> (e.g., okta.users.read, okta.accessRequests.catalog.read). SSF scopes are ssf.<operation> (e.g., ssf.read, ssf.manage).”
After you connect, Serval runs a series of health checks against your Okta org and reports the result of each one. Each health check is an API call that exercises a specific scope, so the checks always run regardless of which scopes you configured - a check whose scope you removed will simply fail with a missing-scope message. This is expected if you intentionally trimmed the scope list, and you can safely ignore failures for capabilities you don’t plan to use.
List Okta Apps confirms Serval can list applications. On success it reports “Successfully listed” followed by the number of apps found. On failure it reports “Unable to list apps.” If the required scope is missing in Serval, it reports “Missing required scope in Serval: okta.apps.read”.
List Okta Users confirms Serval can list users. On success it reports “Successfully listed” followed by the number of users found. On failure it reports “Unable to list users.” If the scope is missing, it reports “Missing required scope in Serval: okta.users.read”.
List Okta Groups confirms Serval can read groups. On success it reports “Successfully listed” followed by the number of groups found. On failure it reports “Unable to list groups.” If the scope is missing, it reports “Missing required scope in Serval: okta.groups.read”.
Manage Okta Groups creates a temporary test group (named with a “serval-healthcheck-” prefix) and immediately deletes it to verify write access. On success it reports “Successfully created and deleted test group:” followed by the test group’s name. On failure it reports “Unable to create and delete groups.” If the scope is missing, it reports “Missing required scope in Serval: okta.groups.manage”.
When a check fails with a permission error, Serval adds: “The correct scope is configured in Serval, but the OAuth application may need admin consent or additional admin roles in Okta.” When Okta returns a server error, Serval adds: “Okta returned a server error. This is likely a temporary issue with Okta’s API - please try again later.”
The most common surprise: the scope is configured correctly in Serval but a check still fails with a permission error. This almost always means the Okta app is missing the admin role (or admin consent). Assign the app an admin role under your admin-role assignments - a scope on its own is not enough.
A health check fails on permissions even though the scope is set in Serval
Scopes typed into the Serval form are only the scopes requested on the token. They must also be granted on the Okta API Services app, and the app must be assigned an admin role (or a custom role plus resource set). Scopes gate which part of the API is available; the admin role gates which resources can be acted on. Add the missing scope on the Okta app and assign it an admin role under your admin-role assignments.
EMEA (okta-emea.com) domains fail at request time
Serval only connects to “okta.com” and “oktapreview.com” hosts. The connect form’s validation will accept an “okta-emea.com” domain, but requests to EMEA-cell domains will fail once they actually run. Use an “okta.com” or “oktapreview.com” domain.
The API Domain is rejected or requests go to the wrong host
The API Domain field expects a bare host such as “yourcompany.okta.com”. Do not include “https://”, and do not copy the admin console URL - “yourcompany-admin.okta.com” is wrong; strip the “-admin” to get “yourcompany.okta.com”. The domain is used as both the token host and the API base, so a wrong value breaks everything downstream.
Private key authentication isn't being used (or fails)
Serval decides between the plain-secret and private-key methods purely by whether the Client Secret value is a key (in JSON form). For key-based authentication, paste the full key into the Client Secret field; anything that is not a JSON key is treated as a plain client secret. The key must be an RSA key - a non-RSA key fails token generation with “key is not an RSA private key”.
Tokens are rejected after enabling private key auth
Serval does not support DPoP / proof-of-possession. In the custom API Services app’s general settings, uncheck the “Require Demonstrating Proof of Possession (DPoP)” option before connecting, otherwise token use will be rejected.
Updating the connection wiped or kept the secret unexpectedly
On update, Serval still requires Scopes, Client ID, and API Domain, but the Client Secret is optional. Leave it blank to keep the existing stored secret unchanged, or paste a new value to replace it. The stored secret is always returned masked.
Requests are being throttled / rate limited
Okta enforces roughly 250 requests per minute per application on the groups and apps endpoints. Serval paces background syncs to stay under this limit and automatically retries when throttled, but heavy custom workflows against these endpoints can still hit Okta’s rate limits.
Need help? Contact support@serval.com for assistance with your Okta integration.