Skip to main content

Configure SCIM Provisioning with Okta

This guide describes how to configure SCIM provisioning between Okta and AtScale using Keycloak's native SCIM API.

This configuration supports OAuth 2.0 Client Credentials authentication and provides the following user lifecycle operations:

  • User provisioning
  • User profile updates
  • User deactivation and reactivation
  • User import from Keycloak
  • Core user attribute synchronization
Important

Group creation is supported, but Okta group membership synchronization is not compatible with Keycloak's SCIM API. For more information, see Group provisioning limitations below.

Architecture​

Okta acts as the SCIM client and Keycloak acts as the SCIM service provider.

Okta
|
| OAuth 2.0 Client Credentials
|
v
AtScale / Keycloak
|
+-- SCIM API
/auth/realms/atscale/scim/v2
Note

The SCIM endpoint must be reachable from Okta over HTTPS. For the AtScale Keycloak image, the /auth context path is part of the URL and must not be omitted.

Prerequisites​

Before configuring SCIM provisioning with Okta, verify that:

  • You have administrator access for both Keycloak and Okta.
  • AtScale is running Keycloak 26.7.x or later.
  • HTTPS access to the SCIM endpoint is available from Okta.

The SCIM endpoint is https://<atscale-host>/auth/realms/atscale/scim/v2, and the OAuth token endpoint is https://<atscale-host>/auth/realms/atscale/protocol/openid-connect/token.

Enable and configure SCIM provisioning in Keycloak​

First you must enable and configure SCIM provisioning in AtScale's Keycloak instance.

  1. Enable the SCIM API in Keycloak. To do this, add the scim-api to the Keycloak feature's startup arguments. For example:

    keycloak:
    extraStartupArgs: --import-realm --features=token-exchange,admin-fine-grained-authz:v1,opentelemetry-logs,scim-api --log=console --hostname-backchannel-dynamic true

    Once this has been set, the Keycloak startup log should show:

    Preview features enabled: scim-api:v1
  2. Enable SCIM for the atscale realm in Keycloak:

    1. Log in to Design Center and click Security in the sidebar. Keycloak opens.

    2. In the sidebar, under Configure, click Realm settings.

    3. On the General tab, enable the SCIM API option.

      Ensure the realm representation contains:

      {
      "scimApiEnabled": true
      }
  3. Create a Keycloak User Profile attribute for the SCIM external ID. SCIM clients use externalId as an identifier for the user in the external identity provider. For example:

    {
    "name": "myExternalId",
    "displayName": "External ID",
    "multivalued": false,
    "permissions": {
    "view": ["admin"],
    "edit": ["admin"]
    },
    "annotations": {
    "kc.scim.schema.attribute": "externalId"
    }
    }
    important

    The annotation key must be kc.scim.schema.attribute. Using scim.schema.attribute will not work. Keycloak may accept the SCIM request but silently discard the externalId.

  4. Create the SCIM client:

    1. In the sidebar, click Clients.

    2. Click Create client.

    3. On the General settings tab, complete the following fields:

      • Client type: Leave this set to OpenID Connect.
      • Client ID: Enter scim-client.
    4. Click Next.

    5. On the Capability config tab, complete the following fields:

      • Client authentication: Enable this option.
      • Authentication flow: Disable Standard flow (if it is not required for this client), and enable Service accounts roles.
    6. Click Next, then click Save.

  5. Assign the scim-client the manage-users role. This provides the permissions required for the SCIM user lifecycle.

    1. Open the scim-client you just created and go to the Service account roles tab.
    2. Click Assign role.
    3. In the Assign roles to scim-client window, select the manage-users role.
    4. Click Assign.
  6. Configure the OAuth audience. The Keycloak access token used by the SCIM API must contain the SCIM endpoint as its audience. Okta's OAuth configuration does not provide a separate audience field, so this audience must be added by Keycloak.

    To add an Audience protocol mapper to the scim-client:

    1. Open the scim-client and go to the Client scopes tab.

    2. Click the scim-client-dedicated scope.

    3. Click Configure a new mapper and select Audience.

    4. Complete the following fields:

      • Name: Enter a name for the mapper.
      • Included Custom Audience: Enter the SCIM base URL, https://<atscale-host>/auth/realms/atscale/scim/v2.
      • Add to access token: Enable this option.
    5. Click Next, then click Save.

    The resulting access token should contain:

    "aud": [
    "https://<atscale-host>/auth/realms/atscale/scim/v2"
    ]
    Note

    The /auth portion of the URL must be included. If the audience does not exactly match the SCIM base URL, Keycloak will return 401 Unauthorized.

  7. Obtain the client secret for the scim-client. You will need this later when configuring Okta.

    1. Open the scim-client.

    2. Go to the Credentials tab and copy the Client Secret.

      Important

      Do not regenerate the Client Secret.

  8. Verify that the SCIM client can obtain a token and access the SCIM API. For example:

    TOKEN=$(curl -s -X POST \
    https://<atscale-host>/auth/realms/atscale/protocol/openid-connect/token \
    -d grant_type=client_credentials \
    -d client_id=scim-client \
    -d client_secret=<client-secret> |
    jq -r .access_token)

    curl \
    https://<atscale-host>/auth/realms/atscale/scim/v2/ServiceProviderConfig \
    -H "Authorization: Bearer $TOKEN" \
    -H "Accept: application/scim+json"

    The request should return the SCIM service provider configuration with HTTP 200. If it returns a 401, verify that the following are configured as described above:

    • The client secret
    • The manage-users role
    • The Audience mapper
    • The SCIM URL
    • The /auth context path

