Production-style multi-tenant SaaS backend built with:
- FastAPI
- Async SQLAlchemy (2.0 style)
- JWT Authentication (Access + Refresh with rotation)
- Role-Based Access Control (RBAC)
- Clean Architecture (API β Service β Repository β DB)
- Dockerized & published to GHCR
API Layer β FastAPI Routers
Service Layer β Business Logic & Permissions
Repository Layer β Database Queries
Database β Async SQLAlchemy ORM
Project structure:
app/ βββ api/
βββ core/
βββ db/
βββ models/
βββ repositories/
βββ schemas/
βββ services/
βββ main.py
.env
- JWT Access Token
- Refresh Token with rotation
- Token revocation support
- Secure password hashing (bcrypt)
- Role-based permissions
Roles:
owner β Full control
admin β Manage projects & members
member β Limited access
- FastAPI
- Async SQLAlchemy
- SQLite (default)
- PostgreSQL (supported)
- python-jose (JWT)
- Passlib (bcrypt)
- Pytest (async testing)
- Docker
By default:
- Database: sqlite+aiosqlite
- Secret Key: auto-generated if not provided
- Access token expiry: 30 minutes
- Refresh token expiry: 7 days
Prebuilt image:
ghcr.io/yovsefx/taskteam_saas:latest
Run with default configuration:
docker run -p 8000:8000 ghcr.io/yovsefx/taskteam_saas:latestRun with custom environment variables (PostgreSQL example):
docker run -p 8000:8000 \\
-e DATABASE_URL="postgresql+asyncpg://user:password@host:5432/dbname" \\
-e SECRET_KEY="your-secret-key" \\
-e ACCESS_TOKEN_EXPIRE_MINUTES=30 \\
-e REFRESH_TOKEN_EXPIRE_DAYS=14 \\
ghcr.io/yovsefx/taskteam_saas:latestuvicorn app.main:app --reloadAPI Docs: http://127.0.0.1:8000/docs