A FastAPI-based authentication microservice for user management with JWT authentication and role-based permissions.
This microservice provides:
- JWT Authentication - Login with RS256-signed tokens
- Account Management - User accounts with email/password
- Role-Based Access - Hierarchical role system
- Permission System - Granular permissions attached to roles
Account (1) βββ (1) Role (1) βββ (M) Permission
- Python 3.11+
- Docker & Docker Compose
# 1. Generate JWT keys (first time only)
python generate_keys.py
# 2. Copy .env.example to .env and add your generated keys
cp .env.example .env
# Edit .env and paste JWT_PRIVATE_KEY and JWT_PUBLIC_KEY
# 3. Start everything (database + app)
docker-compose up -d
# 4. Initialize database
docker exec -it svc-users-app python seed.pyThe service will be available at:
- API: http://localhost:8001
- Docs: http://localhost:8001/docs
# 1. Generate JWT keys (first time only)
python generate_keys.py
# 2. Setup environment
cp .env.example .env
# Edit .env and paste your generated keys
# 3. Install dependencies
pip install -r requirements.txt
# 4. Start PostgreSQL only
docker-compose up -d postgres
# 5. Initialize database
python seed.py
# 6. Run the application
uvicorn app.main:app --host 0.0.0.0 --port 8001 --reloadAfter running seed.py, you can use:
- Admin:
admin@example.com/admin123 - User:
user@example.com/user123
This service uses RS256 asymmetric encryption for JWT tokens. You must generate RSA key pairs before running the application.
python generate_keys.pyThis script generates:
- JWT_PRIVATE_KEY - Used to sign tokens (keep secret!)
- JWT_PUBLIC_KEY - Used to verify tokens (can be shared)
Copy the output and paste into your .env file. The keys are base64-encoded PEM format.
JWT_PRIVATE_KEY to version control!
Create a .env file with these variables:
# Database
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/svc_users
# Server
PORT=8001
HOST=0.0.0.0
ENVIRONMENT=development
# JWT Configuration
JWT_ALGORITHM=RS256
JWT_ISSUER=https://api.example.com
JWT_AUDIENCE=https://api.example.com
JWT_EXPIRATION_DAYS=7
JWT_KID=auth-2025-10-15
# RSA Keys (generate with: python generate_keys.py)
JWT_PRIVATE_KEY=<your-base64-encoded-private-key>
JWT_PUBLIC_KEY=<your-base64-encoded-public-key>Key Variables:
DATABASE_URL- PostgreSQL connection stringJWT_PRIVATE_KEY- Base64-encoded RSA private key for signing tokensJWT_PUBLIC_KEY- Base64-encoded RSA public key for verificationJWT_EXPIRATION_DAYS- Token lifetime (default: 7 days)
See .env.example for complete configuration.
POST /api/v1/auth/login- Login and receive JWT tokenGET /api/v1/auth/jwks- Get public keys for JWT verification
POST /api/v1/accounts- Create accountGET /api/v1/accounts- List accountsGET /api/v1/accounts/{id}- Get accountPATCH /api/v1/accounts/{id}- Update accountDELETE /api/v1/accounts/{id}- Delete account
POST /api/v1/roles- Create roleGET /api/v1/roles- List rolesGET /api/v1/roles/{id}- Get rolePATCH /api/v1/roles/{id}- Update roleDELETE /api/v1/roles/{id}- Delete rolePOST /api/v1/roles/{id}/permissions- Assign permissionsDELETE /api/v1/roles/{id}/permissions/{permission_id}- Remove permission
POST /api/v1/permissions- Create permissionGET /api/v1/permissions- List permissionsGET /api/v1/permissions/{id}- Get permissionPATCH /api/v1/permissions/{id}- Update permissionDELETE /api/v1/permissions/{id}- Delete permission
GET /api/v1/health- Service health status
Full API documentation: http://localhost:8001/docs
curl -X POST http://localhost:8001/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "admin@example.com",
"password": "admin123"
}'Response:
{
"status": "success",
"code": 200,
"message": "Token issued.",
"data": {
"tokenType": "Bearer",
"token": "eyJhbGciOiJSUzI1NiIs...",
"expiresAt": "2025-10-22T12:00:00Z"
}
}curl -X POST http://localhost:8001/api/v1/accounts \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"password": "securepass123",
"role_id": "your-role-uuid-here"
}'Reset database:
docker-compose down -v
docker-compose up -d
python seed.py # or: docker exec -it svc-users-app python seed.pyAccess PostgreSQL:
docker exec -it svc-users-db psql -U postgres -d svc_users# All services
docker-compose logs -f
# App only
docker-compose logs -f app
# Database only
docker-compose logs -f postgressvc-users-python/
βββ app/
β βββ main.py # FastAPI app entry point
β βββ config.py # Configuration management
β βββ database.py # Database connection
β βββ models/ # SQLAlchemy models
β βββ schemas/ # Pydantic schemas
β βββ routers/ # API route handlers
β β βββ v1/
β β βββ auth.py # Authentication endpoints
β β βββ accounts.py
β β βββ roles.py
β β βββ permissions.py
β βββ services/ # Business logic
β βββ utils/ # Utility functions
βββ generate_keys.py # RSA key generation script
βββ seed.py # Database seeding script
βββ docker-compose.yml # Docker services definition
βββ Dockerfile # App container image
βββ requirements.txt # Python dependencies
βββ .env # Environment variables (create from .env.example)
- Passwords: Hashed with bcrypt before storage
- JWT Tokens: Signed with RS256 (asymmetric encryption)
- Key Management: Private keys via environment variables
- Token Expiration: Configurable TTL (default: 7 days)
All endpoints return:
{
"status": "success | error",
"code": 200,
"message": "Human-readable message",
"data": {...} | [...] | null,
"errors": [...] | null,
"meta": {...} | null
}