30 KiB
Authentication System Documentation
Version: 1.0 Last Updated: November 2025 Audience: Development Team & API Consumers
Table of Contents
- System Overview
- Architecture
- Authentication Contexts
- Implementation Guide
- API Reference
- Security Model
- Testing Guidelines
- Troubleshooting
- Best Practices
System Overview
The Wizamart platform uses a context-based authentication system with three isolated security domains:
- Admin Portal - Platform administration and management
- Vendor Portal - Multi-tenant shop management
- Customer Shop - Public storefront and customer accounts
Each context uses dual authentication supporting both cookie-based (for HTML pages) and header-based (for API calls) authentication with complete isolation between contexts.
Key Features
- Cookie Path Isolation - Separate cookies per context prevent cross-context access
- Role-Based Access Control - Strict enforcement of user roles
- JWT Token Authentication - Stateless, secure token-based auth
- HTTP-Only Cookies - XSS protection for browser sessions
- CSRF Protection - SameSite cookie attribute
- Comprehensive Logging - Full audit trail of authentication events
Architecture
Authentication Flow
┌─────────────────────────────────────────────────────┐
│ Client Request │
└─────────────────┬───────────────────────────────────┘
│
┌───────▼────────┐
│ Route Handler │
└───────┬────────┘
│
┌───────▼────────────────────────────────┐
│ Authentication Dependency │
│ (from app/api/deps.py) │
└───────┬────────────────────────────────┘
│
┌─────────────┼─────────────┐
│ │ │
┌───▼───┐ ┌────▼────┐ ┌───▼────┐
│Cookie │ │ Header │ │ None │
└───┬───┘ └────┬────┘ └───┬────┘
│ │ │
└────────┬───┴────────────┘
│
┌──────▼───────┐
│ Validate JWT │
└──────┬───────┘
│
┌──────▼──────────┐
│ Check User Role │
└──────┬──────────┘
│
┌────────┴─────────┐
│ │
┌───▼────┐ ┌─────▼──────┐
│Success │ │ Auth Error │
│Return │ │ 401/403 │
│User │ └────────────┘
└────────┘
Cookie Isolation
Each authentication context uses a separate cookie with path restrictions:
| Context | Cookie Name | Cookie Path | Access Scope |
|---|---|---|---|
| Admin | admin_token |
/admin |
Admin routes only |
| Vendor | vendor_token |
/vendor |
Vendor routes only |
| Customer | customer_token |
/shop |
Shop routes only |
Browser Behavior:
- When requesting
/admin/*, browser sendsadmin_tokencookie only - When requesting
/vendor/*, browser sendsvendor_tokencookie only - When requesting
/shop/*, browser sendscustomer_tokencookie only
This prevents cookie leakage between contexts.
Authentication Contexts
1. Admin Context
Routes: /admin/*
Role: admin
Cookie: admin_token (path=/admin)
Purpose: Platform administration, vendor management, system configuration.
Access Control:
- ✅ Admin users only
- ❌ Vendor users blocked
- ❌ Customer users blocked
Login Endpoint:
POST /api/v1/admin/auth/login
Example Request:
curl -X POST http://localhost:8000/api/v1/admin/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
Example Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"is_active": true
}
}
Additionally, sets cookie:
Set-Cookie: admin_token=<JWT>; Path=/admin; HttpOnly; Secure; SameSite=Lax
2. Vendor Context
Routes: /vendor/*
Role: vendor
Cookie: vendor_token (path=/vendor)
Purpose: Vendor shop management, product catalog, orders, team management.
Access Control:
- ❌ Admin users blocked (admins use admin portal for vendor management)
- ✅ Vendor users (owners and team members)
- ❌ Customer users blocked
Login Endpoint:
POST /api/v1/vendor/auth/login
Example Request:
curl -X POST http://localhost:8000/api/v1/vendor/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"vendor_owner","password":"vendor123"}'
Example Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": 2,
"username": "vendor_owner",
"email": "owner@vendorshop.com",
"role": "vendor",
"is_active": true
},
"vendor": {
"id": 1,
"vendor_code": "ACME",
"name": "ACME Store"
},
"vendor_role": "owner"
}
Additionally, sets cookie:
Set-Cookie: vendor_token=<JWT>; Path=/vendor; HttpOnly; Secure; SameSite=Lax
3. Customer Context
Routes: /shop/account/* (authenticated), /shop/* (public)
Role: customer
Cookie: customer_token (path=/shop)
Purpose: Product browsing (public), customer accounts, orders, profile management.
Access Control:
- Public Routes (
/shop/products,/shop/cart, etc.):- ✅ Anyone can access (no authentication)
- Account Routes (
/shop/account/*):- ❌ Admin users blocked
- ❌ Vendor users blocked
- ✅ Customer users only
Login Endpoint:
POST /api/v1/public/vendors/{vendor_id}/customers/login
Example Request:
curl -X POST http://localhost:8000/api/v1/public/vendors/1/customers/login \
-H "Content-Type: application/json" \
-d '{"username":"customer","password":"customer123"}'
Example Response:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": 100,
"email": "customer@example.com",
"customer_number": "CUST-001",
"is_active": true
}
}
Additionally, sets cookie:
Set-Cookie: customer_token=<JWT>; Path=/shop; HttpOnly; Secure; SameSite=Lax
Implementation Guide
Module Structure
app/api/
├── deps.py # Authentication dependencies
├── v1/
├── admin/
│ └── auth.py # Admin authentication endpoints
├── vendor/
│ └── auth.py # Vendor authentication endpoints
└── public/vendors/
└── auth.py # Customer authentication endpoints
For HTML Pages (Server-Rendered)
Use the *_from_cookie_or_header functions for pages that users navigate to:
from fastapi import APIRouter, Request, Depends
from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from app.api.deps import (
get_current_admin_from_cookie_or_header,
get_current_vendor_from_cookie_or_header,
get_current_customer_from_cookie_or_header,
get_db
)
from models.database.user import User
router = APIRouter()
# Admin page
@router.get("/admin/dashboard", response_class=HTMLResponse)
async def admin_dashboard(
request: Request,
current_user: User = Depends(get_current_admin_from_cookie_or_header),
db: Session = Depends(get_db)
):
return templates.TemplateResponse("admin/dashboard.html", {
"request": request,
"user": current_user
})
# Vendor page
@router.get("/vendor/{vendor_code}/dashboard", response_class=HTMLResponse)
async def vendor_dashboard(
request: Request,
vendor_code: str,
current_user: User = Depends(get_current_vendor_from_cookie_or_header),
db: Session = Depends(get_db)
):
return templates.TemplateResponse("vendor/dashboard.html", {
"request": request,
"user": current_user,
"vendor_code": vendor_code
})
# Customer account page
@router.get("/shop/account/dashboard", response_class=HTMLResponse)
async def customer_dashboard(
request: Request,
current_user: User = Depends(get_current_customer_from_cookie_or_header),
db: Session = Depends(get_db)
):
return templates.TemplateResponse("shop/account/dashboard.html", {
"request": request,
"user": current_user
})
For API Endpoints (JSON Responses)
Use the *_api functions for API endpoints to enforce header-based authentication:
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session
from app.api.deps import (
get_current_admin_api,
get_current_vendor_api,
get_current_customer_api,
get_db
)
from models.database.user import User
router = APIRouter()
# Admin API
@router.post("/api/v1/admin/vendors")
def create_vendor(
vendor_data: VendorCreate,
current_user: User = Depends(get_current_admin_api),
db: Session = Depends(get_db)
):
# Only accepts Authorization header (no cookies)
# Better security - prevents CSRF attacks
return {"message": "Vendor created"}
# Vendor API
@router.post("/api/v1/vendor/{vendor_code}/products")
def create_product(
vendor_code: str,
product_data: ProductCreate,
current_user: User = Depends(get_current_vendor_api),
db: Session = Depends(get_db)
):
return {"message": "Product created"}
# Customer API
@router.post("/api/v1/shop/orders")
def create_order(
order_data: OrderCreate,
current_user: User = Depends(get_current_customer_api),
db: Session = Depends(get_db)
):
return {"message": "Order created"}
For Public Routes (No Authentication)
Simply don't use any authentication dependency:
@router.get("/shop/products")
async def public_products(request: Request):
# No authentication required
return templates.TemplateResponse("shop/products.html", {
"request": request
})
API Reference
Authentication Dependencies
All authentication functions are in app/api/deps.py:
get_current_admin_from_cookie_or_header()
Purpose: Authenticate admin users for HTML pages
Accepts: Cookie (admin_token) OR Authorization header
Returns: User object with role="admin"
Raises:
InvalidTokenException- No token or invalid tokenAdminRequiredException- User is not admin
Usage:
current_user: User = Depends(get_current_admin_from_cookie_or_header)
get_current_admin_api()
Purpose: Authenticate admin users for API endpoints
Accepts: Authorization header ONLY
Returns: User object with role="admin"
Raises:
InvalidTokenException- No token or invalid tokenAdminRequiredException- User is not admin
Usage:
current_user: User = Depends(get_current_admin_api)
get_current_vendor_from_cookie_or_header()
Purpose: Authenticate vendor users for HTML pages
Accepts: Cookie (vendor_token) OR Authorization header
Returns: User object with role="vendor"
Raises:
InvalidTokenException- No token or invalid tokenInsufficientPermissionsException- User is not vendor or is admin
Note: The InsufficientPermissionsException raised here is from app.exceptions.auth, which provides general authentication permission checking. This is distinct from InsufficientTeamPermissionsException used for team-specific permissions.
Usage:
current_user: User = Depends(get_current_vendor_from_cookie_or_header)
get_current_vendor_api()
Purpose: Authenticate vendor users for API endpoints
Accepts: Authorization header ONLY
Returns: User object with role="vendor"
Raises:
InvalidTokenException- No token or invalid tokenInsufficientPermissionsException- User is not vendor or is admin
Usage:
current_user: User = Depends(get_current_vendor_api)
get_current_customer_from_cookie_or_header()
Purpose: Authenticate customer users for HTML pages
Accepts: Cookie (customer_token) OR Authorization header
Returns: Customer object
Raises:
InvalidTokenException- No token or invalid tokenInsufficientPermissionsException- User is not customer (admin/vendor blocked)
Note: The InsufficientPermissionsException raised here is from app.exceptions.auth, which provides general authentication permission checking. This is distinct from InsufficientTeamPermissionsException used for team-specific permissions.
Usage:
current_customer: Customer = Depends(get_current_customer_from_cookie_or_header)
get_current_customer_api()
Purpose: Authenticate customer users for API endpoints
Accepts: Authorization header ONLY
Returns: Customer object
Raises:
InvalidTokenException- No token or invalid tokenInsufficientPermissionsException- User is not customer (admin/vendor blocked)
Usage:
current_customer: Customer = Depends(get_current_customer_api)
get_current_user()
Purpose: Authenticate any user (no role checking)
Accepts: Authorization header ONLY
Returns: User object (any role)
Raises:
InvalidTokenException- No token or invalid token
Usage:
current_user: User = Depends(get_current_user)
Login Response Format
All login endpoints return:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"token_type": "Bearer",
"expires_in": 3600,
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"is_active": true
}
}
Additionally, the response sets an HTTP-only cookie:
- Admin:
admin_token(path=/admin) - Vendor:
vendor_token(path=/vendor) - Customer:
customer_token(path=/shop)
Security Model
Role-Based Access Control Matrix
| User Role | Admin Portal | Vendor Portal | Shop Catalog | Customer Account |
|---|---|---|---|---|
| Admin | ✅ Full | ❌ Blocked | ✅ View | ❌ Blocked |
| Vendor | ❌ Blocked | ✅ Full | ✅ View | ❌ Blocked |
| Customer | ❌ Blocked | ❌ Blocked | ✅ View | ✅ Full |
| Anonymous | ❌ Blocked | ❌ Blocked | ✅ View | ❌ Blocked |
Cookie Security Settings
All authentication cookies use the following security attributes:
response.set_cookie(
key="<context>_token",
value=jwt_token,
httponly=True, # JavaScript cannot access (XSS protection)
secure=True, # HTTPS only in production
samesite="lax", # CSRF protection
max_age=3600, # Matches JWT expiry
path="/<context>" # Path restriction for isolation
)
Token Validation
JWT tokens include:
sub- User IDrole- User role (admin/vendor/customer)exp- Expiration timestampiat- Issued at timestamp
Tokens are validated on every request:
- Extract token from cookie or header
- Verify JWT signature
- Check expiration
- Load user from database
- Verify user is active
- Check role matches route requirements
Token Validation Edge Cases
The token verification process includes comprehensive validation of token claims:
Required Claims Validation:
- Missing
sub(User ID): RaisesInvalidTokenException("Token missing user identifier") - Missing
exp(Expiration): RaisesInvalidTokenException("Token missing expiration") - Expired Token: Raises
TokenExpiredException()
Signature Verification:
- Invalid Signature: Raises
InvalidTokenException("Could not validate credentials") - Wrong Algorithm: Raises
InvalidTokenException() - Malformed Token: Raises
InvalidTokenException()
Exception Handling Pattern: Custom exceptions (such as those raised for missing claims) are preserved with their specific error messages, allowing for detailed error reporting to clients. This follows the exception handling pattern documented in the Exception Handling Guide.
Example Error Responses:
{
"error_code": "INVALID_TOKEN",
"message": "Token missing user identifier",
"status_code": 401
}
{
"error_code": "TOKEN_EXPIRED",
"message": "Token has expired",
"status_code": 401
}
HTTPS Requirement
Production Environment:
- All cookies have
secure=True - HTTPS required for all authenticated routes
- HTTP requests automatically redirect to HTTPS
Development Environment:
- Cookies have
secure=Falsefor local testing - HTTP allowed (http://localhost:8000)
Testing Guidelines
Manual Testing with Browser
Test Admin Authentication
-
Navigate to admin login:
http://localhost:8000/admin/login -
Login with admin credentials:
- Username:
admin - Password:
admin123(or your configured admin password)
- Username:
-
Verify cookie in DevTools:
- Open DevTools → Application → Cookies
- Look for
admin_tokencookie - Verify
Pathis/admin - Verify
HttpOnlyis checked - Verify
SameSiteisLax
-
Test navigation:
- Navigate to
/admin/dashboard- Should work ✅ - Navigate to
/vendor/TESTVENDOR/dashboard- Should fail (cookie not sent) ❌ - Navigate to
/shop/account/dashboard- Should fail (cookie not sent) ❌
- Navigate to
-
Logout:
POST /api/v1/admin/auth/logout
Test Vendor Authentication
-
Navigate to vendor login:
http://localhost:8000/vendor/{VENDOR_CODE}/login -
Login with vendor credentials
-
Verify cookie in DevTools:
- Look for
vendor_tokencookie - Verify
Pathis/vendor
- Look for
-
Test navigation:
- Navigate to
/vendor/{VENDOR_CODE}/dashboard- Should work ✅ - Navigate to
/admin/dashboard- Should fail ❌ - Navigate to
/shop/account/dashboard- Should fail ❌
- Navigate to
Test Customer Authentication
-
Navigate to customer login:
http://localhost:8000/shop/account/login -
Login with customer credentials
-
Verify cookie in DevTools:
- Look for
customer_tokencookie - Verify
Pathis/shop
- Look for
-
Test navigation:
- Navigate to
/shop/account/dashboard- Should work ✅ - Navigate to
/admin/dashboard- Should fail ❌ - Navigate to
/vendor/{CODE}/dashboard- Should fail ❌
- Navigate to
API Testing with curl
Test Admin API
# Login
curl -X POST http://localhost:8000/api/v1/admin/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# Save the access_token from response
# Test authenticated endpoint
curl http://localhost:8000/api/v1/admin/vendors \
-H "Authorization: Bearer <access_token>"
# Test cross-context blocking
curl http://localhost:8000/api/v1/vendor/TESTVENDOR/products \
-H "Authorization: Bearer <admin_access_token>"
# Should return 403 Forbidden
Test Vendor API
# Login
curl -X POST http://localhost:8000/api/v1/vendor/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"vendor","password":"vendor123"}'
# Test authenticated endpoint
curl http://localhost:8000/api/v1/vendor/TESTVENDOR/products \
-H "Authorization: Bearer <vendor_access_token>"
# Test cross-context blocking
curl http://localhost:8000/api/v1/admin/vendors \
-H "Authorization: Bearer <vendor_access_token>"
# Should return 403 Forbidden
Test Customer API
# Login
curl -X POST http://localhost:8000/api/v1/public/vendors/1/customers/login \
-H "Content-Type: application/json" \
-d '{"username":"customer","password":"customer123"}'
# Test authenticated endpoint with token
curl http://localhost:8000/api/v1/shop/orders \
-H "Authorization: Bearer <customer_access_token>"
# Test cross-context blocking
curl http://localhost:8000/api/v1/admin/vendors \
-H "Authorization: Bearer <customer_access_token>"
# Should return 403 Forbidden
Frontend JavaScript Testing
Login and Store Token
// Admin login
async function loginAdmin(username, password) {
const response = await fetch('/api/v1/admin/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const data = await response.json();
// Cookie is set automatically
// Optionally store token for API calls
localStorage.setItem('admin_token', data.access_token);
// Redirect to dashboard
window.location.href = '/admin/dashboard';
}
Make API Call with Token
// API call with token
async function fetchVendors() {
const token = localStorage.getItem('admin_token');
const response = await fetch('/api/v1/admin/vendors', {
headers: {
'Authorization': `Bearer ${token}`
}
});
return response.json();
}
Page Navigation (Cookie Automatic)
// Just navigate - cookie sent automatically
window.location.href = '/admin/dashboard';
// Browser automatically includes admin_token cookie
Automated Testing
Test Cookie Isolation
import pytest
from fastapi.testclient import TestClient
def test_admin_cookie_not_sent_to_vendor_routes(client: TestClient):
# Login as admin
response = client.post('/api/v1/admin/auth/login', json={
'username': 'admin',
'password': 'admin123'
})
# Try to access vendor route (cookie should not be sent)
response = client.get('/vendor/TESTVENDOR/dashboard')
# Should redirect to login or return 401
assert response.status_code in [302, 401]
def test_vendor_token_blocked_from_admin_api(client: TestClient):
# Login as vendor
response = client.post('/api/v1/vendor/auth/login', json={
'username': 'vendor',
'password': 'vendor123'
})
vendor_token = response.json()['access_token']
# Try to access admin API with vendor token
response = client.get(
'/api/v1/admin/vendors',
headers={'Authorization': f'Bearer {vendor_token}'}
)
# Should return 403 Forbidden
assert response.status_code == 403
Troubleshooting
Common Issues
"Invalid token" error when navigating to pages
Symptom: User is logged in but gets "Invalid token" error
Causes:
- Token expired (default: 1 hour)
- Cookie was deleted
- Wrong cookie being sent
Solution:
- Check cookie expiration in DevTools
- Re-login to get fresh token
- Verify correct cookie exists with correct path
Cookie not being sent to endpoints
Symptom: API calls work with Authorization header but pages don't load
Causes:
- Cookie path mismatch
- Cookie expired
- Wrong domain
Solution:
- Verify cookie path matches route (e.g.,
/admincookie for/admin/*routes) - Check cookie expiration
- Ensure cookie domain matches current domain
"Admin cannot access vendor portal" error
Symptom: Admin user cannot access vendor routes
Explanation: This is intentional security design. Admins have their own portal at /admin. To manage vendors, use admin routes:
- View vendors:
/admin/vendors - Edit vendor:
/admin/vendors/{code}/edit
Admins should not log into vendor portal as this violates security boundaries.
"Customer cannot access admin/vendor routes" error
Symptom: Customer trying to access management interfaces
Explanation: Customers only have access to:
- Public shop routes:
/shop/products, etc. - Their account:
/shop/account/*
Admin and vendor portals are not accessible to customers.
Token works in Postman but not in browser
Cause: Postman uses Authorization header, browser uses cookies
Solution:
- For API testing: Use Authorization header
- For browser testing: Rely on cookies (automatic)
- For JavaScript API calls: Add Authorization header manually
Debugging Tips
Check Cookie in Browser
// In browser console
document.cookie.split(';').forEach(c => console.log(c.trim()));
Decode JWT Token
// In browser console
function parseJwt(token) {
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const jsonPayload = decodeURIComponent(atob(base64).split('').map(c => {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
}
const token = localStorage.getItem('admin_token');
console.log(parseJwt(token));
Check Server Logs
The authentication system logs all auth events:
INFO: Admin login successful: admin
INFO: Request: GET /admin/dashboard from 127.0.0.1
INFO: Response: 200 for GET /admin/dashboard (0.045s)
Look for:
- Login attempts
- Token validation errors
- Permission denials
Best Practices
For Developers
-
Use the right dependency for the job:
- HTML pages →
get_current_<context>_from_cookie_or_header - API endpoints →
get_current_<context>_api
- HTML pages →
-
Don't mix authentication contexts:
- Admin users should use admin portal
- Vendor users should use vendor portal
- Customers should use shop
-
Always check user.is_active:
if not current_user.is_active: raise UserNotActiveException() -
Use type hints:
def my_route(current_user: User = Depends(get_current_admin_api)): # IDE will have autocomplete for current_user -
Handle exceptions properly:
try: # Your logic except InvalidTokenException: # Handle auth failure except InsufficientPermissionsException: # Handle permission denial
For Frontend
-
Store tokens securely:
- Tokens in localStorage/sessionStorage are vulnerable to XSS
- Prefer using cookies for page navigation
- Only use localStorage for explicit API calls
-
Always send Authorization header for API calls:
const token = localStorage.getItem('token'); fetch('/api/v1/admin/vendors', { headers: { 'Authorization': `Bearer ${token}` } }); -
Handle 401/403 responses:
if (response.status === 401) { // Redirect to login window.location.href = '/admin/login'; } -
Clear tokens on logout:
localStorage.removeItem('token'); // Logout endpoint will clear cookie await fetch('/api/v1/admin/auth/logout', { method: 'POST' });
Security Considerations
- Never log tokens - They're sensitive credentials
- Use HTTPS in production - Required for secure cookies
- Set appropriate token expiration - Balance security vs UX
- Rotate secrets regularly - JWT signing keys
- Monitor failed auth attempts - Detect brute force attacks
Configuration
Environment Variables
# JWT Configuration
JWT_SECRET_KEY=your-secret-key-here
JWT_ALGORITHM=HS256
JWT_EXPIRATION=3600 # 1 hour in seconds
# Environment
ENVIRONMENT=production # or development
# When ENVIRONMENT=production:
# - Cookies use secure=True (HTTPS only)
# - Debug mode is disabled
# - CORS is stricter
Cookie Expiration
Cookies expire when:
- JWT token expires (default: 1 hour)
- User logs out (cookie deleted)
- Browser session ends (for session cookies)
To change expiration:
# In auth endpoint
response.set_cookie(
max_age=7200 # 2 hours
)
AuthManager Class Reference
The AuthManager class handles all authentication and authorization operations including password hashing, JWT token management, and role-based access control.
::: middleware.auth.AuthManager options: show_source: false heading_level: 3 show_root_heading: true show_root_toc_entry: false members: - init - hash_password - verify_password - authenticate_user - create_access_token - verify_token - get_current_user - require_role - require_admin - require_vendor - require_customer - create_default_admin_user
Quick Reference
For a condensed cheat sheet of authentication patterns, see Authentication Quick Reference.
Related Documentation
- RBAC System - Role-based access control and permissions
- Architecture Overview - System-wide authentication architecture
- Backend Development - Backend development guide
- API Reference - Auto-generated API documentation
Document Version: 1.0 Last Updated: November 2025 Maintained By: Backend Team