Keycloak vs Ory

SS. B. WriterSeptember 10, 202611 min read
Keycloak vs Ory

Keycloak and Ory come up together on almost every self-hosted identity shortlist, and the comparison is harder than it looks because the two are not really the same kind of thing. Keycloak is one server that does everything. Ory is a set of separate services you assemble into the shape you need. Both are open source, both put their core servers under Apache 2.0, and both will authenticate your users without a per-seat contract. Choosing between them is less about protocol checkboxes and more about how much of your identity stack you want to own. The authorization gap that sits on the other side of that choice is the part almost every comparison leaves out, and it is where this one spends its second half.

Two different bets on what an identity provider should be

Keycloak is a Java identity and access management server, now running on Quarkus, and a Cloud Native Computing Foundation incubating project with Red Hat behind its commercial support. You deploy one service and get single sign-on, OpenID Connect, OAuth 2.0, SAML, an admin console, hosted login and account pages, user federation against LDAP or Active Directory, and identity brokering to social and enterprise providers. The repository dates back to 2013, which shows up in the breadth of what it covers and in the size of the community you can search when something breaks.

Ory takes the opposite bet. Instead of one server it publishes a set of single-purpose services. Ory Kratos manages identities, credentials, and sessions. Ory Hydra is an OpenID Certified OAuth 2.0 and OpenID Connect provider. Ory Keto handles permissions using a relationship model. Ory Oathkeeper is an identity aware proxy for the network edge, and Ory Polis covers enterprise SAML and OIDC single sign-on. Kratos, Hydra, Keto, and Oathkeeper are Go binaries. Polis is a TypeScript service, adopted into the project rather than built alongside the others.

The bigger difference is the login screen. Kratos is headless by design. Ory publishes reference self-service UI implementations and a component library, and its hosted Account Experience is tied to Ory Network, so the self-hosted open source path in practice means building and owning the login, recovery, and verification screens yourself. Keycloak hands you those pages finished.

That single design choice explains most of the difference in day to day experience. Keycloak gives you a working login page in an afternoon. Ory gives you total control over the login page and expects you to write it.

Keycloak Ory
Shape One server Separate services you compose
Login UI Themeable pages included Reference UIs, you build and own the real one
Admin console Full web console API first, Ory Network console for managed
Enterprise federation LDAP, Active Directory, SAML, brokering built in SAML and OIDC via Polis, LDAP not native
Authorization model Authorization Services policy engine at the IdP Keto relationship tuples, Zanzibar style
Operational load One deployment, one upgrade path One per component, plus your frontend

Where Keycloak fits best

Keycloak is the stronger pick when you want coverage without assembly. Enterprise federation is the clearest example. If you need SAML with a customer's Active Directory Federation Services, LDAP sync against a directory you do not control, and brokered logins from three different providers, Keycloak covers all of it inside one deployment with a console someone can administer without touching code. That matters when the people running identity are not the people writing the application.

Realms give you a reasonable tenancy boundary out of the box, and the admin API is comprehensive enough that you can automate most of what the console does. The maturity is real, and for teams replacing a commercial identity provider it is usually the shortest path off the contract. Our Keycloak comparison covers how it stacks up against other self-hosted options, and a broader tools roundup puts it next to the rest of the field.

The cost is weight and opinion. It is a JVM service sized for a server rather than a sidecar, upgrades between major versions have historically needed care, and customizing the login experience means working within the theme system rather than writing your own frontend. You inherit Keycloak's data model whether or not it matches yours.

Where Ory fits best

Ory is the stronger pick when identity is part of your product rather than infrastructure sitting beside it. Because Kratos is headless, the signup and login screens are yours. There is no theme system to work around and no hosted page you have to accept. For a consumer facing product where the first screen a user sees is a conversion surface, that control is worth real money.

The modularity also lets you take only what you need. Plenty of teams run Hydra alone because they already have a user store and only need to become an OAuth 2.0 provider for third party integrations. That is a much smaller thing to operate than a full identity server, and the equivalent with Keycloak is heavier, because becoming a token issuer means standing up the whole server even if the token endpoint was all you wanted.

The components ship as single static binaries, which suits container heavy and Kubernetes native environments. Ory also runs a managed cloud if you decide later that you do not want to operate it.

The cost is that you are the integrator. Every component you add is another deployment and another upgrade path, plus a login flow you own for the life of the product, including the recovery, verification, and multi factor screens Keycloak hands you finished. The documentation is good but the surface area is larger, and each project's community is smaller than Keycloak's single one, so obscure problems have fewer existing answers.

The comparison that actually decides it

Protocol support rarely settles this. Both cover OAuth 2.0 and OpenID Connect properly, both reach SAML, and both federate to external providers. What settles it is who owns the login experience and how much operational surface you want.

Pick Keycloak if you want one deployment, a working admin console, deep enterprise federation, and a login page you do not have to build. Pick Ory if the login is part of your product, you want to compose only the pieces you need, and you have the engineering capacity to own the frontend and several services. A useful tie breaker is to ask who will operate this in eighteen months. A platform team with a mixed estate of internal and third party applications tends to be happier with Keycloak. A product engineering team shipping a customer facing signup flow tends to be happier with Ory.

If you are weighing other self-hosted options at the same time, our Keycloak and ZITADEL comparison takes a different angle on the same decision.

