This module allows Anjana Data to connect to a Keycloak realm to download and synchronize users via the Admin REST API.
The synchronization retrieves all active users from the configured realm, including their standard attributes (username, email, firstName, lastName) and any custom attributes (User Profile).
Part 1: Configuration in Keycloak Admin Console
For Anjana to be able to read users, you need to create a confidential client with a service account and assign it the appropriate read permissions.
Step 1: Create the provisioning client
-
Access the Keycloak Admin Console and select the realm from which you want to synchronize users.
-
Go to Clients > Create client.
-
Configure the basic fields:
-
Client type:
OpenID Connect -
Client ID: Set a descriptive name, e.g.
anjana-provisioning
-
-
On the Capability config screen:
-
Client authentication:
ON(confidential mode, required to obtain the secret) -
Service accounts roles:
ON(enables the service account for this client) -
Authorization:
OFF
-
-
Click Save.
-
On the Credentials tab, copy the Client Secret.
Step 2: Assign the view-users role
The client's service account needs the view-users role from the internal realm-management client.
-
With the newly created client open, go to the Service accounts roles tab.
-
Click Assign role.
-
In the filter dropdown, select Filter by clients.
-
Search for
realm-managementand select theview-usersrole. -
Click Assign.
Why realm-management? Keycloak manages administrative permissions through the internal realm-management client. The view-users role grants read-only access to the realm's user list without granting write or administration permissions.
Step 3: Verify access
You can verify that the credentials are correct with the following call:
# 1. Get access token
TOKEN=$(curl -s -X POST \
"https://<keycloak-server>/realms/<realm>/protocol/openid-connect/token" \
-d "grant_type=client_credentials" \
-d "client_id=anjana-provisioning" \
-d "client_secret=<client-secret>" | jq -r '.access_token')
# 2. List users (should return a JSON array)
curl -s -H "Authorization: Bearer $TOKEN" \
"https://<keycloak-server>/admin/realms/<realm>/users?max=5"
Part 2: Configuration in application.yml
Edit the Anjana configuration file and include the data obtained in the security.provisioning.providers.keycloak section.
security:
provisioning:
providers:
keycloak:
# Unique key to identify this provider (can be any name, e.g: keycloak-corp)
keycloak-corp:
# Base URL of the Keycloak server (without the realm)
server-url: "https://sso.mi-dominio.com"
# Name of the realm from which users will be synchronized
realm: "mi-realm"
# Client ID of the client created in Step 1
client-id: "anjana-provisioning"
# Client Secret obtained in Step 1
client-secret: "${KEYCLOAK_PROVISIONING_SECRET}"
Multiple realms: If you need to synchronize users from several realms, add one entry per realm with a different key:
keycloak:
keycloak-corp:
server-url: "https://sso.mi-dominio.com"
realm: "corp"
client-id: "anjana-provisioning"
client-secret: "..."
keycloak-partners:
server-url: "https://sso.mi-dominio.com"
realm: "partners"
client-id: "anjana-provisioning"
client-secret: "..."
Synchronized attributes
The following fields are obtained from the GET /admin/realms/{realm}/users endpoint. All standard and custom attributes are available for field-mapping.
|
Anjana Field |
Keycloak Field (default) |
Notes |
|---|---|---|
|
|
|
If empty, email is used as fallback |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Custom user attribute (from |
|
|
|
Custom user attribute (from |
Custom attributes: For phoneNumber and title to be synchronized, they must exist as user attributes in Keycloak. You can add them under Realm Settings > User profile or directly in each user's profile.
Custom field mapping (field-mapping)
Anjana includes a default mapping that covers common cases. You can override any field by specifying the Keycloak attribute key from which the value should be read. The keys are listed in priority order: the first non-empty value is used.
Anjana automatically flattens the Keycloak attributes map (attributes), so custom attributes are accessible as top-level keys. For example, if you have attributes.department, you can reference it simply as department.
Default mapping
|
Anjana Field |
Default keys (priority order) |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Available fields
Anjana exposes both the user's root fields and all custom attributes flattened as top-level keys.
|
Key |
Description |
|---|---|
|
|
Unique UUID of the user in Keycloak. |
|
|
Login username. |
|
|
Email address. |
|
|
First name. |
|
|
Last name. |
|
|
|
|
|
|
|
<attribute name> |
Any custom attribute defined in the realm's User Profile (e.g. |
Configuration example
security:
provisioning:
providers:
keycloak:
keycloak-corp:
server-url: "https://sso.mi-dominio.com"
realm: "mi-realm"
client-id: "anjana-provisioning"
client-secret: "..."
field-mapping:
# Use email as userName if username is empty
user-name: ["username", "email"]
# Read phone from the 'mobile' or 'phoneNumber' attribute
phone: ["mobile", "phoneNumber"]
# Job title from the 'position' or 'title' attribute
title: ["position", "title"]
Summary of required data
|
YAML Property |
Description |
Where to find it |
|---|---|---|
|
|
Base URL of Keycloak (without the realm) |
Access URL of the Admin Console |
|
|
Realm name |
Realm selector in the Admin Console |
|
|
Client ID of the provisioning client |
Clients > <client> > Settings |
|
|
Client secret |
Clients > <client> > Credentials |