FastAPI RBAC (Role-Based Access Control) plugin with comprehensive user and permission management
Project description
Siduri - Advanced RBAC FastAPI Extension
A powerful, production-ready Role-Based Access Control (RBAC) extension for FastAPI applications. Siduri 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: MySQL, PostgreSQL, SQLite support
- Docker Ready: Container-friendly configuration
- Production Features: Health checks, monitoring endpoints, CORS support
📋 Requirements
- Python: 3.11+
- Database: MySQL 5.7+ / PostgreSQL 12+ / SQLite 3.31+
- Dependencies: FastAPI, SQLModel, Pydantic v2, aiomysql/asyncpg
🛠 Installation
Using pip (Recommended)
pip install siduri-rbac
Development Installation
git clone https://github.com/yourorg/siduri.git
cd siduri
pip install -e ".[dev]"
Using uv (Modern Python Package Manager)
uv add siduri-rbac
🚀 Quick Start
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 siduri import RBACPlugin, RBACConfig
# Create FastAPI app
app = FastAPI(title="My App with RBAC")
# Database setup
engine = create_async_engine("mysql+aiomysql://user:pass@localhost:3306/mydb")
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 siduri 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"}
📚 API Endpoints
Once integrated, Siduri provides the following REST API endpoints:
User Management
GET /api/rbac/users # List users with pagination
POST /api/rbac/users # Create new user
GET /api/rbac/users/{user_id} # Get user details
PUT /api/rbac/users/{user_id} # Update user
DELETE /api/rbac/users/{user_id} # Delete user (soft delete)
GET /api/rbac/users/search # Search users
POST /api/rbac/users/{user_id}/roles # Assign roles to user
DELETE /api/rbac/users/{user_id}/roles/{role_id} # Remove role from user
Role Management
GET /api/rbac/roles # List roles
POST /api/rbac/roles # Create role
GET /api/rbac/roles/{role_id} # Get role details
PUT /api/rbac/roles/{role_id} # Update role
DELETE /api/rbac/roles/{role_id} # Delete role
POST /api/rbac/roles/{role_id}/users # Assign users to role
POST /api/rbac/roles/{role_id}/permissions # Assign permissions to role
Permission Management
GET /api/rbac/permissions # List permissions
POST /api/rbac/permissions # Create permission
GET /api/rbac/permissions/{permission_id} # Get permission details
PUT /api/rbac/permissions/{permission_id} # Update permission
DELETE /api/rbac/permissions/{permission_id} # Delete permission
POST /api/rbac/permissions/{permission_id}/roles # Assign roles to permission
⚙️ 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 siduri 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 siduri 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 siduri 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:
- basic_usage.py: Simple integration for prototyping
- advanced_integration.py: Production-ready setup with middleware
- permission_dependency_example.py: Permission-based access control
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
# Clone the repository
git clone https://github.com/yourorg/siduri.git
cd siduri
# 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
- Documentation: https://siduri-rbac.readthedocs.io
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: support@siduri-rbac.com
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_rbac-0.1.0.tar.gz.
File metadata
- Download URL: fastapi_rbac-0.1.0.tar.gz
- Upload date:
- Size: 235.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c67bd8880e4697440541f4d7c005730e4d7c41ed2d2b540080953d61a894a39e
|
|
| MD5 |
a4763a90e4f50d1a3eb2c09270455bb4
|
|
| BLAKE2b-256 |
e268a5a4e2d810ac6780e5303c62eca21450d53d7ded13e6ffa1d70cf38f02fe
|
File details
Details for the file fastapi_rbac-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fastapi_rbac-0.1.0-py3-none-any.whl
- Upload date:
- Size: 165.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.5.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a09377f341ae1b9629067cc447d7366d07b78f729e82db39b2e00df80b248d0
|
|
| MD5 |
a7eb2519a93a8ea7db6ce4806e057762
|
|
| BLAKE2b-256 |
e676537d49cacab08e60cd034ce3d08842ebbd31ef821d25cbc7124c8b84d1e7
|