Centralized Single Sign-On (SSO) authentication and authorization service for ZipTrigo web applications.
The User service provides:
- Single Sign-On (SSO) across multiple first-party web apps
- Centralized identity, roles, and permissions management
- JWT-based authentication for users
- Client ID/Secret authentication for services
- RESTful API under
/api
- Backend: Django 6.0, Python 3.13, Django Ninja
- Frontend: HTMX (minimal landing page)
- Database: SQLite (development) / PostgreSQL (production)
- Create and activate virtual environment:
python -m venv .venv
.venv\Scripts\activate # Windows
# or
source .venv/bin/activate # Linux/Mac- Install dependencies:
pip install -r requirements.txt- Run migrations:
python manage.py migrate- Create superuser:
python manage.py createsuperuser --email admin@example.com- Start development server:
python manage.py runserver/api/docs- Interactive Swagger UI documentation (supports Authorize with Bearer tokens)/api/openapi.json- OpenAPI 3 schema in JSON format
- Auth method: JWT via
Authorization: Bearer <token>. - Service-to-service auth:
X-Client-IdandX-Client-Secretheaders (for endpoints that useServiceAuthentication).
Login (open endpoint)
POST /api/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "password123"
}
Response 200:
{
"access_token": "eyJ...",
"expires_in": 1209600,
"token_type": "Bearer"
}
Create a service to obtain client_id and client_secret the first time.
POST /api/services- Create a new serviceGET /api/services- List all servicesGET /api/services/{id}- Get service detailsPATCH /api/services/{id}- Update service
POST /api/services/{service_id}/permissions- Create permission for serviceGET /api/services/{service_id}/permissions- List service permissionsPOST /api/services/{service_id}/roles- Create role for serviceGET /api/services/{service_id}/roles- List service roles
POST /api/services/{service_id}/users- Create/assign user to serviceGET /api/users/{user_id}- Get user detailsPATCH /api/users/{user_id}- Update userDELETE /api/users/{user_id}- Soft delete userPOST /api/users/{user_id}/deactivate- Deactivate userPOST /api/users/{user_id}/reactivate- Reactivate userGET /api/users/{user_id}/services- List user's service assignmentsPATCH /api/users/{user_id}/services/{service_id}- Update user roles/permissionsDELETE /api/users/{user_id}/services/{service_id}- Remove service assignment
Include JWT token in Authorization header:
Authorization: Bearer <token>
Include client credentials in headers:
X-Client-Id: <client_id>
X-Client-Secret: <client_secret>
{
"sub": "user-uuid",
"email": "user@example.com",
"iat": 1234567890,
"exp": 1234567890,
"global_permissions": ["admin", "manage_users"],
"global_roles": ["super_admin"],
"services": {
"service-uuid": {
"permissions": ["read", "write"],
"roles": ["editor"]
}
}
}Key settings live in config/settings.py.
- Custom user model:
src.user.models.user.User(set viaAUTH_USER_MODEL). - DRF defaults:
IsAuthenticated; admin endpoints layerIsAdminUser. - JWT:
JWT_SECRET(set via environment in production)JWT_ALGORITHM(default: HS256)JWT_EXP_DELTA_SECONDS(default: 2 weeks)
Default superuser credentials for local testing (if you created as shown above):
- Email:
admin@example.com - Password:
admin123
Quick manual test sequence:
- Create a service (admin-only):
POST /api/services— returns generatedclient_idandclient_secret. - Create or assign a user to that service:
POST /api/services/{service_id}/users. - Login as that user:
POST /api/auth/login— receive JWT. - Call protected endpoints with
Authorization: Bearer <token>.
Django admin: http://127.0.0.1:8020/admin/
config/ # Django project config (settings, urls, wsgi/asgi)
src/
user/ # Django app (installed as `src.user`)
models/ # Django models package (one model per file)
__init__.py # Re-exports models for `from src.user.models import ...`
service.py
permission.py
role.py
role_permission.py
user.py
user_service_assignment.py
user_service_role.py
user_service_permission.py
user_global_role.py
user_global_permission.py
schemas/ # Pydantic v2 schemas split by domain
__init__.py
auth.py
services.py
users.py
roles_permissions.py
routers/ # Django Ninja routers split by domain
__init__.py
auth.py
services.py
users.py
roles_permissions.py
admin.py # Django admin registrations
api.py # Main NinjaAPI instance
auth.py # Django Ninja authentication classes
backends.py # Django authentication backend(s)
jwt.py # JWT build/verify helpers
templates/ # Minimal UI templates
static/ # Static assets (if used)
manage.py
pyproject.toml
README.md
WARP.md
See LICENSE file for details.