Most platform engineering teams that adopt Keycloak reach a point where authentication is handled. You've deployed Keycloak, configured realms for your applications, set up federation with your existing user directory, enabled MFA, and Keycloak SSO is working across your services. The fact that you can self-host it, avoid per-MAU pricing, and run it inside your own perimeter is part of why you chose it. The identity layer is solid.
Then someone asks a question that Keycloak, at scale, struggles to answer. Not "who is this person?" but "can this person do this specific thing, to this specific resource, right now, with this much context, fast enough, and auditable enough to pass a SOC 2 review?"
That's authorization. And it's where the gap starts to show.
What Keycloak actually covers
Keycloak is an open-source identity and access management platform. It verifies credentials, issues tokens, manages user directories, handles federation across LDAP and Active Directory, supports OIDC and SAML, and runs the SSO experience across your applications. It's mature, well-documented, and self-hostable, which is why it's a common choice for regulated industries, on-premises deployments, and platform teams who want full control over identity infrastructure.
Keycloak also ships an authorization layer called Keycloak Authorization Services. Unlike most identity providers, this is a real fine-grained authorization story on paper. Resource servers, scopes, role-based policies, attribute-based policies, and historically JavaScript-based policies. Policy decisions can be requested over a Token Exchange flow or via the Policy Enforcement Point integration. For applications that live inside Keycloak's expected architecture, it works.
What Keycloak Authorization Services does not solve well at scale is a separate question. Policies are tied to the Keycloak server itself, which makes the server a single point of decision and a performance bottleneck under high check volume. JavaScript-based policies were deprecated and disabled by default for security reasons, narrowing the expressiveness available to most teams. The model is Java-centric in its integration patterns, which complicates use in polyglot service estates. Authorization decisions are not first-class in Keycloak's event log structure in the way authentication events are, which makes audit reconstruction harder than it should be. And tenant-scoped policy customization through realms creates operational duplication rather than true policy reuse.
Broken access control has been the number one vulnerability in the OWASP Top 10 since 2021. The gap between "we handle login through Keycloak" and "we control access properly across our distributed services, at scale, with audit-grade evidence" is where most of that risk lives.
Where the gap appears
The authorization capabilities Keycloak offers tend to break down along a few predictable lines at enterprise scale.