Both have an authorization story, and both stop short of the same thing

This is the piece most comparisons skip, and it is the one that decides your architecture two years from now. So we want to talk about it.

Authentication answers who the user is. Authorization answers what that user, service, or agent is allowed to do once inside. Keycloak and Ory both ship something in that second category, and it is worth being precise about what each one gives you.

Keycloak has Authorization Services, a policy engine built into the server. You define resources, scopes, and permissions, then attach policies that can be role based, user based, group based, client based, time based, regex based, or aggregated from several others. There is also a JavaScript policy type, though it has to be deployed as a server extension rather than uploaded, so it is not the escape hatch it first looks like. It is a genuine policy engine and it is more capable than most people realise. The constraint is where it runs. Decisions are evaluated at the identity provider, which sees identity and its own resource definitions but not the actual row in your database, its current state, or the rest of the request context. You end up mirroring application objects into Keycloak so it has something to reason about, and keeping those two models in sync is a maintenance tax that grows with the product.

Ory Keto is a different model. It implements the Zanzibar approach, storing relationship tuples such as "this user is an editor of this document" and answering permission checks by traversing that graph. Relationship based access control is genuinely fine grained, and Keto is strong at hierarchies and sharing, where permission flows down a tree of folders or organisations, though the model is built around what an object and a subject are to each other rather than what is true at the moment of the request. Ory describes Permissions as covering RBAC and ABAC and beyond, and the graph does express a lot, but a tuple records a fact about two objects and carries no request attributes. Rules like "only during business hours", "only from a managed device", "only while the record is unlocked", or "only if the invoice total is under the approver's limit" therefore live outside it. You either denormalise those conditions into tuples, which multiplies the data you have to keep current, or you check them in application code, which is exactly the place you were trying to get that logic out of.

Both approaches also share a structural problem with roles carried in tokens. A role assigned at the identity layer tells you someone is an editor. It does not tell you whether this editor may modify this specific document, in this tenant, right now. That distinction is the difference between role based and attribute based access control, and it is why stuffing more claims into the JWT stops scaling once the rules depend on the resource as well as the user.

The failure mode is real. When the AI feature on a widely used work management platform exposed data across tenants between early May and early June 2025, roughly a thousand customers were potentially affected. Login was not broken. Requests arrived with valid credentials. Nothing checked whether the authenticated user should see the specific resource being returned. The gap was not the identity provider, and no choice between Keycloak and Ory would have closed it, because nothing in either stack enforces a check the application never asks for. That is the argument for making the decision an explicit, testable layer instead of a convention.

How the decision layer works when it is separate

A dedicated authorization layer sits downstream of whichever identity provider you picked and answers one question per request. Can this principal perform this action on this resource, given everything that is true right now?

The Cerbos authorization management platform is built for that job, and the two things it does are the two things the models above cannot. First, a single rule reads token claims and resource attributes in the same expression, because policies are YAML with CEL (Common Expression Language) conditions evaluated where the resource actually lives. A document policy can require that the principal's Keycloak realm role is editor, that the document is not locked, that its tenant matches the principal's, and that the request falls inside working hours, in one condition that neither Keycloak's engine nor Keto can express on its own. Second, every decision is logged with the policy version that produced it, which is a level of detail an access log or a relationship change feed does not carry and is what an auditor asks for.

Mechanically the policy decision point is stateless, holding no user database and no session state, so it runs as a sidecar beside each service and the check never leaves the pod. That is what makes low latency authorization practical rather than aspirational. It also speaks the OpenID AuthZEN standard, so it slots in as a standards-based decision point rather than a proprietary one.

For Keycloak the integration is direct. Realm roles, client roles, group memberships, and user attributes travel as principal attributes into policy evaluation, covered in our Keycloak integration notes. Where the token does not carry enough, Cerbos Synapse pulls the fuller profile from the Keycloak directory at decision time, including nested group paths that would never fit in a JWT. With Ory the pattern is the same, since the decision point does not care which provider minted the identity. Either way, your identity provider keeps identity and a separate layer owns the authorization decision, which keeps both replaceable.

A practical way to choose

Start with the login screen, because it is the fastest way to separate these two. If you need it working next week and it can look like a login page, Keycloak. If it is part of the product and has to look like the product, Ory. Then check who operates it, since one deployment and one console is a very different commitment from several services and a frontend you maintain.

After that, decide the authorization question deliberately rather than inheriting whatever your identity provider happens to offer. Keycloak's policy engine and Ory's relationship model both do real work, and for coarse decisions either is fine.

Once your rules start depending on the state of the resource and the shape of the request, plan for a separate decision layer early, because moving authorization out of an application that has grown around it is a far larger project than starting with it outside. If you want a structured way to run that evaluation, we published a framework for it.

Getting started

The fastest way to test the argument in this piece is to write one policy that reads both a token claim and a resource attribute and see whether it expresses a rule your identity provider could not. Try Cerbos to build and deploy that policy across your services.

If you would rather talk it through first, book a call with our authorization experts. For the longer version of the argument, read already have authentication, here is the authorization layer you still need, or take the step by step playbook for decoupling authorization from application code.

FAQ

Tagged in

Free policy workshop

Get your first Cerbos policy written by our team.

Book a session to talk through your requirements and walk away with a working policy.

Book a session