Keycloak is awesome and I’ve been a big fan of Keycloak for some time now. In this post, I’ll share my thoughts on the decisions I’ve had to make when designing a multi-tenant application with Keycloak as the IAM server. I must give a heads up on the fact that the latest version of Keycloak at the time was 18x and hence the design was based on the features of Keycloak available at the time.
Multiple Realms with One Realm per Tenant
The first choice that came to mind in terms of the design was to use one realm per tenant. However, this posed a set of challenges, a few that are general and one that was specific to our requirements.
- The multi-realm setup becomes complex with our choice of the backend stack (Spring Boot and Kotlin).
- The fact that there are scaling issues when the number of realms grows was discussed a lot in Keycloak Discourse and there were a few issues like this https://github.com/keycloak/keycloak/discussions/11074 reported as well.
- Our specific use case wanted to support single sign-on with one of the tenants (internal to the organisation) with other internal applications and that meant we had to share the same realm for that.
Tenants to share a Single Realm
Clarification on some of the requirement specifics
How did we manage an approach where tenants share a single realm? Before going into this, I must clarify a bit more about our requirements. The plan for us was to use Keycloak for Authentication and for us to be able to manage roles and permissions on our own outside of Keycloak to allow users more flexibility to manage permissions and roles from the frontend.

So our ideal state was above where we have the users and clients for each tenant within a single realm and maintain the roles and permissions on a separate database (managed by a micro-service). So the login (authentication) would ideally go through normally from Keycloak but the authorization will be done on each of our backends using Spring Security on the JWT token coming in. For this to work, we needed a way to enrich the JWT token with roles & permissions along with an identifier of the tenant.
Remote JSON Claim Mapper
As I said before, Keycloak is awesome and provides an ample number of extension points. So this is where Keycloak’s Protocol Mapper SPI comes into play and I must give credit to my friend Tharindu Nishada for giving me the initial idea on this.

We had to write a custom keycloak protocol mapper (we call it Remote Json Claim Mapper), that would enrich the token for us during the keycloak authentication flow. I’ve pushed a very basic version of it at https://github.com/Rajind/remote-json-claim-mapper for any of you to get the idea.
From the authorization perspective, we have used keycloak-spring-security-adapter and we had to use a custom implementation of KeycloakAuthenticationProvider for us to be able to parse the custom role and permissions and tenant info from the JWT token. If you would like more details on deployment and configurations of a custom protocol mapper, please refer to https://www.baeldung.com/keycloak-custom-protocol-mapper.
Limitations
The main limitation with this approach so far is that, since the users are in the same realm, we have to make the name or the email unique and thus prevents a user from being added to two tenants using the same email. For our case, this was reasonable but of course there are ways to work around this as well.
Remarks
Keycloak has released a feature called Organizations with Keycloak v25 release and that promises to support some degree of Multi-tenancy within a realm. If you have the freedom to use a newer version of Keycloak, it will be worth exploring.
Keep supporting open source tools. 🙂
References
- https://github.com/keycloak/keycloak/discussions/11074
- https://github.com/Rajind/remote-json-claim-mapper
- https://www.baeldung.com/keycloak-custom-protocol-mapper
- https://www.keycloak.org/2024/06/announcement-keycloak-organizations
~ Rajind Ruparathna
