Realm Role vs. Client Role in Keycloak
The complete beginner-to-production guide to choosing the right scope for a permission — and why getting this wrong quietly costs teams for years.
Picture a large office building again, but this time look at two very different kinds of access passes handed to a new employee. The first is a badge sticker that says “Building Staff” — it works at literally every door in the building, from the lobby to the roof deck, because building security itself issued it and every door reads the same universal sticker. The second is a small keycard that only unlocks the server room on the third floor — issued and understood solely by the IT department, meaningless to any other door in the building. Both are “permissions,” but they live at completely different scopes. Keycloak draws exactly this same line between a Realm Role and a Client Role, and confusing the two is one of the most common design mistakes teams make when they first start modeling permissions.
This guide puts the two side by side: what each one is, how they’re structured differently, how they travel into a token differently, and a clear, repeatable way to decide which one a new permission should actually be. No prior identity or security background is assumed — every term is explained the moment it appears.
1Core Concepts
Realm Role: The Building-Wide Sticker
A Realm Role is a permission label defined at the top level of a Realm — Keycloak’s isolated universe of users and settings — and it is automatically recognized by every single Client (application) registered inside that Realm, with no extra setup required per application. Names like “employee,” “verified-customer,” or “premium-subscriber” are typical examples: broad, organization-wide facts about a user.
Client Role: The Server-Room Keycard
A Client Role is a permission label defined inside one specific Client, and it is meaningful only to that one application. A name like “billing-api:can-issue-refunds” means nothing at all to any other application in the Realm — only the billing application itself knows to look for and interpret it.
Ask: “Would this permission still make sense if I removed one specific application from the picture entirely?” If yes — it’s a Realm Role. If the permission becomes meaningless without that one specific application in mind — it’s a Client Role. This single question resolves the vast majority of real-world scoping decisions.
“Registered Guest” printed on a hotel’s universal key card works at the gym, the pool, and the lobby lounge — a Realm Role, recognized everywhere on the property because the hotel itself issued it. “Suite 402 Access” only works on one specific door — a Client Role, meaningful only to that one room, issued and understood only in that narrow context.
2Side-by-Side Comparison
| Dimension | Realm Role | Client Role |
|---|---|---|
| Defined at | The Realm level | Inside one specific Client |
| Visible to | Every current and future Client in the Realm | Only the one Client it belongs to |
| Typical naming | “employee,” “verified-customer” | “billing-api:can-issue-refunds” |
| Token location | realm_access.roles | resource_access.<client-id>.roles |
| Best for | Broad organizational facts | Fine-grained, application-specific permissions |
| Change impact | Potentially wide — every connected app can see it | Narrow — contained to one application |
graph TD
Realm["Realm"]
Realm --> RR["Realm Role: employee"]
Realm --> ClientA["Client: billing-api"]
Realm --> ClientB["Client: hr-portal"]
ClientA --> CRA["Client Role: can-issue-refunds"]
ClientB --> CRB["Client Role: can-approve-leave"]
User["User: sara"] --> RR
User --> CRA
RR -.->|"seen by"| ClientA
RR -.->|"seen by"| ClientB
CRA -.->|"seen only by"| ClientA
3Where Each One Lives Inside a Token
When Keycloak issues a token, it doesn’t just dump every Role a user has into one flat list. It carefully separates the two scopes into two distinct locations, so that any application reading the token can immediately tell which Roles apply broadly and which apply only to a specific Client:
realm_access.roles
A single, shared list containing every Realm Role the user currently has — the same list, unchanged, regardless of which Client requested the token.
resource_access.<client-id>.roles
A separate list, nested under that specific Client’s own identifier, containing only the Client Roles belonging to that one application.
An application that only ever checks realm_access.roles will never see any of its own Client Roles — they live in a completely separate part of the token. This is a frequent source of “why isn’t my permission check working?” confusion for teams new to Keycloak.
4Internal Working
User Authenticates
The user logs in successfully, independent of which Roles they hold.
Effective Roles Computed, Both Scopes
Keycloak resolves the user’s full set of Realm Roles (direct, via Groups, via composites) and, separately, their Client Roles for every Client relevant to this login.
Token Assembled in Two Sections
Realm Roles are placed into the shared realm_access.roles claim; Client Roles are placed into their own nested resource_access section, keyed by each relevant Client’s ID.
Application Reads the Right Section
A well-built application checks both sections as appropriate — realm_access.roles for broad facts, and its own entry under resource_access for permissions specific to itself.
5Composite Roles Across Both Scopes
A composite Role — one that automatically bundles other Roles when assigned — can mix scopes freely. A composite Realm Role called “department-head” might bundle in a broad Realm Role (“manager”) alongside several narrow Client Roles pulled from three different applications a department head needs access to. This is genuinely powerful: a single assignment step grants a thoughtfully chosen mix of organization-wide and application-specific access at once.
A “New Department Head Starter Pack” is a Realm Role that, when handed over, automatically includes the universal “Manager” sticker (a Realm Role) plus a spa-access keycard and a parking-garage keycard (two Client Roles from two different departments) — one handover, three separate access grants, spanning both scopes at once.
Because a composite Realm Role can reach into Client Roles belonging to applications a Realm-level administrator may not personally manage, changing that composite can silently ripple permissions into unrelated applications. Review composite Realm Roles with special care before editing them.
6Advantages, Disadvantages & Trade-offs
Realm Role Trade-offs
- Gain: defined once, automatically understood by every current and future Client — no per-application setup
- Gain: ideal for facts that genuinely span the whole organization
- Cost: visible everywhere, so a poorly scoped one can leak meaning into applications where it was never intended to apply
Client Role Trade-offs
- Gain: tightly scoped — changes and reviews stay contained to one application
- Gain: keeps an application’s own permission model self-contained and easy to audit in isolation
- Cost: must be set up separately for each application that needs its own permissions, with no automatic sharing across Clients
7Security
Problem
A team needing a narrow permission for just one application — say, “can-approve-invoices” for a billing app — defines it as a Realm Role out of convenience, rather than scoping it as a Client Role on that one Client.
Why It Fails
Every other application in the Realm now also sees this Role name inside every user’s token, even though it’s meaningless to them. This raises the risk that a different, unrelated application’s code mistakenly checks for or misinterprets that Role name, granting access it should never have had.
Correct Approach
Apply the one-sentence test from Chapter 1 consistently: scope a permission as a Client Role unless it would clearly still make sense with any single application removed from the picture.
Auditing Is Easier When Scope Matches Meaning
A security review asking “what can this user do inside the billing application specifically?” is far faster to answer when billing-specific permissions live cleanly as Client Roles on that one Client, rather than being scattered across a mix of Realm Roles and Client Roles with overlapping, ambiguous meaning.
8Monitoring, Logging & Metrics
Scope-Aware Access Reviews
A useful access review separately lists “which users have this Realm Role” and “which users have this Client Role on this application,” rather than blending both into one undifferentiated report.
Token Claim Inspection
When an application’s permission check unexpectedly fails, inspecting whether the expected Role actually appears in realm_access versus the correct resource_access.<client-id> section is often the fastest way to spot a scoping mistake.
Cross-Scope Duplication Checks
Periodically checking for Realm Roles and Client Roles with confusingly similar names helps catch cases where a permission may have been defined redundantly in both scopes.
9Best Practices & Common Mistakes
Best Practices
- Apply the one-sentence scoping test from Chapter 1 consistently, every time a new permission is created
- Reserve Realm Roles for facts genuinely meaningful across the whole organization
- Namespace Client Role names clearly with their Client (like “billing-api:refund-approve”) so their scope is obvious at a glance
- Review composite Realm Roles that reach into Client Roles with extra scrutiny, given their wider blast radius
Common Mistakes
- Defaulting to Realm Roles for every new permission simply because they’re the first option teams learn about
- Checking only
realm_access.rolesin application code and never looking at the Client-scoped section, missing Client Role checks entirely - Letting the same underlying permission get redundantly defined once as a Realm Role and again as a Client Role
- Nesting composite Roles many layers deep across both scopes until nobody can trace the full effective access anymore
10Real-World & Industry Examples
Enterprise Employee Directory
A company might use Realm Roles like “employee” and “manager” (organization-wide facts) alongside Client Roles like “expense-app:can-approve” and “hr-portal:can-view-salaries” (permissions meaningful only inside one specific tool) — a textbook clean split between the two scopes.
SaaS Products with Modular Add-Ons
A software-as-a-service platform frequently uses a Realm Role like “premium-subscriber” to reflect account-wide subscription status, while individual product modules (analytics, reporting, integrations) each define their own Client Roles for the specific actions available within that one module.
Multi-Application Government Portals
A government agency running many separate citizen-facing applications behind one identity provider often uses Realm Roles for broad citizen status (like “verified-identity”) while each individual application defines its own Client Roles for the specific services it uniquely offers.
11Frequently Asked Questions
realm_access.roles claim, while Client Roles appear separately, nested under resource_access.<client-id>.roles for each relevant Client.resource_access.<client-id>.roles, not inside realm_access.roles, which only contains Realm Roles.12Summary and Key Takeaways
Key Takeaways
- A Realm Role is defined at the Realm level and automatically recognized by every Client — use it for broad, organization-wide facts.
- A Client Role is defined inside one specific Client and only meaningful there — use it for fine-grained, application-specific permissions.
- The one-sentence test — “would this still make sense without one specific application?” — resolves the vast majority of scoping decisions.
- The two scopes live in different token locations:
realm_access.rolesfor Realm Roles,resource_access.<client-id>.rolesfor Client Roles — a frequent source of “why isn’t my check working?” bugs. - Composite Roles can mix both scopes, but composites reaching into Client Roles from other applications carry a wider blast radius when changed.
- Getting the scope wrong has real security consequences — an over-broadly scoped permission can leak meaning into applications that were never meant to see it.
- Consistent naming and disciplined scoping keep a Keycloak Realm’s permission model auditable and maintainable, even at scale.