Dead simple role-based access control for FastAPI
Project description
FastAPI Simple RBAC
Dead simple role-based access control for FastAPI.
Why?
I got tired of writing the same role-checking boilerplate in every FastAPI project. This package lets you protect endpoints with a simple decorator:
@app.get("/admin")
@require_roles("admin")
def admin_only(request: Request):
return {"message": "You're an admin!"}
That's it. No complex setup, no learning curve.
Installation
pip install fastapi-simple-rbac
Quick Start
from fastapi import FastAPI, Request
from fastapi_simple_rbac import RBACMiddleware, require_roles
app = FastAPI()
app.add_middleware(RBACMiddleware)
@app.get("/admin")
@require_roles("admin")
def admin_dashboard(request: Request):
return {"message": "Welcome, admin!"}
By default, it looks for roles in JWT tokens (in the Authorization header). If you need something else, keep reading.
Examples
Multiple roles
# User needs BOTH roles
@require_roles(["admin", "editor"], require_all=True)
def admin_editor_only(request: Request):
return {"message": "You're both admin AND editor"}
# User needs ANY of these roles
@require_roles(["admin", "editor", "moderator"], require_all=False)
def staff_only(request: Request):
return {"message": "You're staff"}
# Shorthand for the above
@require_any_role(["admin", "editor", "moderator"])
def staff_only_alt(request: Request):
return {"message": "Same thing"}
Custom role sources
Don't use JWT? No problem. Write your own role getter:
def get_roles_from_database(request: Request):
user_id = request.headers.get("X-User-ID")
return database.get_user_roles(user_id)
app.add_middleware(RBACMiddleware, role_getter=get_roles_from_database)
Or from headers:
def get_roles_from_header(request: Request):
roles = request.headers.get("X-User-Roles", "")
return roles.split(",") if roles else []
app.add_middleware(RBACMiddleware, role_getter=get_roles_from_header)
Async role getters work too:
async def get_roles_from_api(request: Request):
user_id = extract_user_id(request)
async with httpx.AsyncClient() as client:
response = await client.get(f"/users/{user_id}/roles")
return response.json()["roles"]
app.add_middleware(RBACMiddleware, role_getter=get_roles_from_api)
JWT Configuration
app.add_middleware(
RBACMiddleware,
secret_key="your-secret-key",
verify_jwt_signature=True, # Set to False for development
role_claim="permissions" # Default is "roles"
)
Custom error messages
@require_roles("vip", error_message="VIP membership required!")
def vip_lounge(request: Request):
return {"message": "Welcome to the VIP lounge"}
Custom error handling
def custom_error_handler(request: Request, exception: RBACException):
return JSONResponse(
status_code=exception.status_code,
content={"error": "Nope", "details": exception.message}
)
app.add_middleware(RBACMiddleware, error_handler=custom_error_handler)
FastAPI Dependencies
If you prefer dependency injection:
from fastapi import Depends
from fastapi_simple_rbac import get_current_user_roles, create_role_dependency
# Inject roles into your endpoint
@app.get("/profile")
def get_profile(roles: list = Depends(get_current_user_roles)):
return {"your_roles": roles}
# Create reusable dependencies
admin_required = create_role_dependency("admin")
@app.get("/admin", dependencies=[Depends(admin_required)])
def admin_endpoint():
return {"message": "Admin access"}
JWT Token Format
Your JWT should look like this:
{
"sub": "user123",
"roles": ["admin", "editor"],
"exp": 1234567890
}
The roles can be a single string or an array. Both work fine.
Development
git clone https://github.com/yourusername/fastapi-simple-rbac
cd fastapi-simple-rbac
pip install -e ".[dev]"
pytest
License
MIT. Do whatever you want with it.
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 fastapi_simple_rbac-0.1.1.tar.gz.
File metadata
- Download URL: fastapi_simple_rbac-0.1.1.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0b0b99b6859cc4d3fd8bb8299894fa0105cab00d4b36729f27a1e397e02a00f9
|
|
| MD5 |
50cfd488aca8abed5d2ec1f2c4ca4209
|
|
| BLAKE2b-256 |
77d3c19a751efaaa6cf0394afbe723d0681afc723e86c49120cde514b77d6b55
|
File details
Details for the file fastapi_simple_rbac-0.1.1-py3-none-any.whl.
File metadata
- Download URL: fastapi_simple_rbac-0.1.1-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8bad3aa5bd6fbce8e8959f8a61643ee0600462ff45afc623248210c48354f6b3
|
|
| MD5 |
aa0caac0fc7251a969d5135a7d4ae537
|
|
| BLAKE2b-256 |
1c91ad781e74fd45b5df8f6a19babec5a87e75714bf55a20839a7b71bb151d3c
|