This tutorial describes how to configure concurrent session limiting in Keycloak using the Keycloak Admin Console. After following these steps, you will be able to control how many active Keycloak sessions a user can have open at the same time.
- Keycloak 26.x or later.
- Custody LTS Version 1.34 or later.
- The frontend v2 web application. Session limiting is not available in older frontend versions.
- Admin access to the Keycloak Admin Console.
- You are working in the Metaco realm.
While Steps 1–6 are non-disruptive (they create or modify flows and settings that are not yet active), Steps 7–9 make changes that affect active user authentication — the sub claim value in tokens will change, and the identity provider (IDP) login flow will switch over. The steps below are ordered to minimize downtime by completing all preparatory steps first, then applying the disruptive changes (Steps 7–9) in quick succession.
For more documentation on using the Keycloak Admin Console, see Keycloak's Server Administration Guide.
The following sections detail the steps to configure concurrent session limiting in Keycloak.
For more information about using the Keycloak Admin Console to configure a realm, see Configuring realms.
Before beginning, make sure you are in the Metaco realm:
- Using your administrator account, go to the URL for the Keycloak Admin Console, and log in.
- Change the Current realm to Metaco.
Update the login email settings as follows:
- In the left menu, go to Realm settings.
- Select the Login tab.
- Under Email settings, set the following:
- Login with email: Off
- Duplicate emails: On
To create the Authentication flow:
- In the left menu, go to Authentication.
- Select the Flows tab.
- Select Create flow.
- Enter the following:
- Name: Post Broker Login with Session limit
- Flow type: Basic flow
- Select Create.
To add a new execution for setting the session limit:
- In the newly created flow, select Add execution.
- Look for User session count limiter (
user-session-limits), and add it. - Set its requirement to Required.
- Select the gear/settings icon next to the User Session Limits step.
- Set the following values, and select Save.
| Setting | Field name | Value | Description |
|---|---|---|---|
| Alias | alias | Session limit | Display name for this config |
| Max sessions per user (realm) | userRealmLimit | 1 (or your desired limit) | 0 = no limit. 1 = one session at a time. |
| Max sessions per user per client | userClientLimit | 0 | 0 = no limit per client. |
| Behavior | behavior | Deny new session | Defines what happens when the limit is reached. |
| Error message | errorMessage | sessionLimitError | Key used for the error page message. |
Do not modify the errorMessage field, as it is used in the UI to show a specific descriptive error page.
The userRealmLimit value controls how many concurrent sessions a single user can have across all clients. Set it to the number that fits your security requirements.
Modify the built-in first broker login flow so that it automatically links IDP users without manual confirmation or profile review.
To create a modifiable copy of the first broker login flow:
- In the left menu, go to Authentication.
- Select the
first broker loginflow. - Select Duplicate.
To prevent the user from being prompted to review or edit their profile on first login through the identity provider (IDP), which is not the desired behavior, disable the Review Profile step as follows:
- Find the Review Profile (
idp-review-profile) step. - Change its requirement from Required to Disabled.
To change the way the flow handles existing accounts:
- Find the Handle Existing Account sub-flow.
- Remove the existing steps inside the flow (
idp-confirm-linkand theAccount verification optionssub-flow). - Add a new step: Automatically set existing user (
idp-auto-link). - Set its requirement to Required.
On the top right, select action and bind the flow to first broker login.
The flow should look like the following:

