logo

Using SCIM 2.0 with Skycloak (Managed Keycloak)

Introduction

Keycloak SCIM integration enables automated user provisioning and lifecycle management across applications using the SCIM 2.0 standard. When combined with Skycloak, a fully managed Keycloak IAM platform, SCIM can be securely exposed using external JWT-based authentication, making it ideal for integrations with third-party identity providers.

In this article, we demonstrate how to configure SCIM 2.0 in Keycloak using Skycloak, focusing on the EXTERNAL authentication mode. This approach allows an external Identity Provider (IdP) to act as the SCIM client while Keycloak functions as the SCIM server, validating incoming requests using JWTs and a JWKS endpoint.

SCIM (System for Cross-domain Identity Management) is an open standard that simplifies identity lifecycle management by providing a common REST/JSON interface for creating, updating, and deleting users and groups. Integrating SCIM with Keycloak helps organizations automate onboarding and offboarding processes, reduce manual user management, and maintain consistency across distributed systems.

Using Postman, we walk through practical SCIM operations such as user creation, update, retrieval, and deletion, while highlighting Skycloak-specific configuration details.

Brief Overview

Skycloak supports SCIM through a custom SCIM 2.0 server extension, available via its Extensions marketplace.

The SCIM extension supports two authentication modes:

  • KEYCLOAK
  • EXTERNAL

In this article, we focus on the EXTERNAL authentication mode and demonstrate SCIM operations by making REST calls using Postman.
In real-world scenarios, the SCIM client is typically an external Identity Provider (IdP) such as Entra ID, Auth0, or Ping Identity.

SCIM Configuration Levels

The SCIM extension can be configured at multiple levels:

  • Instance level
  • Realm level (override instance settings)
  • Organization level

This article covers instance-level configuration and briefly explains how to override the configuration at the realm level toward the end.

For more details on this extension, please refer to the SCIM extension documentation available here.

Configuration Steps

The setup involves two major steps:

  1. Configuration at the external Identity Provider
  2. Configuration at the Keycloak (Skycloak) level

This article does not go into detail on step 1.
For testing purposes, an access token was obtained from an external IdP (Auth0), and the following values were used during configuration:

  • Token issuer
  • Audience
  • JWKS URL

Configuring SCIM at the Skycloak Level

Step 1: Install the SCIM Extension

  1. Navigate to the Skycloak Console
  2. Ensure you are working in the correct cluster
  3. Go to: Extensions -> Install SCIM 2.0 Server for Keycloak

Provide the following inputs:

  • Authentication mode: EXTERNAL
  • External JWT issuer URL: Issuer of the SCIM client token
  • External JWT audience: Expected audience claim
  • JWKS URL: URL used to validate the incoming JWT signature

After installation, the extension will appear under Installed Extensions.

Verify Installation

Invoke the following request using Postman:

GET https://<skycloak_hostname>/realms/<realm_name>/scim/v2/ServiceProviderConfig
  • Without a valid Bearer token, the response should be:
    401 Unauthorized

This confirms that the SCIM endpoint is active and protected.

Testing the Integration

As per the SCIM extension documentation, a role named scim-managed must exist.
Only users assigned this role are returned when querying users via SCIM.

We check couple of use cases for users.

As mentioned in the SCIM extension documentation, scim-managed role to be created so that a GET call for Users will succeed to give user list (it will give only users with scim-managed role)

Create User

Request

POST https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users

Headers:

  • Authorization: Bearer <access_token>
  • Content-Type: application/scim+json

Payload

{
  "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
  "userName": "jane.doe",
  "name": {
    "givenName": "Jane",
    "familyName": "Doe"
  },
  "emails": [
    {
      "value": "[email protected]",
      "primary": true
    }
  ],
  "active": true
}

We should get 201 Created as response.

Response

  • 201 Created

Sample response payload:

{
    "id": "0332f6fb-5d48-478f-99db-b29f30562014",
    "userName": "jane.doe",
    "name": {
        "givenName": "Jane",
        "familyName": "Doe"
    },
    "emails": [
        {
            "value": "[email protected]",
            "primary": true
        }
    ],
    "active": true,
    "schemas": [
        "urn:ietf:params:scim:schemas:core:2.0:User"
    ],
    "meta": {
        "location": "https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users/0332f6fb-5d48-478f-99db-b29f30562014",
        "resourceType": "User",
        "created": 1742947200000,
        "lastModified": 1743033600000
    }
}

Get a specific user

GET https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users/{id}
  • Provide a valid Bearer token
  • Response: 200 OK

Update User

PATCH https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users/{id}

Headers:

  • Authorization: Bearer <access_token>
  • Content-Type: application/scim+json

Payload:

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
  "Operations": [
    {
      "op": "replace",
      "path": "active",
      "value": false
    }
  ]
}

Response

Response:

  • 200 OK
  • User status is updated to inactive

Delete User

DELETE https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users/{id}

Response:

  • 204 No Content
  • User is deleted successfully

Get Users

GET https://<skycloak_hostname>/realms/<realm_name>/scim/v2/Users

Response:

  • 200 OK
  • Returns only users with the scim-managed role

Override SCIM Configuration at Realm Level (Optional)

Instance-level SCIM settings can be overridden per realm

  1. Obtain an access token from Keycloak using OIDC Client Credentials Grant for a realm-level client. We use it in the below PUT call.
  2. Assign the following roles to the client’s service account:
    • realm-admin
    • manage-realms

Invoke:

PUT https://<skycloak_hostname>/admin/realms/acme

Headers:

  • Authorization: Bearer <access_token>
  • Content-Type: application/json

Payload

{
  "attributes": {
    "scim.authentication.mode": "EXTERNAL",
    "scim.external.issuer": "string",
    "scim.external.jwks.uri": "string",
    "scim.external.audience": "string"
  }
}

Replace the values with the correct issuer, JWKS URL, and audience.

Summary

In this article, we demonstrated how to configure and test SCIM functionality with Skycloak using details from an external Identity Provider and Postman.

Skycloak is a fully managed Keycloak hosting solution that simplifies deploying and operating Keycloak in production environments, allowing teams to focus on identity integrations rather than infrastructure and maintenance.

If you’re new to Skycloak, visit the Skycloak Getting Started Guide to learn more.

Leave a Comment

Β© 2025 All Rights Reserved. Made by Yasser