Skip to main content

FastAPI RBAC (Role-Based Access Control) plugin with comprehensive user and permission management

Project description

Fastapi-rbac - Advanced RBAC FastAPI Extension

Python Version FastAPI Test Coverage License

A powerful, production-ready Role-Based Access Control (RBAC) extension for FastAPI applications. Fastapi-rbac provides comprehensive user, role, and permission management with fine-grained access control, dependency injection, and enterprise-grade features.

🚀 Key Features

Core RBAC Functionality

  • Complete Permission Model: Users → Roles → Permissions with flexible many-to-many relationships
  • Fine-grained Access Control: Permission-based dependency injection with OR logic support
  • Role Hierarchy: Support for role inheritance and system/custom role management
  • Soft Delete: Configurable soft delete for all entities with audit trail

Advanced Security Features

  • Permission-based Dependencies: require_permissions("user:read", "admin:write") decorator pattern
  • Role-based Dependencies: Traditional role-based access control support
  • Authentication Middleware: Pluggable authentication with JWT/session support
  • Security Audit: Comprehensive audit logging for permission changes

Developer Experience

  • Plug-and-Play: Single plugin class integration with minimal configuration
  • Type Safety: Full SQLModel and Pydantic v2 integration with type hints
  • Auto Documentation: Automatic OpenAPI/Swagger documentation generation
  • Flexible Configuration: Environment-based configuration with validation

Performance & Scalability

  • Optimized Queries: Single-query permission checking with efficient JOINs
  • Caching Ready: Built-in cache support for high-performance scenarios
  • Pagination: Advanced pagination with search and filtering
  • Connection Pooling: Production-ready database connection management

Integration & Deployment

  • SSO Integration: Single Sign-On support with user synchronization
  • Multiple Databases: Base on SQLModel. MySQL, PostgreSQL, SQLite support
  • Docker Ready: Container-friendly configuration
  • Production Features: Health checks, monitoring endpoints, CORS support

📋 Requirements

  • Python: 3.11+
  • Core Dependencies: FastAPI, SQLModel, Pydantic v2, aiocache, alembic

🛠 Installation

Using pip (Recommended)

pip install fastapi-rbac
# uv
uv add fastapi-rbac

# !!!!! ATTENTION:
# Due to the database dependency in the project, after updating the project code, it is necessary to use Alembic to generate the database tables and execute them.

🚀 Quick Start

ATTENTION

Due to the database dependency in the project, after updating the project code, it is necessary to use alembic to generate the database tables and execute them.

1. Basic Setup

from fastapi import FastAPI, Depends
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker

from fastapi-rbac import RBACPlugin, RBACConfig

# Create FastAPI app
app = FastAPI(title="My App with RBAC")

# Database setup
database_url = os.getenv("RBAC_DATABASE_URL", "sqlite+aiosqlite:///rbac.db")

SessionLocal = async_sessionmaker(engine, class_=AsyncSession)

async def get_db():
    async with SessionLocal() as session:
        yield session

# Configure RBAC
config = RBACConfig(
    table_prefix="myapp_",
    enable_soft_delete=True,
    cache_ttl=300
)

# Initialize RBAC plugin
rbac = RBACPlugin(config)

# Setup middleware
app.state.rbac_middleware = rbac.get_rbac_middleware()

# Register RBAC routes
rbac_router = rbac.get_router(get_db)
app.include_router(rbac_router, prefix="/api/rbac")

2. Permission-Based Access Control

from fastapi-rbac import require_permissions

# Protect endpoints with specific permissions
@app.get("/api/users")
async def list_users(
    _: bool = Depends(require_permissions("user:read", "user:list"))
):
    return {"users": []}

@app.post("/api/users")
async def create_user(
    _: bool = Depends(require_permissions("user:create", "admin:all"))
):
    return {"message": "User created"}

# Multiple permission check (OR logic)
@app.get("/api/admin/dashboard")
async def admin_dashboard(
    _: bool = Depends(require_permissions("admin:read", "system:admin"))
):
    return {"dashboard": "data"}

3. Using Plugin Methods

# Create permission dependencies via plugin
require_user_manage = rbac.get_permission_dependency("user:create", "user:update")