If you are using the Harmonize default IDP, you can skip this step.
If you are using your own external identity provider (IDP), you need to ensure you configure the following four mappers for your IDP in Keycloak:
- BROKER_ID Username Template Importer
- Username with provider alias
- Hardcoded user session attribute
- BROKER_USERNAME Username Template Importer
These mappers are required for proper user linking and session tracking.
To configure the mappers:
- In the left menu, go to Identity Providers.
- Select your identity provider (IDP).
- Select the Mappers tab.
- Create these four mappers (if they don't already exist):

Configure these mappers as described in the following sections:
This mapper maps the external user identity to the Keycloak broker ID using the IDP alias and the sub claim. Configure this mapper as follows:
| Field | Value |
|---|---|
| Name | BROKER_ID Username Template Importer |
| Mapper Type | Username Template Importer |
| Sync Mode | Inherit |
| Template | ${ALIAS}:${CLAIM.sub} |
| Target | BROKER_ID |

This mapper maps the external user identity to the Keycloak broker username using the same pattern. Configure this mapper as follows:
| Field | Value |
|---|---|
| Name | BROKER_USERNAME Username Template Importer |
| Mapper Type | Username Template Importer |
| Sync Mode | Inherit |
| Template | ${ALIAS}:${CLAIM.sub} |
| Target | BROKER_USERNAME |

This mapper appends the IDP alias to the username to avoid collisions between users from different identity providers. Configure this mapper as follows:
| Field | Value |
|---|---|
| Name | Username with provider alias |
| Mapper Type | Username with provider alias |
| Sync Mode | Force |

This mapper stores the IDP alias in the user session. Keycloak uses this internally to identify which provider authenticated the user. Configure this mapper as follows:
| Field | Value |
|---|---|
| Name | Hardcoded user session attribute |
| Mapper Type | Hardcoded User Session Attribute |
| Attribute | identity_provider_alias |
| Attribute Value | (your IDP alias) |
| Sync Mode | Force |

From this step on, changes affect active user authentication. To minimize disruption, perform Steps 7–9 in quick succession.
With the new login flow, Keycloak no longer populates the fullId user attribute for users authenticating through the identity provider. You must now map the sub claim in JWT tokens to username instead.
The ROPC/service client (metaco_internal) is not affected by this step — it does not have a LoginId sub claim mapper (it uses a separate Client Credential Sub mapper).
For each client that has a LoginId sub claim mapper (metaco_desktopapp, metaco_webapp, and customer_api):
- Go to Clients and select the client.
- Select Client scopes > metaco_webap-dedicated > Mappers.
- Select LoginId sub claim.
- Change User Attribute from
fullIdtousername. - Select Save.
- Go to Clients and select metaco_webapp (
${CLIENT_WEBAPP_CLIENT_ID}). - Select the Client scopes tab:
- Change
offline_accessfrom Default to Optional.
- Change
- Select the metaco_webap-dedicated > Scope tab:
- Set Full scope allowed to On.
This is the final cutover step. Once applied, all new identity provider (IDP) logins will use the new flows.
- In the left menu, select Identity Providers.
- Select your OpenID Connect identity provider (e.g.,
Harmonize). - In the Settings section:
- Find First login flow and change it from Harmonize Flow to the flow you created in Step 5.
- Find Post broker login flow and set it to: Post Broker Login with Session limit.
- Select Save.
This configuration applies to the frontend v2 web application. Session limiting is not available in older frontend versions.
For session limiting to work correctly, the frontend application must not request the offline_access scope during authentication. Offline access tokens bypass the session limit because they create offline sessions that are not counted by the user-session-limits authenticator.
Make sure that the OAUTH_SCOPE (or equivalent configuration in your frontend) does not include offline_access.
For example, if your current scopes look like this:
openid offline_accesschange them to:
openidThe reason for this is that when the offline_access scope is requested, Keycloak issues an offline token that persists independently of regular sessions. Since the session limit flow only counts online sessions, we want to prevent users from bypassing the limit by obtaining offline tokens.
- Log in as a user through the identity provider — this should work normally.
- Open a second browser (or incognito window) and log in as the same user.
- Verify that the second login is denied with a session limit error page (if
userRealmLimitis set to1).

To change the session limit after initial setup:
- Go to Authentication.
- Select Post Broker Login with Session limit.
- Select the gear icon next to the "User Session Limits" step.
- Change
userRealmLimitto one of the following values, and select Save.
| Value | Behavior |
|---|---|
0 | No limit (feature disabled) |
1 | One session at a time. |
2 | Up to 2 concurrent sessions. |
| N | Up to N concurrent sessions. |
Users see a session limit error but you want to disable it: Set
userRealmLimitto0in the authenticator config (Step 4).The session limit doesn't seem to apply: Verify the identity provider's Post broker login flow is set to
Post Broker Login with Session limit(Step 9).Users can't log in at all: Check that the flow requirement is set to Required and that the authenticator config values are correct. Setting both
userRealmLimitanduserClientLimitto0effectively disables session limiting.