TT Lab
Get started
Learn Learning paths Courses

Keycloak and Enterprise Identity

A Realm Is an Isolation Boundary

Continue in TT Lab

Summary

A realm is a fully isolated unit that holds users, clients, roles, and keys. If the realms differ, they do not know each other's users.

Why this was needed

When you first open Keycloak, there is a master realm. Creating application users here is the first mistake. master is the realm that manages Keycloak itself, and the users here are entangled with Keycloak administration permissions. You must create a separate realm for your application.

What it means for a realm to be an isolation unit is concrete. Each realm has different signing keys, a different user store, and a different token issuer (iss). So a token from realm A fails verification at realm B's API. The design of giving each tenant its own realm in a multi-tenant SaaS comes from here — however, when the number of realms reaches hundreds, management and memory burden grow, so usually tenants are distinguished by groups and attributes within a single realm.

How it works

A client is an application that can request tokens within a realm. They divide into two kinds.

A public client has no secret. SPAs and mobile apps belong here, and PKCE must be turned on. It is also important to register the redirect URI precisely — using wildcards broadly becomes a route for token theft.

A confidential client has a secret. Backend servers belong here, and if you turn on the service account, it can obtain its own token through the client credentials flow.

Roles come in two levels. A realm role is meaningful across the whole realm (for example, admin), and a client role is meaningful only within a specific client (for example, the orders-api client's refund). When there are several services, separating them by client roles prevents name collisions.

A group is a collection of users and can have roles mapped to it. Instead of giving roles individually to 300 users, you give the role to a group and put the users in the group. Groups can have a hierarchy, and a subgroup inherits the roles of its parent.

A composite role is a role that contains other roles. If you make order-admin contain order-reader, you do not need to give an administrator the two roles separately.

What you meet in the field

It is easy to get confused about where roles go in the token. Realm roles go in realm_access.roles, and client roles go in resource_access.<클라이언트ID>.roles (the client ID). And if you turn off a client's "full scope allowed", roles not mapped to that client are dropped from the token. It is used to reduce token size and keep least privilege, but if you turn it off without knowing this, it becomes "I gave the role but it doesn't show in the token".

It is good to script administration tasks with kcadm.sh. Settings made by hand in the web console are not reproducible, and staging and production quietly diverge.

What to look at on the side that verifies the token

However well you configure issuance, it is meaningless if the receiving side does not verify properly. What an API server must check when it receives a token is settled.

What you must never do here is choose the algorithm as the token tells you to. If the verifying side trusts the header's alg as is, an attacker can change it to none or a symmetric algorithm and bypass the signature. You must hard-code the expected algorithm in the code and reject immediately anything different.

Decide the token lifetime design together too. The reason to keep access tokens short (a few minutes) and refresh tokens long is that access tokens cannot be revoked. If the signature is valid and it is before expiry, the token keeps working even if you delete the user in Keycloak. So when immediate blocking is needed, you must lean on the short lifetime, or switch to checking the token state on every request, and with the latter every request goes through Keycloak, so you must consider performance and availability together. The answer to the question "I logged out, so why does it still work?" is mostly in this passage.

Finally, you must also decide how to return a verification failure. A wrong signature or issuer is a 401, and if the token is valid but the action is not allowed with that role, it is a 403. If you lump the two together, the client cannot distinguish a situation where it must log in again from one where it must obtain permission, and you get a screen that attempts to log in again endlessly.

What you will do in the next lab

You create a realm, create a public client and a confidential client each, and create a user. Then in a separate lab you create roles and groups and check how they are reflected in the token, and even try excluding roles with scope.