@app.put("/api/users/{user_id}")
async def update_user(
    user_id: int,
    _: bool = Depends(require_user_manage)
):
    return {"message": f"User {user_id} updated"}

examples

basic_usage

This end-to-end demo boots a fully configured FastAPI application with the RBAC plugin, admin frontend, and seed data. It showcases interactive permission testing via /index, complete CRUD dashboards for users/roles/permissions, and built-in redirects/login flows. The script also demonstrates how to initialize the database with sample roles, extend the default User model with custom fields, expose health/diagnostic endpoints, and wire permission-protected APIs (/api/need-user-read-permission) alongside open endpoints (/api/free-permission). Use it as the quickest way to experience the management UI, verify dependency injection behavior, and understand how session-based authentication cooperates with the RBAC middleware.

Commands

FastAPI RBAC provides two CLI commands to manage RBAC data:

1. Initialize Admin Data (init_data)

Initialize admin user, role, and permission. This command will:

  • Load FastAPI application from the module specified by --app parameter
  • Ensure database tables are created
  • Create admin permission (based on admin_permission_code from config)
  • Create a role named "admin"
  • Create admin user with the specified email
  • Bind permission to role, and user to role

Usage:

python -m fastapi_rbac init_data --email admin@example.com --password admin123 --app main:app

Arguments:

  • --email (required): Admin user email address
  • --password (required): Admin user password
  • --app (required): FastAPI app path in format module:var (e.g., main:app)

Examples:

# Using default app path
python -m fastapi_rbac init_data --email admin@example.com --password admin123 --app main:app

# Using different app module
python -m fastapi_rbac init_data --email admin@example.com --password admin123 --app app.core:application

2. Sync Permissions (sync_permission)

Extract permission codes from application routes and sync them to the database. This command will:

  • Load FastAPI application from the module specified by --app parameter
  • Extract permission codes from routes using require_permissions dependencies
  • Add missing permissions to database (incremental sync)
  • Leave existing permissions unchanged

Usage:

python -m fastapi_rbac sync_permission --app main:app

Arguments:

  • --app (required): FastAPI app path in format module:var (e.g., main:app)

Examples:

# Sync permissions to database
python -m fastapi_rbac sync_permission --app main:app

# Using different app module
python -m fastapi_rbac sync_permission --app app.core:application

Notes:

  • Ensure FastAPI application is constructed at module level (not only in main() function)
  • Ensure RBACPlugin(app, RBACConfig(...)) is instantiated during module import
  • Ensure RBACConfig.custom_session_maker is set (e.g., gen_rbac_async_session)

⚙️ Configuration

Environment Variables

# Database Configuration
DATABASE_URL=mysql+aiomysql://user:pass@localhost:3306/rbac_db

# RBAC Plugin Configuration
RBAC_TABLE_PREFIX=rbac_
RBAC_ENABLE_SOFT_DELETE=true
RBAC_CACHE_TTL=300
RBAC_DEFAULT_PAGE_SIZE=20
RBAC_MAX_PAGE_SIZE=100

# Security Configuration
RBAC_ENABLE_AUDIT_LOG=true
RBAC_SSO_ENABLED=true
RBAC_SSO_USER_SYNC=true

# Performance Configuration
RBAC_ENABLE_CACHE=false
RBAC_ENABLE_ROLE_HIERARCHY=false

Programmatic Configuration

from fastapi-rbac import RBACConfig

config = RBACConfig(
    # Database settings
    table_prefix="myapp_rbac_",
    enable_soft_delete=True,
    
    # Caching settings  
    cache_ttl=600,
    enable_cache=True,
    
    # Pagination settings
    default_page_size=25,
    max_page_size=200,
    
    # Security settings
    enable_audit_log=True,
    role_assignment_audit=True,
    
    # SSO integration
    sso_enabled=True,
    sso_user_sync=True,
    
    # System roles
    system_roles=["Super Admin", "Admin", "User"],
    default_user_role="User"
)

🔐 Authentication Integration

Custom Authentication

from fastapi import Request
from fastapi-rbac import RBACMiddleware

