Skip to main content

Decorator-based authorization for FastAPI with Casbin, without middleware

Project description

casbin-fastapi-decorator logo

casbin-fastapi-decorator

Authorization decorator factory for FastAPI based on Casbin and fastapi-decorators.

PyPI Python PyPI Downloads License CI codecov

📚 Documentation · PyPI · Casbin Ecosystem


Decorators are applied directly to routes — no middleware, no extra parameters in your function signatures.

Why decorator, not middleware?

Feature casbin-fastapi-decorator fastapi-authz / fastapi-casbin-auth
Approach Decorator per route Global middleware
Per-route permission config
Dynamic objects from request AccessSubject
No extra params in endpoint signature
Native FastAPI DI integration ⚠️ partial
JWT extras
DB-backed policies (SQLAlchemy async)
Casdoor OAuth2 integration
Works with APIRouter

Middleware-based authorization checks every incoming request globally. With a decorator, you configure permissions exactly where the route is defined — no hidden side effects, no boilerplate dependencies in every function signature.

Installation

pip install casbin-fastapi-decorator

Optional extras — install only what you need:

pip install "casbin-fastapi-decorator[jwt]"      # JWT authentication
pip install "casbin-fastapi-decorator[db]"       # Policies from DB (SQLAlchemy)
pip install "casbin-fastapi-decorator[casdoor]"  # Casdoor OAuth2

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 — object resolved 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)
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 is resolved 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         task core:test
task jwt:lint          task jwt:test
task db:lint           task db:test         # requires Docker (testcontainers)
task casdoor:lint      task casdoor:test

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

casbin_fastapi_decorator-0.2.3.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

casbin_fastapi_decorator-0.2.3-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file casbin_fastapi_decorator-0.2.3.tar.gz.

File metadata

  • Download URL: casbin_fastapi_decorator-0.2.3.tar.gz
  • Upload date:
  • Size: 6.5 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

Hashes for casbin_fastapi_decorator-0.2.3.tar.gz
Algorithm Hash digest
SHA256 075dea569f777108e0e3ffc5bcfaf71b37f776c51ae0058eecadc60154a15452
MD5 a2b55a7ce79df85fe466797a82b3ddc6
BLAKE2b-256 9d597c119338dfc0ae104ff486b65d6bd93e8292c3727932e52647fc42563f84

See more details on using hashes here.

File details

Details for the file casbin_fastapi_decorator-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: casbin_fastapi_decorator-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 7.9 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

Hashes for casbin_fastapi_decorator-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 c010885b78639c41027b44815658d4d56f50794f2b8d2a5f2c00551dc3bcc6f9
MD5 d5ebb0f57f8d9d8b4307c9b03254d1fc
BLAKE2b-256 19fa4757bf6ee31ba231422dea4919dcea9627644efe241102998f4f53b15207

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page