Fine-grained, attribute-based decisions at scale
Keycloak Authorization Services can model attribute-based policies and resource-scoped permissions. The issue is not whether the model exists, it's whether it holds up at scale. As policy count grows, evaluation moves further inside the Keycloak server, the policy authoring UX through the admin console becomes the bottleneck, and the developer experience of writing policies as code falls short of what modern teams expect. NIST formalized attribute-based access control in SP 800-162, and the model is sound. The question is whether your IdP, doing identity, is also the best place to evaluate every attribute-based decision your applications make.
Runtime evaluation across polyglot services
Keycloak tokens carry a snapshot of roles and group memberships at the moment of issuance. Permission tickets through UMA can re-evaluate, but they introduce additional round trips back to Keycloak. Context changes between token issuance and the moment a user takes an action. A resource gets reclassified. A user changes teams. A tenant updates their configuration. If your access decisions are frozen in the token, they're stale. And if every fresh decision requires a round trip to the central Keycloak server, latency and throughput become production concerns.
Multi-service consistency outside Java
Keycloak's authorization integration patterns are well-supported in Java, less so in Go, Python, Node, Rust, or .NET. The result is that teams running polyglot service estates end up implementing the same authorization rules differently in different languages. One service uses Keycloak's Java adapter. Another fetches roles from the JWT and runs custom logic. A third has permissions hardcoded in middleware. As one commenter put it in a popular Hacker News discussion on distributed authorization, the industry has "a very frustratingly uneven set of solutions for authorization." Authorization policy should be defined once and reused everywhere, not copied, reimplemented, or reverse-engineered from code during an audit.
Tenant-aware policies through realms create their own problems
SaaS products and platform teams serving multiple internal tenants almost always need different authorization rules per tenant. Keycloak's answer is realms, which give you tenant-scoped identity but at the cost of operational duplication. Each realm has its own clients, its own users (or federated mappings), its own policies. Sharing policy logic across realms is manual. Updating a rule that applies to all tenants means touching every realm. Most teams who start with the one-realm-per-tenant pattern eventually feel the operational drag. At NTWRK, managing edge case policies across a distributed architecture became untenable until they moved to externalized, centralized policy management that handled tenant-specific rules without duplicating infrastructure.
Auditable decision trails
Compliance frameworks like SOC 2, HIPAA, and PCI DSS don't just require access controls. They require evidence of how access decisions were made, which policy was in effect, what attributes were evaluated, and why a request was allowed or denied. Keycloak logs authentication events well. But a common audit finding is that companies log authentication events while missing authorization decisions entirely. When an auditor asks "why did this user have access to this resource on this date?", you need to reconstruct the exact authorization decision, not just confirm they logged in through Keycloak. With the average data breach costing $4.88 million in 2024 and $6.08 million in financial services, the evidence trail isn't optional.
Non-human identity governance
Microservices, AI agents, batch jobs, and third-party integrations all make requests that require authorization. They don't authenticate the way humans do, and Keycloak's authorization model wasn't built with them as the primary actor. Service accounts and client credentials grants handle authentication for the machine identity. The policy decision about what that machine can do, to which resource, under which conditions, still has to live somewhere. As organizations deploy more machine identities, the need for a purpose-built authorization layer that governs human and non-human actors consistently becomes hard to ignore.
Recognizing the decision point
None of this means you need to rip anything out. Keycloak remains a strong choice for managing identities, running SSO, and handling authentication, especially in regulated and self-hosted environments. The question is whether you also need a dedicated authorization layer, separate from Keycloak, that handles the access decision side at production scale.
A few signals that you're at that point.
1. Permission changes require code changes or realm-by-realm edits. If updating who can do what means editing application code, recompiling, redeploying, or fanning the change out across multiple Keycloak realms, you've coupled authorization to your release cycle and your identity infrastructure. That coupling gets expensive. At Human Managed, permission modifications used to require source code changes and full redeployment. After externalizing authorization, the same changes became a five-minute task.
2. Multiple services implement the same rules independently. If your Java services use the Keycloak adapter, your Go services parse the JWT and run custom logic, and your Python services query a database, you're maintaining N implementations of logic that should live in one place.
3. Compliance prep is a scramble. If getting audit-ready means manually collecting evidence from Keycloak logs, your application database, and your service logs to demonstrate who had access to what, you don't have centralized authorization visibility.
4. Role explosion is making things harder, not easier. If your Keycloak roles, groups, and per-realm policies have grown from a handful to dozens or hundreds, and you're creating new ones to handle edge cases rather than solving the underlying model problem, the complexity will only accelerate.
5. Your team spends real engineering time on permissions. Authorization work is risky, detail-oriented, and rarely the kind of thing that excites engineers. An IDC study found that developers spend 19% of their weekly hours on security-related tasks, effectively costing organizations $28,000 per developer per year. If a meaningful chunk of that time is going to authorization logic and Keycloak integration plumbing, that's sprint capacity that isn't going to product features.
How to evaluate and shortlist authorization solutions