Enable and configure SCIM provisioning in Okta​

Once you have enabled SCIM in Keycloak, you can configure it in Okta.

Add and configure an Okta Application​

First, you need to create a new application in Okta and enable SCIM provisioning for it.

  1. Open the Okta Admin Console.
  2. Go to Applications and Resources > Applications and click Create App Integration.
  3. Configure the application as needed and add it.
  4. On the General tab for the new application, under App Settings, click Edit.
  5. In the Provisioning field, enable the SCIM option.

Once SCIM is enabled, the Provisioning tab becomes available for the application.

Configure the SCIM connection​

Next, you need to configure the SCIM connection for the application.

  1. Go to the Provisioning tab.

  2. Under Settings > Integration, click Edit.

  3. Complete the following fields:

    • SCIM connector base URL: Enter https://<atscale-host>/auth/realms/atscale/scim/v2.
    • Unique identifier field for users: Enter userName.
    • Authentication Mode: Set to OAuth 2.
    • Grant Type: Set to Client Credentials.
    • Access Token Endpoint: Enter https://<atscale-host>/auth/realms/atscale/protocol/openid-connect/token.
    • Client ID: Enter scim-client.
    • Client Secret: Enter the client secret you copied from Keycloak.
  4. Save your changes.

  5. Click Authenticate with to authenticate the connection.

    Okta may display a message of Authenticate with to enable user import and provisioning features until the OAuth authentication has been completed. Do not proceed until the authentication succeeds.

Enable provisioning operations​

After configuring the SCIM connection, you must enable provisioning operations for the application.

  1. On the Provisioning tab, go to To App and click Edit.

  2. Enable the following options:

    • Create Users
    • Update User Attributes
    • Deactivate Users
  3. (Optional) Depending on your organization's requirements, you can also enable the following:

    • Import New Users
    • Import Profile Updates
    • Push Groups
  4. Save the configuration.

Assign users to the application​

Next, you must assign users to the application.

  1. On the Assignments tab, click Assign and select Assign to People
  2. Select the user that should be provisioned to AtScale.
  3. Save the assignment.

Okta should then create the corresponding Keycloak user through SCIM.

Next, you should configure user attribute mappings in Okta. The following core attributes are handled by the Keycloak SCIM schema.

SCIM AttributeRecommended Okta Attribute
userNameLogin/Username
name.givenNameFirst name
name.familyNameLast name
emails[type eq "work"].valueEmail
activeActive
externalId1Okta user ID

1 For externalId, ensure the Keycloak User Profile attribute is configured as described in step 3 of Enable and configure SCIM provisioning in Keycloak.

Non-core attributes