class CustomRBACMiddleware(RBACMiddleware):
    async def get_current_user_id(self, request: Request) -> Optional[int]:
        # JWT token example
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            try:
                payload = jwt.decode(token.split(" ")[1], SECRET_KEY, algorithms=["HS256"])
                return payload.get("user_id")
            except jwt.InvalidTokenError:
                return None
        return None

# Use custom middleware
app.state.rbac_middleware = CustomRBACMiddleware(rbac)

SSO Integration

@app.post("/api/auth/sso-sync")
async def sync_user_from_sso(
    sso_user_data: dict,
    db_session: AsyncSession = Depends(get_db)
):
    user_serializer = rbac.get_user_serializer(db_session)
    
    # Sync user from external SSO
    user = await user_serializer.create_or_update_user({
        "external_id": sso_user_data["id"],
        "name": sso_user_data["name"],
        "email": sso_user_data["email"]
    })
    
    return {"user_id": user.id, "synced": True}

🧪 Testing

Run Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=. --cov-report=html

# Run specific test files
uv run pytest tests/test_permission_dependencies.py -v

Test Data Setup

import pytest
from sqlmodel.ext.asyncio.session import AsyncSession
from fastapi-rbac import RBACPlugin

@pytest.fixture
async def setup_rbac_data(db_session: AsyncSession):
    rbac = RBACPlugin()
    
    # Create test user
    user_serializer = rbac.get_user_serializer(db_session)
    user = await user_serializer.create_user({
        "name": "Test User",
        "email": "test@example.com"
    })
    
    # Create test role with permissions
    role_serializer = rbac.get_role_serializer(db_session)
    role = await role_serializer.create_role({
        "name": "Test Role",
        "description": "Test role with permissions"
    })
    
    return {"user": user, "role": role}

🚀 Production Deployment

Docker Deployment

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt

COPY . .
EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=mysql+aiomysql://user:pass@db:3306/rbac_db
      - RBAC_ENABLE_CACHE=true
      - RBAC_CACHE_TTL=600
    depends_on:
      - db
      
  db:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=rbac_db
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  mysql_data:

Performance Tuning

# Production configuration example
config = RBACConfig(
    # Enable caching for better performance
    enable_cache=True,
    cache_ttl=900,  # 15 minutes
    
    # Optimize pagination
    default_page_size=50,
    max_page_size=500,
    
    # Database optimization
    pool_size=20,
    max_overflow=30,
    pool_timeout=30,
    
    # Security hardening
    enable_audit_log=True,
    role_assignment_audit=True
)

📖 Examples

Check the examples/ directory for comprehensive integration examples:

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/zxjlm/fastapi-rbac.git
cd fastapi-rbac

# Install development dependencies
uv install --dev

# Install pre-commit hooks
pre-commit install

# Run tests
uv run pytest

# Run linting
uv run ruff check .
uv run ruff format .

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Built with FastAPI and SQLModel
  • Inspired by enterprise RBAC best practices
  • Thanks to all contributors and the open-source community

TODO: How to get user_info?

base on request.

TODO: How to get permission in project?

init via script.

📞 Support

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

fastapi_rbac-0.1.1.tar.gz (237.7 kB view details)

Uploaded Source

Built Distribution

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

fastapi_rbac-0.1.1-py3-none-any.whl (166.7 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_rbac-0.1.1.tar.gz.

File metadata

  • Download URL: fastapi_rbac-0.1.1.tar.gz
  • Upload date:
  • Size: 237.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.5.11

File hashes

Hashes for fastapi_rbac-0.1.1.tar.gz
Algorithm Hash digest
SHA256 37f2ac96105d5327ebfd716aba190e20f680c9760a913c770fd580527b48fd97
MD5 81b81ff9bf65e2aecbbb3eed2650df0f
BLAKE2b-256 fc5c48bbacaf76f7c5f422ed97508795cf1dfa4239906e01635cb71541c73a37

See more details on using hashes here.

File details

Details for the file fastapi_rbac-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_rbac-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 31180b9d85cdb28b507e83d73aefbc03efee584bf842648268f58fcfee6d96d5
MD5 66bbf1254f6f9e995de878159daa4f0d
BLAKE2b-256 342813e98adda463b6cc22012b137f2a00c86147713cdc972170e8b8cdae4fd0

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