Once you've identified the gap, the next step is evaluating solutions with a structured approach rather than a feature-by-feature comparison. We published a detailed evaluation framework covering nine dimensions that enterprise teams should consider. Here are the ones that matter most when you're shortlisting alongside Keycloak.
Policy model and expressiveness. Can the solution support RBAC, ABAC, and policy-based access control in a single readable language? Can you express conditions using attributes of the user, the resource, and the context of the request? Keycloak Authorization Services supports several models on paper, but in practice the policy authoring UX is heavy and the deprecation of JavaScript-based policies narrowed the available expressiveness. Look for a policy language that's readable by people outside engineering, a purpose-built declarative format in YAML or similar that auditors, product managers, and security leads can review without learning Java or Rego.
Integration with your Keycloak stack and services. The authorization layer should consume identity context from Keycloak without replacing it. It should accept Keycloak-issued tokens, read role mappings and claims, work with your token format, and fit your deployment model whether that's on-premises, in your own Kubernetes cluster, or in a hybrid cloud. Check for SDKs in the languages your team uses, not just Java. APIs that fit your architecture matter, whether that's REST, gRPC, or both. An authorization solution that requires you to change how you handle identity through Keycloak is solving the wrong problem.
Deployment model and latency. Authorization is on the critical path of every request. Latency matters, and any architecture that requires a round trip to a central Keycloak server for every authorization decision will struggle under load. Look for architectures where the decision engine runs close to your application, ideally as a sidecar or within the same cluster, with in-memory evaluation and sub-millisecond response times. Stateless designs that allow horizontal scaling without shared state are easier to operate in production and a natural fit for the kind of self-hosted, regulated environments where Keycloak is common.
Multi-tenancy support. If you're serving multiple tenants, evaluate how the solution handles per-tenant policy customization. Can you scope policies to individual tenants without duplicating your entire policy set across realms? Can tenants have different roles, different rules, different access models without affecting each other? Realm-per-tenant is a workable identity pattern in Keycloak. It is rarely a good policy reuse pattern.
Audit logging and compliance readiness. Every authorization decision should be logged with enough context to reconstruct it later. That means the requesting principal, the action, the resource, the decision, and the policy version that was evaluated. Look for structured log formats that integrate with your SIEM, configurable retention, and the ability to correlate authorization decisions with application events. Cerbos Hub, for example, provides structured audit logs meeting SOC 2, ISO 27001, HIPAA, PCI DSS, and GDPR requirements, including a unique correlation ID (cerbosCallId) that links authorization decisions back to the originating application request.
Developer and admin experience. The learning curve matters. Solutions that require weeks of ramp-up before a developer can write a policy will face adoption resistance, especially compared to the friction many teams already experience with Keycloak Authorization Services configuration. Look for policy-as-code workflows with version control, testing and simulation tools, and a clear local development story. The ability for non-developers to understand and even modify policies, through a UI or readable policy files, reduces the engineering bottleneck over time. One enterprise team described their experience as taking a few days to understand the system and a couple of weeks to reach production.
Cost and build-vs-buy economics. Keycloak's open-source license keeps the identity layer cost-effective, which is part of why platform teams choose it. The trap is assuming that means authorization is also free. The total cost of extending Keycloak Authorization Services to cover ABAC, multi-tenant policies, polyglot service estates, and audit-grade logging is rarely accounted for honestly. A realistic build-vs-buy analysis should account for ongoing maintenance, not just initial development. One company estimated the lifetime cost of their in-house approach at seven figures. Another startup scoped the development cost alone at GBP 200,000 before exploring external options. Open-source authorization engines like Cerbos PDP, which are self-hostable like Keycloak, fit the same operational profile.
Running a proof of concept
Before committing, run a focused POC against one real service. Not a demo app, an actual service in your stack with real users and real authorization requirements.
Define what success looks like up front. Can the solution model your existing Keycloak roles, groups, and any realm-specific overrides accurately? Does it handle the edge cases your team currently hardcodes around? What's the latency overhead under realistic load, including in your self-hosted environment? Can a new developer write a policy without hand-holding?
Involve more than just the engineering team. Have your security lead review the audit output. Have a product manager read the policies. Have your platform team confirm the deployment model fits your existing infrastructure. If the solution only makes sense to the person who configured it, adoption will stall.
The bigger picture
Authentication and authorization solve fundamentally different problems. Authentication has been successfully decoupled from applications for years, and the industry is better for it. Keycloak is the proof point for self-hosted, open-source identity at enterprise scale. Authorization is following the same trajectory, with self-hostable open-source decision engines now part of the stack.
There's a reason a Hacker News thread titled "Why Authorization Is Hard" drew over 300 upvotes and dozens of engineers sharing war stories. This is a problem most teams eventually hit, and the tooling to solve it properly is maturing. The OpenID Foundation's AuthZEN specification, is formalizing the interface between enforcement points and decision points, much like OAuth and OIDC standardized authentication.
Keycloak handles identity. A dedicated authorization layer handles access decisions at scale. Together they form a complete access control architecture. The teams that recognize this gap early, before compliance pressure or scale forces their hand, are the ones that avoid the painful migration later.
Try Cerbos to see how externalized authorization works alongside Keycloak, or book a call to talk through your architecture with our authorization experts.
Go deeper: How to adopt externalized authorization (eBook) for a step-by-step playbook on decoupling authorization from application code.
FAQ
Tagged in




