Ability to configure a different session lifetime for admin-console users

Hi everyone,

we have a realm where there are normal application users and admin users (having permissions to manage users - signing in via an external IDP). To allow for a better user experience for the application users, we selected a rather high SSO Session Max setting on realm level allowing users to use the application without having to sign in regularly.

Admin users are supposed to use the build-in realm admin-console for managing user accounts. Unfortunately the SSO Session Max setting also applies for the admin users. For sake of improved security the session lifetime of admin users using the admin-console should be limited.

We tried configuring the Client Session Idle/Max settings for the admin-console client, but this only leads to the client session expiring sooner prompting a redirect to the authorization endpoint that then again finds a valid session and automatically sings in the admin user again.

I found this comment from Alexander Schwartz here, further explaining the difference between the user session and the client session, but unfortunately I am still searching for a way to limit the session lifetime of the admin users and/or for sessions on the admin-console.

Any ideas?

One option would be to remove the Cookie step from the authentication flow that is used for the admin console login. By doing so, having the Keycloak Authentication Cookie is not enough anymore for the admins to sign in, so always a redirect to the IDP is done. As long as the IDP session is valid the user is then automatically signed in.

One drawback with this approach is, that the IDP redirect is done every time the user opens or reloads the admin console.

Thank you for sharing this here. I read

For sake of improved security the session lifetime of admin users using the admin-console should be limited.

I assume limiting the lifetime of the client sessions is only means to an end. Can you explain more what the threat you want to mitigate using a reduced lifetime? How should the mitigation look like from an admin’s point of view?

When the session of an admin user is not expiring soon enough, the risk increases that somehow someone gains access to the users browser session - e.g. by just physically gaining access to the admins unlocked device - that would allow him to gain access to the admin console without having to re-enter the admins user credentials.

Rather then having the same user session lifetime as a regular application user, the session of an admin should only last a limited time. At least when he is accessing the application in an admin context (e.g. keycloak admin console or another admin client application).

If you are using an external IDP where you are already logged in, you can also open the admin UI if it is not already open, and use the existing authentication to just continue, so it IMHO not about the lifetime of an admin context.

IMHO this still lacks information on how the mitigation should look from an admin’s point of view. Would they need to re-authenticate? As you are using an external IDP, would you like to re-authenticate with an external IDP, or would it be an option to ask for a second factor that is asked by Keycloak?

Asking for the second factor all the time when accessing the admin UI can be achieved by adding a custom login flow which asks for the second factor.

What you are most likely asking for is an implementaiton of a “level of authentication” (LoA) that can be configured on a per-client level, and which is also propagated to the external IDP, so you can force the external IDP to ask for credentials again when a specific application is accessed, and no credentials have been entered for a specific amount of time.

There is a discussion here to enforce a LoA on a per-client-level, see Support to enforce LoA in authentication flow (Step-up) ¡ Issue #16884 ¡ keycloak/keycloak ¡ GitHub together with a PR Enable clients to enforce an ACR via client attribute by sonOfRa ¡ Pull Request #33205 ¡ keycloak/keycloak ¡ GitHub

I am also not sure how the LoA can be propagated to the external IdP - maybe @thomasdarimont can help out here with the current state of things.

This is an interesting use case.

Adjusting an individual user session based on some criteria is possible but tricky.
But before fleshing this out, we must consider its usability without compromising security.

Use case: Lower session idle time for privileged accounts

Let’s imagine that we could make the session idle time dependent on the user, e.g. for all users with an admin role, we could limit it to a maximum of 5 minutes.

If an admin user has to work in the admin console for more than 5 minutes, they have to log in repeatedly, which is good for security but could be better in terms of usability.

To make the process more pleasant for admins while still keeping it secure, we could use a procedure that is used in the financial sector for online banking solutions.

We define a shorter max idle time for admins, e.g. 5 minutes, and display a timer that is visible to the admin user. This timer then counts down from 5 minutes. The user can extend the current admin ‘session’ by clicking on the timer again, which also resets the idle time tracker on the server side.
This approach allows the admin to work in the admin UI without the inconvenience of frequent logins, thereby enhancing their user experience.
If the admin leaves and does not extend his session, it will then expire normally with the shortened idle time.

Propagate security context information to the IdP

I think you’d rather pass the required acr_values around than LoA information.

AFAIK, the OIDC IdP support currently does not explicitly support passing values like acr_values, however we have the option to forward parameters to the idp which might help you in this regard.

If this doesn’t help you’d probably need to implement your own IdentityProvider by extending the existing implementations and add extract the desired information from the current KeycloakSession / AuthSession and add appropriate paramerters to the auth/token requests send to the provider.

Approach for limiting access for “master” realm users

I don’t know your realm structure, but the following would work if your admins sign-in via the master realm (through an IdP), to manage the other realms.

You could force admin users to register a custom OTP authenticator in the master realm in addition to their linked IdP account. Then you could use a custom browser flow in the master realm that forces a certain LoA level which requires OTP. In the configuration for the OTP Form authenticator, you configure the “Authenticator Reference Max Age” to expire after e.g. 15 mins.

With that in place. (Admin) Users who login in the master realm via the IdP need to enter the OTP code before accessing the admin-console. The OTP code remains valid for 15mins, and in during this time admins can work in the admin console without interruption. Once the 15mins run out, then the user is redirected to the OTP form when the next token request is attempted. You could adjust the access token timeout to ensure this happens quick enough.

In case you are using realm local admins for accessing the realm local security-admin-console then the workflow above needs to be adjusted a bit (e.g. with custom extensions) to only apply / and require the OTP authenticator for certain groups / roles.

As a sidenote I hope the feature Enable clients to enforce an ACR via client attribute by sonOfRa · Pull Request #33205 · keycloak/keycloak · GitHub (minimal acr_value per client) quickly finds it’s way into the next release as it will greatly simplify expression and enforcing required authentication levels per client.

Cheers,
Thomas

1 Like

Yes, that’s also my experience. acr_values are currently not propagated to the external IdP.
I implemented this some time ago for a customer of mine, b/c it was not possible with the forward parameters ootb.
The basic propagation is not that much effort. But it becomes a bit more tricky, if you need some translation of the acr_values if the external IdP(s) use different values.

The first part would be what we are looking for. Basically we simply want admin users having to reauthenticate against the external IDP sooner than the session of a normal application user is expiring. Currently we achieve this by removing the Cookie Step from the authentication flow of the admin-console like you suggested. But this comes with the drawback that there is basically no Keycloak Session used for the admin users and on every page refresh or revisit the IDP has to be visited.

We were more thinking about having an idle time of 12h, to basically fit in a workday. The normal application users, have a way longer idle time configured though.

Putting it more simple, what would work for us or achieve the goal here, would be to have the possibility to configure the SSO Session Cookie TTL in Keycloak on a per Client/User/Authentication Flow basis. Is the user signing in for the admin-console, or does he have the admin role, the Cookie should be issued with a lower TTL (basically meaning a lower session idle time)

They are singing into the same realm as the end users, but become member of an admin group. Otherwise we could have just had a different SSO Session Idle time in the master realm, which would have been enough. But signing them into the master realm would have come with other drawbacks that we couldn’t handle (e.g. no custom theme configurable - or at least it would apply for all master realm admins)