Keycloak Role & Domain Mappers (multi-domain / user-group support)
This is the single, login-type-neutral procedure for making Keycloak translate a user’s Active Directory group membership into the two application claims the backend needs:
-
user-group— the application user-group (role) name, and -
domain— the application domain name (Super domain= full access,domainId = 0).
It is shared verbatim by the ldap and windows login types — both use the same realm, the
same LDAP federation and the same mappers, and differ only in how Keycloak authenticates the
user (the login form vs. silent Kerberos / SPNEGO). Configure it once per realm and it applies
to whichever login type that portal uses.
|
When you need this — multi-domain / multi-role support
This is what enables multi-domain and multi-role deployments: each AD group carries an
attribute holding the application name, Keycloak emits it as a claim, and the backend
resolves permissions and domain visibility from it. Directory naming ( If every user should simply land in one fixed user-group and the super domain, you still need
the |
1. Prerequisites
Before configuring the mappers below, the following must already exist — from your login type’s setup guide:
-
A realm per portal (e.g.
oneiot-sc,oneiot-mc) with a confidential OIDC client. See LDAP Login via Keycloak (OIDC) or Windows (AD / Kerberos) SSO for the realm and client setup. -
LDAP User Federation connected to Active Directory, with a group mapper, and the AD groups synced into Keycloak (User federation > the provider > Mappers > the group mapper > Action → Sync LDAP groups to Keycloak). The groups must be visible under Groups before their translation attributes can be set.
-
One role group and one domain group per user in AD.
|
One user-group and one domain per user
Both claims are single-valued: the backend stores one |
|
The claim value must exactly match a name in the backend database
The backend matches claim values by name: the |
2. Step 1 — Translation attributes on groups
This is where the AD group name is translated into the application name. Each group carries one attribute; the attribute name decides which claim it feeds.
| AD group | Attribute key | Attribute value |
|---|---|---|
|
|
|
|
|
|
|
|
|
For each group: open Groups > the group > Attributes, click Add attributes, fill in the key and value, and click Save.
|
The value is the application name, spelled exactly
The attribute value must match a user-group or domain that exists in the backend database for that portal. |
This replaces the older arrangement in which AD groups had to be named exactly like the application user-groups. With the translation attribute, directory naming and application naming are independent.
3. Step 2 — Protocol mappers (per client)
The ID token must carry three custom claims: portal-type, user-group, and domain. The
username arrives in the standard preferred_username claim and needs no mapper. Add the
mappers to the client’s dedicated scope, in each realm.
-
Switch to the target realm and open Clients > your client > Client scopes.
-
Click the client’s dedicated scope — the first row, described as "Dedicated scope and mappers for this client".
-
Click Add mapper > By configuration and create the mappers below.
|
Remove obsolete hardcoded mappers first
Earlier revisions configured |
3.1. portal-type (Hardcoded claim)
| Field | Value |
|---|---|
Mapper type |
|
Name |
|
Token Claim Name |
|
Claim value |
|
Claim JSON Type |
|
Add to ID token |
|
3.2. user-group (User Attribute)
Both remaining mappers use the same type, User Attribute, and differ only in the name. In the type picker, scroll down to User Attribute — not User Client Role or User Property.
| Field | Value |
|---|---|
Mapper type |
|
Name |
|
User Attribute |
|
Token Claim Name |
|
Claim JSON Type |
|
Add to ID token |
|
Add to access token |
|
Multivalued |
|
Aggregate attribute values |
|
|
Why Multivalued and Aggregate stay off
Role and domain are one value per user. With Aggregate attribute values off, Keycloak returns the value of the first group that carries the attribute and skips groups that do not — exactly the required behaviour. Leaving Multivalued off keeps the claim a plain string rather than an array. |
3.3. domain (User Attribute)
Identical to the previous mapper, with domain substituted everywhere.
| Field | Value |
|---|---|
Mapper type |
|
Name |
|
User Attribute |
|
Token Claim Name |
|
Claim JSON Type |
|
Add to ID token |
|
Add to access token |
|
Multivalued / Aggregate attribute values |
|
The Token Claim Name values must be exactly portal-type, user-group, and
domain — the backend expects these fixed names and has no override for them.
The claim
values come from the group attributes configured in
Step 1 — Translation attributes on groups and must match names that exist in the backend database.
|
4. Step 3 — Verify the claims without logging in
Keycloak can assemble a token for any user from the Admin Console, which verifies the whole chain without disturbing anyone’s session.
-
Open Clients > your client > Client scopes > Evaluate.
-
Start typing a login in the Users field and pick the user from the suggestions.
-
On the right, click Generated ID token.
The configuration is correct when both claims are present as plain strings:
"domain": "Super domain",
"user-group": "admin",
An array (["admin"]) instead of a string means Multivalued is still enabled on the mapper.
|
|
Diagnose from the token backwards
Work the chain in this order: the generated ID token (Client scopes → Evaluate), then the user’s Groups tab, then the group’s Attributes tab (Step 1), then the federation’s group mapper. The first step that shows the wrong value is the layer that is broken. |
5. Checklist
-
AD groups synced into Keycloak and visible under Groups.
-
A
user-groupattribute set on each role group, and adomainattribute on each domain group (Step 1); values match names that exist in the backend database for that portal. -
Protocol mappers on the client’s dedicated scope (Step 2):
user-groupanddomain(both User Attribute, Multivalued / Aggregate off) plusportal-type(hardcodedsc/mc). -
No leftover Hardcoded claim or Group Membership mappers for
user-group/domain. -
Evaluate shows both claims as plain strings (Step 3).
6. Related documentation
-
LDAP Login via Keycloak (OIDC) — the
ldaplogin type: backend variables, TLS trust, OIDC client, and LDAP User Federation. -
Windows (AD / Kerberos) SSO — the
windowslogin type: the same OIDC/Keycloak flow with silent Kerberos SSO. -
Keycloak Deployment — deploy the Keycloak container (Docker, storage, TLS, network, HA).