Decorator-based authorization for FastAPI with Casbin, without middleware
Project description
casbin-fastapi-decorator
Authorization decorator factory for FastAPI based on Casbin and fastapi-decorators.
Decorators are applied to routes — no middleware or dependencies in the endpoint signature.
Installation
pip install casbin-fastapi-decorator
Additional providers:
pip install "casbin-fastapi-decorator[jwt]" # JWT authentication
pip install "casbin-fastapi-decorator[db]" # Policies from DB (SQLAlchemy)
Quick start
import casbin
from fastapi import FastAPI, HTTPException
from casbin_fastapi_decorator import AccessSubject, PermissionGuard
# 1. Providers — regular FastAPI dependencies
async def get_current_user() -> dict:
return {"sub": "alice", "role": "admin"}
async def get_enforcer() -> casbin.Enforcer:
return casbin.Enforcer("model.conf", "policy.csv")
# 2. Decorator factory
guard = PermissionGuard(
user_provider=get_current_user,
enforcer_provider=get_enforcer,
error_factory=lambda user, *rv: HTTPException(403, "Forbidden"),
)
app = FastAPI()
# 3. Authentication only
@app.get("/me")
@guard.auth_required()
async def me():
return {"ok": True}
# 4. Static permission check
@app.get("/articles")
@guard.require_permission("articles", "read")
async def list_articles():
return []
# 5. Dynamic check — value from request
async def get_article(article_id: int) -> dict:
return {"id": article_id, "owner": "alice"}
@app.get("/articles/{article_id}")
@guard.require_permission(
AccessSubject(val=get_article, selector=lambda a: a["owner"]),
"read",
)
async def read_article(article_id: int):
return {"article_id": article_id}
Arguments of require_permission are passed to enforcer.enforce(user, *args) in the same order. AccessSubject is resolved via FastAPI DI, then transformed by the selector.
API
PermissionGuard
PermissionGuard(
user_provider=..., # FastAPI dependency that returns the current user
enforcer_provider=..., # FastAPI dependency that returns a casbin.Enforcer
error_factory=..., # callable(user, *rvals) -> Exception
)
| Method | Description |
|---|---|
auth_required() |
Decorator: authentication only (user_provider must not raise an exception) |
require_permission(*args) |
Decorator: permission check via enforcer.enforce(user, *args) |
AccessSubject
AccessSubject(
val=get_item, # FastAPI dependency
selector=lambda item: item["name"], # transformation before enforce
)
Wraps a dependency whose value needs to be obtained from the request and passed to the enforcer. By default, selector is identity (lambda x: x).
JWT provider
casbin-fastapi-decorator-jwt — extracts and validates a JWT from the Bearer header and/or a cookie.
pip install "casbin-fastapi-decorator[jwt]"
See packages/casbin-fastapi-decorator-jwt/README.md for full API and usage.
DB provider
casbin-fastapi-decorator-db — loads Casbin policies from a SQLAlchemy async session.
pip install "casbin-fastapi-decorator[db]"
See packages/casbin-fastapi-decorator-db/README.md for full API and usage.
Casdoor provider
casbin-fastapi-decorator-casdoor — Casdoor OAuth2 authentication and remote Casbin policy enforcement.
pip install "casbin-fastapi-decorator[casdoor]"
from casbin_fastapi_decorator_casdoor import CasdoorEnforceTarget, CasdoorIntegration
casdoor = CasdoorIntegration(
endpoint="http://localhost:8000",
client_id="...", client_secret="...", certificate=cert,
org_name="my_org", application_name="my_app",
target=CasdoorEnforceTarget(
enforce_id=lambda parsed: f"{parsed['owner']}/my_enforcer",
),
)
app.include_router(casdoor.router) # GET /callback, POST /logout
guard = casdoor.create_guard()
CasdoorEnforceTarget selects the Casdoor enforce mode — by enforcer, permission, model, resource, or owner. Values can be static strings or callables resolved from the JWT payload at request time.
See packages/casbin-fastapi-decorator-casdoor/README.md for full API, compose pattern, and usage.
Examples
| Example | Description |
|---|---|
examples/core |
Bearer token auth, file-based Casbin policies |
examples/core-jwt |
JWT auth via JWTUserProvider, file-based policies |
examples/core-db |
Bearer token auth, policies from SQLite via DatabaseEnforcerProvider |
examples/core-casdoor |
Casdoor OAuth2 auth + remote enforcement, facade and compose patterns |
Development
Requires Python 3.10+, uv, task.
task install # uv sync --all-groups + install extras (jwt, db, casdoor)
task lint # ruff + ty + bandit for all packages
task tests # all tests (core + jwt + db + casdoor)
Individual package tasks:
task core:lint # lint core only
task core:test # test core only
task jwt:lint # lint JWT package
task jwt:test # test JWT package
task db:lint # lint DB package
task db:test # test DB package (requires Docker for testcontainers)
task casdoor:lint # lint Casdoor package
task casdoor:test # test Casdoor package
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file casbin_fastapi_decorator-0.2.1.tar.gz.
File metadata
- Download URL: casbin_fastapi_decorator-0.2.1.tar.gz
- Upload date:
- Size: 5.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
47bcdcc24c03112e050756939ce021addcfa8f9fc7902416df2c3c1a241fa371
|
|
| MD5 |
3cd9f129708542c6113c9971dd2eec29
|
|
| BLAKE2b-256 |
c9097985537ce69e046d8c55929b9005dbd1186fdc01eeaed19c917820b07968
|
File details
Details for the file casbin_fastapi_decorator-0.2.1-py3-none-any.whl.
File metadata
- Download URL: casbin_fastapi_decorator-0.2.1-py3-none-any.whl
- Upload date:
- Size: 7.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6a44249a8f114ea8a6a74daf67e3f8ba9bb365274ab37de56c67cca4dbf6980
|
|
| MD5 |
11a647a60a45d2cad637ef1fbc1240b8
|
|
| BLAKE2b-256 |
46f6223382644abb8fdbf6225db6b0c0e8e651137cd8494986246727fcce8fdc
|