Additional attributes such as title, department, and jobTitle are not automatically persisted by Keycloak simply because Okta sends them through SCIM. If a non-core attribute needs to be synchronized, create a corresponding Keycloak User Profile attribute and map it to the appropriate SCIM schema attribute. Without the required User Profile configuration, the value may be silently dropped.

Working with provisioning in Okta​

User lifecycle​

Provisioning​

Assign the user to the Okta application. This should have the following result:

Okta
> SCIM POST /Users
> Keycloak user created

The user should appear in Keycloak with the following attributes:

  • Username
  • Email
  • First name
  • Last name
  • externalId
  • Enabled/active state

Profile updates​

When a supported profile attribute is changed in Okta, Okta sends the update through SCIM. The corresponding Keycloak user should receive the updated value.

Deprovisioning​

When a user is unassigned from the Okta application, Okta sends a SCIM deactivation. Note that this disables the Keycloak user; it does not delete them.

Important

Deactivation does not immediately terminate existing Keycloak sessions or already-issued tokens. Existing sessions remain valid until they expire unless they are explicitly terminated.

Import users from Keycloak​

Okta can import users that already exist in Keycloak. On the Provisioning tab in Okta, enable To Okta and configure the required import operations.

Okta retrieves users through GET /Users. Keycloak supports SCIM pagination using startIndex, count, totalResults, and itemsPerPage.

Imported users appear in Okta's import/review flow, rather than automatically becoming active Okta users.

Group provisioning limitations​

Empty groups​

Okta can create an empty group in Keycloak.

Groups with members​

Group membership synchronization with Okta Group Push is not supported with Keycloak SCIM. Okta sends the group together with its members during group create/update operations. Keycloak rejects those requests with the following error:

400 Bad Request
Managing members on updates are not supported

This behavior is caused by the Keycloak SCIM implementation, rather than a configuration issue in Okta. Keycloak accepts group membership changes through SCIM PATCH; for example, PATCH /Groups/{id}. However, Okta's group push flow sends the complete group resource with members, rather than using the PATCH operation expected by Keycloak.

AtScale therefore recommends against relying on Okta SCIM Group Push for AtScale group membership with Keycloak. The existing IdP claim to AtScale group mapping should remain in place where group membership is required.

Group operation support status​

OperationStatus
Create empty groupSupported
Create group with membersNot supported
Update group with membersNot supported
Membership synchronization through Okta Group PushNot supported
SCIM PATCH membership operationSupported

Private network/On-Premises Provisioning​

Direct Okta SCIM provisioning requires the SCIM endpoint to be reachable from Okta Cloud. If you cannot expose the Keycloak SCIM endpoint publicly, you may consider using Okta On-Premises Provisioning (OPP).

Be aware, however, that the Keycloak SCIM API supports OAuth Bearer Token authentication, while the Okta Provisioning Agent supports Basic Authentication, HTTP Header authentication, or no authentication for the SCIM endpoint.

This means that Okta OPP with Keycloak SCIM has an authentication compatibility limitation and should not be considered a supported configuration without an additional authentication proxy or another validated solution.

Note that this is different from the direct cloud-to-cloud configuration documented above.

AtScale administrative accounts​

SCIM-managed users should not include Keycloak/AtScale administrative accounts. Users with realm-management administrative roles are protected by Keycloak's SCIM implementation. For these users, SCIM GET responses may contain only limited user information. SCIM updates and deletion may return a 403. This can result in repeated provisioning failures in Okta.

Due to this, AtScale recommends you exclude administrative users from the Okta SCIM application assignment.

For a standard cloud deployment, AtScale recommends the following configuration:

Okta
|
| OAuth 2.0 Client Credentials
|
v
AtScale Keycloak
|
+-- Native SCIM API
+-- SCIM Client
+-- Audience Mapper
+-- External ID User Profile Attribute

Use the Keycloak's native scim-api implementation.

The custom keycloak-scim-server fork is not required for the standard Okta cloud integration because Okta supports OAuth 2.0 Client Credentials.

Validation checklist​

After configuring SCIM provisioning with Okta, verify the following.

CapabilityExpected Result
OAuth Client CredentialsPASS
SCIM connection testPASS
User provisioningPASS
User profile updatePASS
User deprovisioningPASS
User importPASS
Empty group creationPASS
Group membership pushNot supported