# PyCasbin uses CONF to define an access control model

> PyCasbin is the Apache 2.0 licensed Python port of the Casbin authorization library, where the model lives in a CONF file and the rules live in a CSV file. It is a fit when your authorization needs change shape often, and a poor fit when you want the decision hard coded in code and typed.

**apache/casbin-pycasbin** — An authorization library that supports access control models like ACL, RBAC, ABAC in Python

- Repository: https://github.com/apache/casbin-pycasbin
- Website: https://casbin.org
- Stars: 1,776 · Forks: 222
- Language: Python
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/apache-casbin-pycasbin

## The model file is the contract, and the CSV is the data

Casbin splits authorization into two files. The model is a CONF file written against what the project calls the PERM metamodel, standing for Policy, Effect, Request and Matchers. The policy is a CSV file of rules, loaded at runtime and mutable through the management API without touching code.

That split is the whole design decision. Switching from plain ACL to RBAC, or folding ABAC attributes into an RBAC model, is an edit to the CONF file rather than a refactor. The README is explicit that a custom model can be assembled by combining available models, and that you can hold RBAC roles and ABAC attributes in one model sharing one set of policy rules.

The trade is the matcher. Because the model is evaluated, not executed as compiled Python, an expression typo in a matcher becomes a runtime failure on a request path rather than an import error at deploy time. The repository ships an examples/error/ directory alongside the model and policy files, which acknowledges that these two file types fail in ways code does not.

## Eleven models, and the ones that actually change the code around them

The README enumerates the supported models. ACL is the base case. Then come ACL with superuser, ACL without users for systems with no login at all, and ACL without resources, where permissions name a type of resource such as `write-article` instead of a specific one. RBAC is there, along with resource roles where both users and resources carry roles, and RBAC with domains so a user holds different role sets per tenant.

ABAC is the one that changes your Python. Attribute access is described as syntax sugar, so something like `resource.Owner` can be used inside the matcher. In practice that means your objects have to expose the attributes the matcher names, which couples your domain model to the authorization file. ABAC variants in the examples directory, `abac_model.conf`, `abac_rule_model.conf` and `abac_multiple_rules_model.conf`, show that there is more than one shape for this.

RESTful matching handles paths like `/res/*` and `/res/:id` with HTTP methods, ipmatch covers network ranges, keymatch and globmatch cover URL patterns. Priority makes rules behave like firewall rules, and deny-override lets a deny beat an allow. Those two last models are mutually significant: the same policy line answers differently depending on which one you configure.

## Installation and the two runtime dependencies

PyCasbin is published on PyPI as `pycasbin` and the README carries its installation section, so the package manager path is the documented one. There is no first party binary or container image to worry about: it is a pure Python library.

The dependency list in requirements.txt is short and worth knowing before you take the dependency. Both are hard requirements, not extras.

The package metadata in pyproject.toml requires Python 3.8 or newer and classifies support up through 3.13, with the build backend set to setuptools and dependencies resolved dynamically from requirements.txt. The pyproject version field reads 2.6.1 while the most recent published tag is v2.8.0 from 2026-02-02, which tells you the manifest in the default branch is not always the version on PyPI. Pin deliberately.

## Enforce, manage and the sync problem

The library has two surfaces. The enforcer answers whether a subject may act on an object, and the management API lets code add, remove or inspect policy rules at runtime. That management API is what makes dynamic delegation possible, such as granting a role without a deploy.

The same capability is the operational hazard. Policy in CSV is convenient in development and awkward in production, because a CSV file has no transactions, no history and no concurrency story. The README documents policy persistence as a topic but the repository contents show no database adapter module beyond the casbin package, so if you persist policies anywhere but a file you are writing that adapter yourself.

Role inheritance is handled by a role manager rather than by the model file, which is a separate object with its own behaviour. Async support arrived in Pycasbin 1.23.0 through a separate async enforcer, so an asyncio application needs the async class rather than the sync one.

## What it will not do for you

Casbin decides. It does not authenticate, it does not know who the caller is, and it has no opinion about sessions or tokens. Pairing it with an identity layer is your job.

Log and audit behaviour is listed as a topic in the README, and logging is separately configurable, but there is no built in decision log with a durable store in the repository layout. If you need to answer later why a request was allowed, capture the request, the model version and the policy revision at call time yourself.

Framework integration is out of tree. For Django the README points at a separate project, officialpycasbin/django-authorization, rather than shipping middleware in this repository.

## Against a hand written permission check

The realistic alternative is a decorator or a helper in your own code, `if user.can_edit(post):...`, backed by whatever your ORM gives you. It can be typed and greppable without requiring a configuration file.

PyCasbin wins when the rules are combinatorial: multiple tenants, several resource types, a superuser, an exception list, and a REST surface. Hand written checks express that as a growing pile of conditionals, and the pile is where authorization bugs live.

PyCasbin loses when the rule is one comparison. A CONF file, a CSV loader and an expression evaluator are more moving parts than `user.org_id == post.org_id`, and every one of them is a thing that can be misconfigured at deploy time without a traceback at startup. The C++ implementation is still labelled beta-test in the language table, by the way, so cross language policy sharing is not uniformly settled.

## Apache 2.0, a disclaimer file and an active but uneven release line

The licence is Apache 2.0, which allows commercial use and modification with attribution and patent grant preserved, and the repository carries both a NOTICE and a DISCLAIMER file. The disclaimer is worth reading before you build on this, since an authorization library's contract is narrower than its marketing.

The repository is an Apache Software Foundation project rather than a personal one, which matters for governance. It is not archived and the last push was on 2026-10-09.

Release cadence is uneven, though. The three most recent tags are v2.8.0 on 2026-02-02, v2.7.1 on 2026-01-01 and v2.7.0 on 2025-12-28, while the default branch has seen a later push. That pattern suggests maintenance continues without a scheduled release train, so an upgrade means watching tags rather than watching announcements. There is a CHANGELOG.md in the repository to check before moving a pin.

## Conclusion

Adopt PyCasbin if your authorization rules change often enough that editing a data file beats shipping a code change, and if you can accept a match layer that is evaluated at runtime rather than at import time. Do not adopt it if you need a decision to be a static, typed function of your domain objects. Before wiring it in, read the model CONF you intend to use and test it against a deny rule, because a deny-override model and an allow-only model produce opposite answers for the same policy line, and the library cannot tell you which one you meant.

## FAQ

### How do I install PyCasbin?

It is published on PyPI as pycasbin and the README carries an installation section. It requires Python 3.8 or newer and pulls in simpleeval and wcmatch as runtime dependencies.

### What access control models does PyCasbin support?

The README lists ACL, ACL with superuser, ACL without users, ACL without resources, RBAC, RBAC with resource roles, RBAC with domains, ABAC, RESTful, deny-override and priority. Models are composed through a CONF file and rules are held in a CSV file.

### Does PyCasbin support async Python?

Yes. The README states that async is supported from Pycasbin 1.23.0 onward, through a separate async enforcer, so an asyncio application should use that class rather than the synchronous one.

### How do I use PyCasbin with Django?

The README does not ship Django middleware in this repository. It points you at a separate project, officialpycasbin/django-authorization, described as an authorization library for the Django framework.

## Sources

- [apache/casbin-pycasbin on GitHub](https://github.com/apache/casbin-pycasbin)
- [License: Apache-2.0](https://github.com/apache/casbin-pycasbin/blob/master/LICENSE)
- [Project website](https://casbin.org)
- [README](https://github.com/apache/casbin-pycasbin/blob/master/README.md)
- [Releases](https://github.com/apache/casbin-pycasbin/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/apache-casbin-pycasbin
