Overview
By default, Keycloak does not ship with any authentication flows that require a user to have a given role.
For example, we can gate access to an application by requiring users have an app:login or app:access role.
We may then assign this role to a group of users, paving the way for a proper RBAC/GBAC ready access flow.
Implementation
Duplicate Existing Flow
Copy an existing role that has your existing requirements. In my case, this is a modified browser flow with webauthn support and mandatory MFA.
- Navigate to
Authentication - Duplicate the flow you wish to use as your base flow.

- You should now have a starting point to make our RBAC changes
Adjust Existing Flow
The existing flow needs to be converted to a sub-flow. This will switch the final login logic to:
if ($user->login->is_success and $user->hasRole('my-role'))
Unfortunately there is no way to drag and drop components into a subflow, so they must be changed by hand.
- Create a new subflow called
loginand move it to the top of the flow - Set the flow to
Required - Manually recreate all of the existing steps as steps inside the subflow.
- Click on the
+for the subflow and clickadd step - Duplicate an existing step
- Click on the
- Delete the original step
- Repeat these steps for all existing flow steps

Implement RBAC
Implementing RBAC is fairly straightforward - we add a conditional flow with inverse logic that denies users.
DENY unless (exists $roles->{'my-role'})
- Create a new subflow AFTER the login form
- Set the new subflow to
conditionalso it only runs if a condition is met - Add a condition:
- Set the type to
user role - Once created, switch it from
disabledtorequired - Click the gear to edit and set the following:
- Set the Alias to a description of what is triggering (require-app:login)
- Select the role you with to check against
- Switch
Negate outputfrom Off to On
- Set the type to
- Add a new
Denystep - Set the
Denystep toRequired
Final Flow
The logic for the authentication flow provided should now be:
if (
($user->hasCookie or
$user->alternativeIdentity->is_success or
($user->password->is_success and
($user->webauthn->is_success or
$user->otp->is_success
)
)
) and
$user->hasRole('my-role')
)
Binding the Flow
Because this flow requires a user role to succeed, it is not likely that it can be used as a general authentication flow. Instead, we will bind it to a specific client’s browser flow.
- Navigate to the client you wish to use the RBAC flow with
- Click
Advanced - Click
Authentication flow overrides - Select your new flow from the dropdown for Browser Flow

Testing the Flow
missing role:
has role:
