Auth & Security
info
Fluvius Framework provides built-in support for authentication and authorization using Casbin.
Authentication
Basic Authentication
Authenticate users:
from fluvius.fastapi.authentication import AuthMiddleware
app = FluviusFastAPI()
app.add_middleware(AuthMiddleware)
JWT Authentication
Use JWT tokens:
from fluvius.fastapi.authentication import JWTAuth
auth = JWTAuth(secret_key="your-secret-key")
@app.post("/login")
async def login(username: str, password: str):
# Validate credentials
user = await validate_user(username, password)
token = auth.create_token(user.id)
return {"token": token}
API Key Authentication
Use API keys:
from fluvius.fastapi.authentication import APIKeyAuth
auth = APIKeyAuth()
@app.post("/api/endpoint")
@auth.required
async def protected_endpoint():
# Requires API key
pass
Authorization with Casbin
Casbin Integration
Fluvius integrates with Casbin for policy-based access control:
from fluvius.casbin import CasbinEnforcer
enforcer = CasbinEnforcer(
model_path="path/to/model.conf",
policy_path="path/to/policy.csv"
)
Policy Model
Define policy model:
# model.conf
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow))
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
Policy Rules
Define policy rules:
# policy.csv
p, admin, user, create
p, admin, user, read
p, admin, user, update
p, admin, user, delete
p, user, user, read
p, user, user, update
Enforcing Policies
Enforce policies in aggregates:
from fluvius.domain import Aggregate, action
from fluvius.casbin import require_permission
class UserAggregate(Aggregate):
@action(evt_key='user-created', resources=['user'])
@require_permission('user', 'create')
async def create_user(self, name: str, email: str):
# Only users with 'user:create' permission can call this
pass
Resource-Based Authorization
Resource Authorization
Authorize based on resources:
@action(evt_key='user-updated', resources=['user'])
@require_permission('user', 'update')
async def update_user(self, name: str):
# Requires 'user:update' permission
pass
Resource Ownership
Check resource ownership:
@action(evt_key='user-updated', resources=['user'])
@require_permission('user', 'update')
async def update_user(self, name: str):
# Check if user owns the resource
if not self.domain.context.user_id == self._state.owner_id:
raise PermissionError("Not authorized")
pass
Role-Based Access Control (RBAC)
Roles
Define roles:
# Assign roles
enforcer.add_grouping_policy("alice", "admin")
enforcer.add_grouping_policy("bob", "user")
Role Permissions
Define role permissions:
# Admin can do everything
enforcer.add_policy("admin", "user", "create")
enforcer.add_policy("admin", "user", "read")
enforcer.add_policy("admin", "user", "update")
enforcer.add_policy("admin", "user", "delete")
# User can only read and update
enforcer.add_policy("user", "user", "read")
enforcer.add_policy("user", "user", "update")
Attribute-Based Access Control (ABAC)
Attributes
Use attributes for authorization:
# Check attributes
enforcer.add_policy("admin", "user", "create", "department == 'IT'")
Dynamic Policies
Create dynamic policies:
# Policy based on resource attributes
if resource.department == user.department:
enforcer.add_policy(user.id, resource.type, "read")
Security Best Practices
1. Validate Input
Always validate input:
from pydantic import BaseModel, EmailStr
class CreateUserRequest(BaseModel):
name: str
email: EmailStr # Validated email
@action(evt_key='user-created')
async def create_user(self, name: str, email: str):
# Input is validated by Pydantic
pass
2. Use HTTPS
Always use HTTPS in production:
# Use HTTPS
app = FluviusFastAPI()
# Configure SSL certificates
3. Secure Secrets
Store secrets securely:
import os
# Use environment variables
secret_key = os.getenv("SECRET_KEY")
# Never commit secrets
# Use .env file (gitignored)
4. Rate Limiting
Implement rate limiting:
from slowapi import Limiter
limiter = Limiter(key_func=get_remote_address)
@app.post("/api/users")
@limiter.limit("10/minute")
async def create_user():
pass
5. Input Sanitization
Sanitize user input:
import html
@action(evt_key='user-created')
async def create_user(self, name: str, email: str):
# Sanitize input
name = html.escape(name)
email = html.escape(email)
pass
Security Headers
CORS Configuration
Configure CORS:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_credentials=True,
allow_methods=["GET", "POST"],
allow_headers=["*"],
)
Security Headers
Add security headers:
@app.middleware("http")
async def add_security_headers(request, call_next):
response = await call_next(request)
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-XSS-Protection"] = "1; mode=block"
return response
Audit Logging
Audit Events
Log security events:
@action(evt_key='user-created')
async def create_user(self, name: str, email: str):
# Event is automatically logged
# Include audit information
logger.info(f"User created by {self.domain.context.user_id}")
pass
Access Logging
Log access attempts:
@middleware
async def access_logging_middleware(request, call_next):
logger.info(f"Access: {request.method} {request.url} by {request.user}")
response = await call_next(request)
return response
Next Steps
- Learn about Security
- Explore Input Validation
- Check Usage Guide