Skip to content

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.

Prerequisites

  • 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.
Disruption notice

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.

Configure session limiting

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.

Step 0: Go to the Metaco realm

Before beginning, make sure you are in the Metaco realm:

  1. Using your administrator account, go to the URL for the Keycloak Admin Console, and log in.
  2. Change the Current realm to Metaco.

Step 1: Update realm login email settings

Update the login email settings as follows:

  1. In the left menu, go to Realm settings.
  2. Select the Login tab.
  3. Under Email settings, set the following:
    • Login with email: Off
    • Duplicate emails: On

Step 2: Create the Authentication flow

To create the Authentication flow:

  1. In the left menu, go to Authentication.
  2. Select the Flows tab.
  3. Select Create flow.
  4. Enter the following:
    • Name: Post Broker Login with Session limit
    • Flow type: Basic flow
  5. Select Create.

Step 3: Add the session limit execution

To add a new execution for setting the session limit:

  1. In the newly created flow, select Add execution.
  2. Look for User session count limiter (user-session-limits), and add it.
  3. Set its requirement to Required.

Step 4: Configure the session limit

  1. Select the gear/settings icon next to the User Session Limits step.
  2. Set the following values, and select Save.
SettingField name              Value            Description
AliasaliasSession limitDisplay name for this config
Max sessions per user (realm)userRealmLimit1 (or your desired limit)0 = no limit.
1 = one session at a time.
Max sessions per user
per client
userClientLimit00 = no limit per client.
BehaviorbehaviorDeny new sessionDefines what happens when the limit is reached.
Error messageerrorMessagesessionLimitErrorKey used for the error page message.
Do not modify the error message

Do not modify the errorMessage field, as it is used in the UI to show a specific descriptive error page.

Note

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.

Step 5: Modify the 'first broker login' flow

Modify the built-in first broker login flow so that it automatically links IDP users without manual confirmation or profile review.

Step 5a: Duplicate the 'first broker login' built-in flow

To create a modifiable copy of the first broker login flow:

  1. In the left menu, go to Authentication.
  2. Select the first broker login flow.
  3. Select Duplicate.

Step 5b: Disable "Review Profile"

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:

  1. Find the Review Profile (idp-review-profile) step.
  2. Change its requirement from Required to Disabled.

To change the way the flow handles existing accounts:

  1. Find the Handle Existing Account sub-flow.
  2. Remove the existing steps inside the flow (idp-confirm-link and the Account verification options sub-flow).
  3. Add a new step: Automatically set existing user (idp-auto-link).
  4. Set its requirement to Required.

Step 5d: Bind the modified flow to first broker login

On the top right, select action and bind the flow to first broker login.

The flow should look like the following:

Step 6: Configure your own IDP (skip if using default IDP)

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:

  1. In the left menu, go to Identity Providers.
  2. Select your identity provider (IDP).
  3. Select the Mappers tab.
  4. Create these four mappers (if they don't already exist):

Configure these mappers as described in the following sections:

Mapper 1 — BROKER_ID Username Template Importer

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:

FieldValue
NameBROKER_ID Username Template Importer
Mapper TypeUsername Template Importer
Sync ModeInherit
Template${ALIAS}:${CLAIM.sub}
TargetBROKER_ID

Mapper 2 — BROKER_USERNAME Username Template Importer

This mapper maps the external user identity to the Keycloak broker username using the same pattern. Configure this mapper as follows:

FieldValue
NameBROKER_USERNAME Username Template Importer
Mapper TypeUsername Template Importer
Sync ModeInherit
Template${ALIAS}:${CLAIM.sub}
TargetBROKER_USERNAME

Mapper 3 — Username with provider alias

This mapper appends the IDP alias to the username to avoid collisions between users from different identity providers. Configure this mapper as follows:

FieldValue
NameUsername with provider alias
Mapper TypeUsername with provider alias
Sync ModeForce

Mapper 4 — Hardcoded user session attribute

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:

FieldValue
NameHardcoded user session attribute
Mapper TypeHardcoded User Session Attribute
Attributeidentity_provider_alias
Attribute Value(your IDP alias)
Sync ModeForce

Step 7: Update the sub claim mapper on clients

Disruption notice

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.

Note

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):

  1. Go to Clients and select the client.
  2. Select Client scopes > metaco_webap-dedicated > Mappers.
  3. Select LoginId sub claim.
  4. Change User Attribute from fullId to username.
  5. Select Save.

Step 8: Update the metaco_webapp client settings

  1. Go to Clients and select metaco_webapp (${CLIENT_WEBAPP_CLIENT_ID}).
  2. Select the Client scopes tab:
    • Change offline_access from Default to Optional.
  3. Select the metaco_webap-dedicated > Scope tab:
    • Set Full scope allowed to On.

Step 9: Update the IDP flow overrides

This is the final cutover step. Once applied, all new identity provider (IDP) logins will use the new flows.

  1. In the left menu, select Identity Providers.
  2. Select your OpenID Connect identity provider (e.g., Harmonize).
  3. In the Settings section:
    1. Find First login flow and change it from Harmonize Flow to the flow you created in Step 5.
    2. Find Post broker login flow and set it to: Post Broker Login with Session limit.
  4. Select Save.

Frontend client configuration

Frontend v2 only

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_access

change them to:

openid

The 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.

Verification

  1. Log in as a user through the identity provider — this should work normally.
  2. Open a second browser (or incognito window) and log in as the same user.
  3. Verify that the second login is denied with a session limit error page (if userRealmLimit is set to 1).

Adjusting the session limit

To change the session limit after initial setup:

  1. Go to Authentication.
  2. Select Post Broker Login with Session limit.
  3. Select the gear icon next to the "User Session Limits" step.
  4. Change userRealmLimit to one of the following values, and select Save.
ValueBehavior
0No limit (feature disabled)
1One session at a time.
2Up to 2 concurrent sessions.
NUp to N concurrent sessions.

Troubleshooting

  • Users see a session limit error but you want to disable it: Set userRealmLimit to 0 in 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 userRealmLimit and userClientLimit to 0 effectively disables session limiting.