Ory Keto: a Zanzibar-style permission server you run yourself
The most scalable and customizable permission server on the market. Fix your slow or broken permission system with Google's proven "Zanzibar" approach. Supports ACL, RBAC, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
At a glance
- What is it?
- Ory Keto implements Google's Zanzibar model as a Go authorization server, with relation tuples, the Ory Permission Language and a self-hosted or managed deployment path. It suits teams that need relationship-based checks; it is a poor fit if you only need a handful of static roles.
- Who is it for?
- Adopt Ory Keto if your authorization questions are relationship-shaped (who can read this document, who is an editor of this folder) and you can operate a database-backed service. Do not adopt it for a fixed set of three roles checked in one application, and do not adopt the open source distribution for a business-critical system without reading the Ory Enterprise License terms, since the README ties guaranteed CVE fixes and SLAs to a commercial agreement.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 26 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Ory Keto solves, and who actually has it
Application code usually starts with a role column and ends up with permission checks scattered across services. Ory Keto moves those checks into a separate server that answers one question: does this subject have this relation to this object? The README frames it as an open source implementation of "Zanzibar: Google's Consistent, Global Authorization System", and lists the intended properties: scalable permission checks, the Ory Permission Language for defining policies, relationship-based access control (ReBAC), low latency checks, horizontal scaling to billions of relationships, consistency and high availability.
That description tells you who it is for. If your access rules are naturally relational (a document belongs to a folder, a folder belongs to a team, a team has members), a tuple store matches the shape of the problem better than a table of roles. If your rules are a short, fixed list of roles with no nesting, the same machinery is overhead. The README also states that Keto works with any identity provider through integration points, so it does not force you onto Ory's identity stack, though the surrounding ecosystem (Kratos for identities, Hydra for OAuth2 and OpenID Connect, Oathkeeper as an identity and access proxy) is where the integration is best documented.
Relation tuples, namespaces and the Ory Permission Language
The core data model is the relation tuple. The README's quickstart writes one directly: a document called secret, the relation read, and the subject tom. Everything the server decides is derived from tuples like that one, plus the namespace definitions that say which relations exist and how they inherit.
Namespaces are written in the Ory Permission Language, a TypeScript-like syntax. The quickstart's example is minimal: `class Document implements Namespace {}`. A namespace with no configuration declares the object type but no relations; real policies add relations and rules that let a permission on one object follow from a relation on another. That is the mechanism behind ReBAC: you grant a relation on a container, and the check on a child resolves through the namespace rules rather than through duplicated grants.
The README describes permission checks as low latency, and the repository's go.mod shows a dependency on dgraph-io/ristretto, an in-process cache. That is consistent with a design where repeated checks are served without a database round trip, but the README does not document cache invalidation semantics, so treat the caching behaviour as something to verify against your own consistency requirements rather than something the front page settles.
Two ports, two APIs: 4466 and 4467 in the Docker Compose file
The repository's docker-compose.yml exposes two ports, 4466 and 4467, and runs the server with `serve -c /home/ory/keto.yml`, binding config/keto.yml into the container. Two ports for one service usually means two protocols, and the go.mod dependencies confirm the split: connectrpc.com/connect, grpc, grpchealth and grpcreflect are all present, alongside OpenTelemetry instrumentation for net/http. Practically, one port serves the gRPC/Connect API and the other the REST API, and clients pick whichever their language tooling supports.
The Compose file also sets `restart: on-failure` and pins the image to oryd/keto:v26.2.0, which is the most recent release listed. That pinning matters: the release history shows v0.14.0 in March 2025, v25.4.0 in November 2025, and v26.2.0 in March 2026, so the project moved to calendar-style version numbers partway through. A deployment that tracked `latest` would have crossed that boundary silently. The README does not describe the migration steps for that jump; UPGRADE.md exists in the repository root and is where that information would live.
Running Ory Keto with Docker and granting a first permission
The README's own quickstart goes through the Ory CLI and Ory Network rather than a local server. It installs the CLI, signs in, and creates a project:
# Install the Ory CLI if you do not have it yet:
bash <(curl https://raw.githubusercontent.com/ory/meta/master/install.sh) -b . ory
sudo mv ./ory /usr/local/bin/
# Sign in or sign up
ory auth
# Create a new project
ory create project --create-workspace "Ory Open Source" --name "GitHub Quickstart" --use-projectAfter the project exists, the quickstart defines a namespace in the Ory Permission Language, applies it, and creates a tuple granting tom read access to a document:
# Write a simple configuration with one namespace
echo "class Document implements Namespace {}" > config.ts
# Apply that configuration
ory patch opl -f file://./config.ts
# Create a relationship that grants tom access to a document
echo "Document:secret#read@tom" \
| ory parse relation-tuples --format=json - \
| ory create relation-tuples -
# List all relationships
ory lThe tuple string follows the format object:identifier#relation@subject, so `Document:secret#read@tom` is namespace Document, object secret, relation read, subject tom. The parse step converts that human-readable form into JSON for the create call. After `ory l`, you should see the tuple listed.
For a self-hosted server, the repository's docker-compose.yml is the starting point. It expects config/keto.yml to exist on the host, so the Compose file is not self-sufficient:
docker compose upThis starts the container on ports 4466 and 4467 with the config bound in. The README points self-hosters at the install guide for Linux, macOS, Windows and Docker, for configuring PostgreSQL, MySQL or CockroachDB, and for Kubernetes deployment. Building from source is covered there too; the Makefile's install target is simply `go install .`.
Where Ory Keto is the wrong tool
The README is explicit that the open source distribution is aimed at individuals, researchers, hackers, and companies that want to experiment, prototype, or run unimportant workloads without SLAs. That sentence is the sharpest limitation in the whole document. It means the free build is not positioned for business-critical authorization, and the features that make production operation easier (advanced scaling, multi-tenancy, complex deployments, regular security releases with CVE patches under an SLA, and access to a private Docker registry of vetted builds) sit behind the Ory Enterprise License.
There is a second limitation that has nothing to do with licensing. A tuple store answers authorization questions; it does not authenticate anyone. Ory Keto has no opinion about who tom is, which is why the README lists integration points with any identity provider and why the surrounding ecosystem includes Kratos for identity management. If you expected a permission server to also handle login, you will be wiring two systems together.
Finally, consider the operational surface. You need a supported database (PostgreSQL, MySQL or CockroachDB per the install guide), a config file, and a decision about which API port your services call. For a small application with a roles table, that is more moving parts than the problem justifies.
Ory Keto compared with OpenFGA and OPA
The most natural comparison is OpenFGA, another open source implementation of the Zanzibar model. Both use relation tuples and both separate authorization from application code, so the difference is not the model. It is the surrounding stack and the policy language: Ory Keto ships the Ory Permission Language, a TypeScript-like syntax for namespaces, and sits in an ecosystem with Kratos, Hydra and Oathkeeper under a single vendor. Choosing between them is largely a question of which ecosystem you already run and which policy language your team will maintain.
The comparison with Open Policy Agent is a difference in kind, not degree. OPA evaluates policies written in Rego against a document you feed it; it is a general policy engine that can express authorization, admission control and other decisions. Ory Keto stores relationships and answers permission checks derived from them. If your rules are naturally relational, Keto's model removes the work of assembling the data a Rego policy needs. If your rules are arbitrary logic over request attributes, a general policy engine expresses them more directly. The README does not position Keto against either project, so treat this as a structural distinction rather than a claim from the documentation.
Licence, releases and what an upgrade costs you
The repository is licensed Apache-2.0, and package.json carries `"license": "Apache 2.0"`. That covers the open source distribution. It does not cover the Ory Enterprise License, which the README describes as layering on top of self-hosted Keto for additional enterprise features, security releases with CVE patches under SLAs, advanced scaling and multi-tenancy, premium support, and access to a private Docker registry. Those are separate terms; nothing here is legal advice, and the README points to the Ory Enterprise License page and a contact form for the actual conditions.
The upgrade cost is visible in the release list. Three releases are named: v0.14.0 on 2025-03-06, v25.4.0 on 2025-11-07, and v26.2.0 on 2026-03-20. The gap between v0.14.0 and v25.4.0 is roughly eight months with a version scheme change, and the gap between v25.4.0 and v26.2.0 is about four months. The last push to the default branch was on 2026-09-04, which is recent, but the README does not document a support window for older releases or a backport policy for the open source build. UPGRADE.md sits in the repository root, and that file, not the README, is where migration guidance would be found. If you pin an image tag, as the Compose file does, plan the jump deliberately rather than letting a version bump arrive with a rebuild.
Editorial conclusion
Adopt Ory Keto if your authorization questions are relationship-shaped (who can read this document, who is an editor of this folder) and you can operate a database-backed service. Do not adopt it for a fixed set of three roles checked in one application, and do not adopt the open source distribution for a business-critical system without reading the Ory Enterprise License terms, since the README ties guaranteed CVE fixes and SLAs to a commercial agreement. Before committing, verify which of the two ports your clients will call, and check UPGRADE.md for the migration path from your current version, because the release history jumps from v0.14.0 to v25.4.0 and then v26.2.0.
Frequently asked questions
What is Ory Keto?
It is an open source authorization server written in Go that implements Google's Zanzibar model, using relation tuples and the Ory Permission Language to answer permission checks. The README describes it as supporting relationship-based access control and scaling horizontally to billions of relationships, available as a managed service on Ory Network or self-hosted.
How does Ory Keto compare with OPA?
They differ in kind. Ory Keto stores relationships and derives permission checks from them, while Open Policy Agent is a general policy engine. The README does not compare the two, so the distinction rests on the data model each one uses.
What are the alternatives to Ory Keto?
OpenFGA is the closest alternative, since it also implements the Zanzibar model with relation tuples; the practical difference is Ory Keto's Ory Permission Language and its place in the Ory ecosystem alongside Kratos, Hydra and Oathkeeper. A general policy engine such as Open Policy Agent is an alternative when the rules are not naturally relational.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ory-keto)