CA

Casbin

Authorization library supporting many access control models

Identity & SSO ★ 20.4k stars Medium setup Apache-2.0

Casbin is an open-source authorization library that supports access control models such as ACL, RBAC, and ABAC. It is embedded in applications or run with self-hosted services for centralized policy enforcement.

Key features

  • Multiple access models
  • Policy as configuration
  • Many language ports
  • Storage adapters

Pros & cons

Strengths

  • Many access control models
  • Multi-language ports
  • Battle-tested library

Trade-offs

  • Library rather than service
  • Policy syntax takes learning

Casbin replaces

Last reviewed Aug 26, 2026 · 889 words

Casbin is not something you deploy. It is a library your application imports, and what it buys you is that the question "may this user do this to that" leaves your code and lands in 2 text files: a model that says how decisions are made, and a policy that lists who may do what. If you maintain a self-hosted app whose permission checks are if user.is_admin or item.owner == user scattered across 40 handlers, Casbin is the fix. If you want a login page, it is the wrong tool entirely; that job belongs to an identity provider like Authentik, and Casbin sits behind it deciding what the authenticated user may touch.

The model file does the thinking, the policy file does the listing

A Casbin model is a short INI file describing the shape of a request, the shape of a policy line, how roles inherit, and the matcher expression that ties them together. This one is plain RBAC:

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

The policy is a CSV of facts:

p, admin, /api/backups, write
p, viewer, /api/backups, read
g, alice, admin

And the call site in Go is 2 lines:

e, _ := casbin.NewEnforcer("model.conf", "policy.csv")
ok, _ := e.Enforce("alice", "/api/backups", "write")

The point is what happens when requirements change. Adding "owners can edit their own items" is a matcher edit (|| r.obj.Owner == r.sub), not a code change. Swapping exact path matching for patterns is keyMatch(r.obj, p.obj). The code that calls Enforce never moves.

Start with RBAC and add attributes only when you can name them

Casbin ships example models for ACL, RBAC, RBAC with domains for multi-tenant apps, ABAC, RESTful path matching, deny-override and priority policies. That breadth is the main selling point and the main way people hurt themselves. In my experience 9 self-hosted apps in 10 need exactly two things: roles, and "you own it or you don't". That is the RBAC model above plus one ownership clause. Reach for ABAC when a real attribute drives the decision: time of day, source IP, a document's classification. The policy syntax takes an afternoon to learn, and the online editor at casbin.org lets you test a model and policy against sample requests before touching code, which I would do every time.

Adapters put the policy in your database, watchers keep instances in sync

A CSV file is fine for a single-binary app with a fixed role set. The moment users create roles at runtime you want an adapter, and Casbin has them for GORM, xorm, raw SQL, Redis, MongoDB and most things with a driver. Policies load into memory at startup and Enforce runs against that in-memory copy, so the library adds negligible overhead to a request. Run 2 replicas and you also want a watcher (Redis is the common one) so a policy saved on one instance is reloaded on the others. Skip the watcher and you get the classic "I revoked access but it still works" ticket.

The same model file works across the language ports: jCasbin, node-casbin, PyCasbin, Casbin.NET, casbin-rs and PHP-Casbin. A Go API and a TypeScript front end can enforce identical rules from one shared model.conf, which is worth more than it sounds when a team argues about who can see what.

What it is not, and what to run next to it

Casbin does not authenticate anyone. It trusts whatever subject you pass in, so the identity layer is yours to provide: a session from your own login, a JWT from Authentik, a header from a forward-auth proxy. It is also not a network service by default. A Casbin Server project exists that exposes enforcement over gRPC, but if you want a standalone policy decision point that several services query, compare it against Open Policy Agent, and if your permissions are relationship-shaped ("editors of the folder this file is in") look at OpenFGA, which models that directly. The Casbin organisation's own answer to "I want a server" is Casdoor, an identity provider built on top of Casbin.

Two catalogue notes. The 128 MB figure is really "whatever your host application uses"; the library itself holds a policy table in memory and little else. And the Apache-2.0 licence means embedding it in a closed product is fine, which is one reason it has 20,000-plus stars and shows up inside so many other projects.

What I'd do

Building or forking a self-hosted app: RBAC-with-domains model, GORM adapter against the app's existing database, a Redis watcher the day you run a second replica, and a test file that asserts a dozen allow/deny pairs so a matcher typo fails CI instead of production. Running a homelab and not writing code: you do not need Casbin. Put Authentik in front of your services and let its groups be the policy. Casbin earns its place the moment you are the one writing the handlers.

Similar identity & sso apps