Production-ready authentication system with API Gateway pattern, microservices architecture, and centralized security.
This is a complete authentication and authorization system with:
- ✅ Microservices architecture (5 services)
- ✅ API Gateway pattern (single entry point)
- ✅ JWT-based authentication (two-layer security)
- ✅ Rate limiting (100 req/60sec per IP)
- ✅ Centralized logging
- ✅ Docker containerization
- ✅ Complete Postman testing collection (27 requests)
- ✅ Password reset feature
- ✅ Production-ready code
Perfect for: Building scalable authentication systems, learning microservices architecture, or as a template for new projects.
-
Start all services:
cd am docker-compose up -d --build -
Verify services are running:
docker-compose ps curl http://localhost:8000/health # API Gateway -
Test the system:
- Follow Quick Start Guide (5 min read)
- Use Postman Collection (27 requests)
- Run automated tests:
bash am/test_all.sh
auth-test/
├── am/ # Microservices
│ ├── am-api-gateway/ # API Gateway (Port 8000) ✅ PUBLIC
│ ├── am-user-management/ # User Service (Port 8010) ✅ PUBLIC
│ ├── am-auth-tokens/ # Auth Service (Port 8001) ✅ PUBLIC
│ ├── am-python-internal-service/ # Internal (Port 8002) ⛔ NO EXTERNAL ACCESS
│ ├── am-java-internal-service/ # Internal (Port 8003) ⛔ NO EXTERNAL ACCESS
│ ├── docker-compose.yml # Service orchestration
│ └── test_all.sh # Run all tests (automated)
├── docs/
│ ├── ARCHITECTURE.md # System design
│ ├── QUICK_START.md # 5-minute setup
│ ├── SECURITY.md # Security patterns
│ └── TESTING.md # Complete testing guide
├── postman/ # API Testing
│ ├── AM-Complete-API-Collection.json # 27 requests, all endpoints
│ ├── QUICK_REFERENCE.md # 30-second quick card
│ ├── POSTMAN_COMPLETE_GUIDE.md # Full Postman guide
│ └── README.md # Postman overview
├── shared/ # Shared utilities
│ ├── auth/ # JWT utilities
│ └── logging/ # Centralized logging
├── DOCUMENTATION.md # Master documentation index
├── FEATURE_PASSWORD_RESET.md # Password reset feature guide
└── README.md # This file
┌─────────────────────────────────────────────────────────┐
│ EXTERNAL CLIENTS │
│ (Postman, Web Browser, Mobile App, etc) │
└──────────────────────────┬──────────────────────────────┘
│ http://localhost:8000
↓
┌─────────────────────────────────────────────────────────┐
│ API GATEWAY (Port 8000) │
│ • Routes requests to correct service │
│ • Validates JWT tokens │
│ • Generates service tokens │
│ • Rate limiting (100 req/60s per IP) │
│ • Audit logging │
└──────────────────┬──────────────────┬──────────────────┘
│ │
┌──────────────┴──────┐ ┌──────┴──────────────┐
↓ ↓ ↓ ↓
USER MANAGEMENT AUTH TOKENS PROTECTED ENDPOINTS
(Port 8010) (Port 8001) (Python & Java Internal)
• Register • Login • Documents (8002)
• Activate • Validate Token • Reports (8003)
• Get Profile • Refresh Token • Portfolio
↓ Service Token (JWT) ↓
┌─────────────────────────────────────────────────────────┐
│ INTERNAL DOCKER NETWORK │
│ (No external port access - completely isolated) │
└─────────────────────────────────────────────────────────┘
Key Features:
- ✅ Single Entry Point: All external requests go through API Gateway (8000)
- ✅ Network Isolation: Internal services have no external ports
- ✅ Two-Layer Security: Network layer + JWT authentication
- ✅ Rate Limiting: 100 requests/60 seconds per IP
- ✅ Centralized Logging: All requests tracked with context
- ✅ Service Mesh: Internal services communicate via service tokens
| Service | Port | Access | Purpose |
|---|---|---|---|
| API Gateway | 8000 | ✅ Public | Single entry point, routing, auth |
| User Management | 8010 | ✅ Public | Registration, profiles, RBAC |
| Auth Tokens | 8001 | ✅ Public | JWT tokens, validation |
| Python Service | 8002 | Document processing | |
| Java Service | 8003 | Report generation | |
| PR Agent | N/A | 🤖 AI | Automated PR Review (Gemini 1.5 Flash) |
This repository is automatically reviewed by the Global AI PR Agent (powered by Google Gemini 1.5 Flash).
- Auto-Enabled: No local configuration is required. This feature is managed centrally via the organization's
.githubrepository andam-pipelines. - Automatic Reviews: Every time a PR is opened, the agent will automatically provide a description and a code review.
- Manual Commands: You can trigger the agent manually by commenting on a PR:
/review: Request a comprehensive code review./describe: Update the PR description and add a summary./improve: Suggest code improvements./ask <question>: Ask the agent a specific question about the PR.
GET /health → Service health check (all services)
GET /api/v1/info → System information
POST /api/v1/auth/register → Create new user account
GET /api/v1/users/{id}/status → Get user status & details
PATCH /api/v1/users/{id}/status → Update user status (activate/deactivate)
POST /api/v1/auth/login → Login with email/password → Returns JWT token
POST /api/v1/tokens → Create JWT token (username/password)
POST /api/v1/validate → Validate token (send token in body)
POST /api/v1/validate/bearer → Validate token (bearer format alternative)
GET /api/v1/validate/me?token=... → Validate token (query parameter)
POST /api/v1/request-reset → Request password reset token (24h expiry)
POST /api/v1/validate-reset-token → Verify reset token validity
POST /api/v1/confirm-reset → Complete password reset with new password
GET /api/v1/documents → Get user's documents
GET /api/v1/reports → Get user's reports
GET /api/v1/portfolio → Get user's portfolio
- ✅ All external clients use http://localhost:8000
- ✅ API Gateway routes to internal services
- ✅ JWT tokens validated at gateway
- ✅ Service tokens generated automatically
curl -X POST http://localhost:8010/api/v1/users/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "SecurePass123!",
"full_name": "John Doe"
}'
# Response (201 Created):
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"full_name": "John Doe",
"status": "inactive",
"created_at": "2025-11-18T10:30:00Z"
}curl -X PATCH http://localhost:8010/api/v1/users/550e8400-e29b-41d4-a716-446655440000/status \
-H "Content-Type: application/json" \
-d '{"status": "active"}'
# Response (200 OK):
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "active",
"updated_at": "2025-11-18T10:31:00Z"
}curl -X POST http://localhost:8001/api/v1/tokens \
-H "Content-Type: application/json" \
-d '{
"username": "user@example.com",
"password": "SecurePass123!"
}'
# Response (200 OK):
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600
}curl -X GET http://localhost:8000/api/v1/documents \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# Response (200 OK):
{
"documents": [
{
"id": "doc-123",
"name": "Resume.pdf",
"size": 2048,
"created_at": "2025-11-18T10:00:00Z"
}
],
"total": 1
}# Method 1: POST with token in body (recommended)
curl -X POST http://localhost:8001/api/v1/validate \
-H "Content-Type: application/json" \
-d '{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}'
# Method 2: GET with token as query parameter
curl -X GET "http://localhost:8001/api/v1/validate/me?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
# Method 3: POST with bearer format
curl -X POST http://localhost:8001/api/v1/validate/bearer \
-H "Content-Type: application/json" \
-d '{"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}'
# Response (200 OK) for all methods:
{
"valid": true,
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"username": "user@example.com",
"email": "user@example.com",
"type": "user",
"scopes": ["read", "write"],
"expires_at": "2025-11-18T11:30:00Z",
"message": "Token is valid"
}# Step 1: Request reset token - TOKEN RETURNED IN RESPONSE (development mode)
curl -X POST http://localhost:8010/api/v1/request-reset \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
# Response (200 OK) - Token included in development/docker mode:
{
"success": true,
"message": "If an account exists with this email, a password reset link will be sent",
"note": "If an account exists with this email, a password reset link will be sent",
"reset_token": "34ELseSP1lZOZf3W9KfgJe6J4WBVwbONXeP04nQKQqc"
}
# Step 2: Validate reset token
curl -X POST http://localhost:8010/api/v1/validate-reset-token \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"token": "34ELseSP1lZOZf3W9KfgJe6J4WBVwbONXeP04nQKQqc"
}'
# Response (200 OK):
{"valid": true, "message": "Token is valid"}
# Step 3: Confirm reset with new password
curl -X POST http://localhost:8010/api/v1/confirm-reset \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"token": "34ELseSP1lZOZf3W9KfgJe6J4WBVwbONXeP04nQKQqc",
"new_password": "NewPassword123!"
}'
# Response (200 OK):
{"success": true, "message": "Password reset successfully"}{"success": true, "message": "Password reset successfully"}
---
## 🔐 Password Requirements
All passwords must have:
- **Minimum 8 characters**
- **At least 1 uppercase letter** (A-Z)
- **At least 1 lowercase letter** (a-z)
- **At least 1 digit** (0-9)
**Valid:** `SecurePass123`, `MyPassword999`, `Test1Secure`
**Invalid:** `weakpass` (no uppercase/digit), `PASSWORD1` (no lowercase), `short1A` (only 7 chars)
---
## 🧪 Testing - Three Options
### Option 1: Automated Testing (Fast - 5 minutes)
```bash
cd /path/to/auth-test-3
bash am/test_all.sh
What it tests:
- ✅ All 5 services health checks
- ✅ User registration, activation, login
- ✅ JWT token generation and validation
- ✅ Password reset complete flow
- ✅ Protected endpoints via API Gateway
- ✅ Rate limiting (100 requests/60 seconds)
- ✅ Security (401 with no token, 403 with invalid token)
Result: 100% pass rate (15/15 tests)
Import collection: /postman/AM-Complete-API-Collection.postman_collection.json
27 requests organized in 9 groups:
- Service Health (4 requests) - Health checks
- User Registration (3 requests) - Register, activate, get user
- Authentication (2 requests) - Login, validate token
- Password Reset (3 requests) - Request, validate, confirm reset
- Protected Endpoints (3 requests) - Documents, reports, portfolio
- Security Testing (3 requests) - No token, invalid token, malformed auth
- Rate Limiting (2 requests) - Single request, 101-request bulk test
- Error Scenarios (4 requests) - Invalid email, weak password, wrong credentials
- Documentation (4 links) - Swagger/ReDoc reference
Features:
- ✅ Auto-saving variables (user_id, access_token)
- ✅ Pre-configured environment
- ✅ One-click test execution
- ✅ Comprehensive descriptions
Start: Read /postman/QUICK_REFERENCE.md (5 minutes)
Follow the examples above, or use the complete workflow:
# 1. Register
EMAIL="test$(date +%s)@example.com"
USER_ID=$(curl -s -X POST http://localhost:8010/api/v1/users/register \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\",\"password\":\"TestPass123!\",\"full_name\":\"Test User\"}" \
| jq -r '.user_id')
# 2. Activate
curl -s -X PATCH http://localhost:8010/api/v1/users/$USER_ID/status \
-H "Content-Type: application/json" \
-d '{"status":"active"}' | jq .
# 3. Login
TOKEN=$(curl -s -X POST http://localhost:8001/api/v1/tokens \
-H "Content-Type: application/json" \
-d "{\"username\":\"$EMAIL\",\"password\":\"TestPass123!\"}" \
| jq -r '.access_token')
# 4. Test protected endpoint
curl -s -X GET http://localhost:8000/api/v1/documents \
-H "Authorization: Bearer $TOKEN" | jq .
# 5. Test password reset
curl -s -X POST http://localhost:8010/api/v1/request-reset \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\"}" | jq .🎯 I want to use the API
→ Read: /postman/QUICK_REFERENCE.md (5 min)
→ Then: Import /postman/AM-Complete-API-Collection.postman_collection.json
→ Test: Run the 27 requests in order
🏗️ I want to understand the architecture
→ Read: /docs/ARCHITECTURE.md (15 min)
→ Then: /.github/copilot-instructions.md (development patterns)
→ Then: /docs/SECURITY.md (security details)
🧪 I want to test everything
→ Run: bash am/test_all.sh (5 min)
→ Read: /docs/TESTING.md (comprehensive guide)
→ Use: Postman collection for manual testing
🔑 I need password reset feature
→ Read: /FEATURE_PASSWORD_RESET.md (complete guide)
→ Test: Manual flow or Postman Group 4
→ Debug: See troubleshooting section
🚀 I want to deploy to production
→ Read: /docs/QUICK_START.md (setup guide)
→ Check: /docs/SECURITY.md (security checklist)
→ Reference: /.github/copilot-instructions.md
| File | Purpose | Read Time |
|---|---|---|
/DOCUMENTATION.md |
Master index with workflows | 10 min |
/FEATURE_PASSWORD_RESET.md |
Complete password reset guide | 15 min |
/docs/ARCHITECTURE.md |
System design & patterns | 15 min |
/docs/QUICK_START.md |
5-minute setup guide | 5 min |
/docs/SECURITY.md |
Security patterns & checklist | 15 min |
/docs/TESTING.md |
Complete testing guide | 20 min |
/postman/README.md |
Postman overview & links | 5 min |
/postman/QUICK_REFERENCE.md |
30-second setup card | 5 min |
/postman/POSTMAN_COMPLETE_GUIDE.md |
Comprehensive Postman guide | 20 min |
- Start services:
cd am && docker-compose up -d --build - Wait 30 seconds for services to be ready
- Run:
bash am/test_all.sh - Check result: All tests pass ✅
- Open Postman
- Import:
AM-Complete-API-Collection.postman_collection.json - Set environment:
base_url=http://localhost:8000, etc. - Run requests in order:
- Health check (verify services up)
- Register user
- Activate user
- Login
- Access protected endpoint
- Test password reset
- Read:
/.github/copilot-instructions.md→ "Adding New Endpoints" - Create endpoint file in
am/am-api-gateway/api/v1/endpoints/ - Register router in
main.py - Add tests to Postman collection
- Update documentation
- Run tests:
bash am/test_all.sh
- Request reset:
POST /api/v1/request-resetwith email - Get token from logs:
docker-compose logs am-user-management | grep "Reset token" - Validate token:
POST /api/v1/validate-reset-token - Confirm reset:
POST /api/v1/confirm-resetwith new password - Verify: Login with new password
# 1. Check if user exists and is activated
curl http://localhost:8010/api/v1/users/{user_id}
# 2. Check if token is valid
curl -X POST http://localhost:8001/api/v1/validate \
-H "Content-Type: application/json" \
-d '{"token": "YOUR_TOKEN"}'
# 3. Check logs for errors
docker-compose logs am-api-gateway | grep -i error
# 4. Verify token format: "Authorization: Bearer <token>"- ✅ User registration with email/password
- ✅ User account activation
- ✅ JWT token generation
- ✅ Token validation
- ✅ Token expiration (1 hour default)
- ✅ Password reset with 24-hour tokens
- ✅ Role-based access control (RBAC)
- ✅ Protected endpoints
- ✅ Service-to-service authentication
- ✅ API Gateway permission checks
- ✅ Bcrypt password hashing (12 rounds)
- ✅ JWT HS256 signing
- ✅ Rate limiting (100 req/60s per IP)
- ✅ Network isolation (internal services)
- ✅ Audit logging
- ✅ CORS configuration
- ✅ Async/await (FastAPI)
- ✅ Connection pooling (PostgreSQL)
- ✅ Request caching headers
- ✅ Optimized database queries
- ✅ Docker containerization
- ✅ Health checks
- ✅ Centralized logging
- ✅ Error handling & recovery
- ✅ Database migrations
# Check services
docker-compose ps
# View logs
docker-compose logs am-user-management
# Restart
docker-compose down && docker-compose up -d --build- ✅ Is user registered? Yes → Activate user
- ✅ Is user activated? Yes → Get new token
- ✅ Token format:
Authorization: Bearer <token>(with space) - ✅ Token expired? (default 1 hour) → Login again
- ✅ Wait 60 seconds, then retry
- ✅ Or increase limit in
docker-compose.yml:RATE_LIMIT_REQUESTS=200
# Get token from logs
docker-compose logs am-user-management | grep "Reset token"This is correct! Internal services (8002, 8003) are not exposed. Use API Gateway (8000).
- Read relevant documentation (see files guide above)
- Check logs:
docker-compose logs <service_name> - Run tests:
bash am/test_all.sh - Use Postman: Test endpoints manually with collection
- Read troubleshooting sections in relevant docs
All services run in Docker with these configurations:
PostgreSQL Database:
- Host:
postgres(internal Docker network) - Port: 5432 (internal only, not exposed)
- Database:
auth_db - Auto-migration on startup
Environment Variables (in am/.env.docker):
JWT_SECRET=your-32-character-secret-key-here
INTERNAL_JWT_SECRET=your-service-token-secret-key-here
DATABASE_URL=postgresql://postgres:password@postgres:5432/auth_db
LOG_FORMAT=structured # or 'json' for production
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60
Access from Outside Docker:
- API Gateway: http://localhost:8000
- User Management: http://localhost:8010
- Auth Tokens: http://localhost:8001
Access from Inside Docker:
- Services use container names:
http://am-api-gateway:8000
# 1. Create unique email
EMAIL="user$(date +%s)@example.com"
# 2. Register user
USER_RESPONSE=$(curl -s -X POST http://localhost:8010/api/v1/users/register \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$EMAIL\",
\"password\": \"SecurePass123!\",
\"full_name\": \"John Doe\"
}")
USER_ID=$(echo $USER_RESPONSE | jq -r '.user_id')
echo "Registered user: $USER_ID"
# 3. Activate user
curl -s -X PATCH http://localhost:8010/api/v1/users/$USER_ID/status \
-H "Content-Type: application/json" \
-d '{"status": "active"}' | jq .
# 4. Login (get JWT token)
LOGIN_RESPONSE=$(curl -s -X POST http://localhost:8001/api/v1/tokens \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$EMAIL\",
\"password\": \"SecurePass123!\"
}")
TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.access_token')
echo "Got token: ${TOKEN:0:20}..."
# 5. Access protected endpoint
curl -s -X GET http://localhost:8000/api/v1/documents \
-H "Authorization: Bearer $TOKEN" | jq .
echo "✅ Workflow complete!"# 1. Request password reset
EMAIL="user@example.com"
curl -s -X POST http://localhost:8010/api/v1/request-reset \
-H "Content-Type: application/json" \
-d "{\"email\": \"$EMAIL\"}" | jq .
# 2. Extract token from logs (development only)
RESET_TOKEN=$(docker-compose logs am-user-management | grep "Reset token" | tail -1 | sed 's/.*: //')
echo "Reset token: $RESET_TOKEN"
# 3. Validate token
curl -s -X POST http://localhost:8010/api/v1/validate-reset-token \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$EMAIL\",
\"token\": \"$RESET_TOKEN\"
}" | jq .
# 4. Confirm password reset
curl -s -X POST http://localhost:8010/api/v1/confirm-reset \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$EMAIL\",
\"token\": \"$RESET_TOKEN\",
\"new_password\": \"NewPassword123!\"
}" | jq .
# 5. Verify new password works
curl -s -X POST http://localhost:8001/api/v1/tokens \
-H "Content-Type: application/json" \
-d "{
\"username\": \"$EMAIL\",
\"password\": \"NewPassword123!\"
}" | jq '.access_token'
echo "✅ Password reset complete!"- External ports exposed: Only 3 (8000, 8001, 8010)
- Internal ports: 8002, 8003 have no external port mapping
- Attack surface: 57% reduction compared to no gateway
- Docker network: All services on internal bridge network
User provides password → API returns JWT token
Client uses token in header: Authorization: Bearer <token>
Token expires after 1 hour
Services validate token at every request
100 requests allowed per 60 seconds per IP
Response headers show limit:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1731968400
- All requests logged with timestamp, user, endpoint, status
- Logs in JSON format (production) or structured (development)
- Sensitive data (passwords, tokens) never logged
| Code | Meaning | Example |
|---|---|---|
| 200 | Success | Token validation, data retrieved |
| 201 | Created | User registered, resource created |
| 400 | Bad Request | Invalid email, weak password |
| 401 | Unauthorized | No token, invalid token, user not activated |
| 403 | Forbidden | Token valid but no access to resource |
| 404 | Not Found | User not found, resource not found |
| 429 | Too Many Requests | Rate limit exceeded (wait 60 seconds) |
| 500 | Server Error | Service error, database error |
- Docker & Docker Compose (for running services)
- Python 3.11+ (for Python services)
- Java 17+ (for Java service)
- Git (for version control)
- Postman (for API testing)
- jq (for JSON parsing in scripts)
- Create feature branch:
git checkout -b feature/my-feature - Implement feature following patterns in
/.github/copilot-instructions.md - Add tests to Postman collection
- Update documentation
- Run:
bash am/test_all.shto verify - Submit pull request with test results
- Format: PEP 8 (Python), Google Java Style
- Type hints: Required in all functions
- Tests: Unit + integration tests required
- Documentation: Docstrings and API documentation required
- Logging: Use centralized logging framework
- Start services:
cd am && docker-compose up -d --build - Wait 30 seconds for services to initialize
- Choose a testing option: Automated, Postman, or manual
- Read relevant documentation (see guide above)
- Explore the code in each service directory
- Modify and extend as needed for your use case
| Metric | Value |
|---|---|
| Services | 5 (3 public + 2 internal) |
| API Endpoints | 15+ (core functionality) |
| Database Tables | 3 (users, password_reset_tokens, service_registry) |
| Test Coverage | 15+ automated tests, 27 Postman requests |
| Documentation | 9 comprehensive guides (5,600+ lines) |
| Code Lines | 3,000+ (excluding tests) |
| Docker Compose | Yes (all services containerized) |
| Security Layers | 2 (network + JWT authentication) |
Status: ✅ PRODUCTION READY
Last Updated: November 18, 2025
Test Pass Rate: 100% (15/15 automated tests)
Documentation: Complete and comprehensive
For more information, see /DOCUMENTATION.md (master documentation index)
A production-ready, microservices-based authentication system built with Clean Architecture principles, featuring JWT token management and comprehensive user management capabilities.
Auth Test is a complete authentication and authorization platform designed for modern web applications. It consists of two independent microservices that work together to provide secure user management and token-based authentication:
- AM User Management Service - Handles user registration, authentication, and account management
- AM Auth Tokens Service - Manages JWT token creation, validation, and lifecycle
The system is designed with security, scalability, and maintainability as core principles, making it suitable for production deployments.
This is a microservices architecture where each service has a specific responsibility:
┌─────────────────────────────────────────────────────────────┐
│ Client Application │
└──────────────────┬──────────────────────────────────────────┘
│
├─────────────────┬──────────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────────────┐ ┌──────────────────┐ ┌────────────────┐
│ Auth Tokens Service │ │ User Management │ │ PostgreSQL │
│ (Port 5000/8000) │──│ Service (8000) │───│ Database │
│ JWT Operations │ │ User Accounts │ │ Persistence │
└──────────────────────┘ └──────────────────┘ └────────────────┘
- Purpose: JWT token lifecycle management
- Key Features:
- Create JWT access tokens after credential validation
- Validate JWT tokens and extract user claims
- OAuth2-compatible token endpoints
- Account status enforcement (only ACTIVE users get tokens)
- Integration with User Management for credential validation
- Technology: FastAPI, Python 3.11
- Purpose: User account management and authentication
- Key Features:
- User registration with email verification
- Secure credential validation (Bcrypt password hashing)
- Account status management (ACTIVE, INACTIVE, SUSPENDED)
- Email verification system
- PostgreSQL data persistence
- Clean Architecture with Domain-Driven Design
- Technology: FastAPI, PostgreSQL 15+, SQLAlchemy 2.0, Python 3.11
- Python 3.11+
- PostgreSQL 15+ (for User Management service)
- pip or uv for package management
git clone https://github.com/AM-Portfolio/auth-test.git
cd auth-testcd am/am-user-management
# Install dependencies
pip install -r requirements.txt
# Setup PostgreSQL database
createdb am_user_management
# Configure environment
cp .env.example .env
# Edit .env with your PostgreSQL credentials
# Run the service
python main_integrated.pyService will be available at http://localhost:8000
cd am/am-auth-tokens
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp .env.example .env
# Set USER_SERVICE_URL=http://localhost:8000
# Run the service
python main.pyService will be available at http://localhost:5000
POST /api/v1/tokens- Create JWT access token with credentialsPOST /api/v1/tokens/oauth- OAuth2-compatible token endpointPOST /api/v1/validate- Validate JWT tokenGET /health- Health checkGET /api/v1/docs- API documentation (when DEBUG=true)
POST /api/v1/auth/register- Register new userPOST /api/v1/auth/login- Validate credentials and return user dataGET /api/v1/auth/verify-email- Verify email addressPOST /api/v1/auth/resend-verification- Resend verification emailGET /health- Health checkGET /docs- API documentation
Here's how the services work together for a complete authentication flow:
-
User Registration
- Client → User Management Service:
POST /api/v1/auth/register - User account created with status="PENDING" (awaiting email verification)
- Client → User Management Service:
-
Email Verification
- User clicks verification link
- Client → User Management Service:
GET /api/v1/auth/verify-email?token=... - User status updated to "ACTIVE"
-
Token Creation (Login)
- Client → Auth Tokens Service:
POST /api/v1/tokens(username + password) - Auth Tokens → User Management:
POST /api/v1/auth/login(validate credentials) - User Management validates and returns user data including status
- Auth Tokens checks status == "ACTIVE"
- If active, JWT token is created and returned to client
- Client → Auth Tokens Service:
-
Token Usage
- Client → Any Service: API request with
Authorization: Bearer <token> - Service validates token (internal validation or via Auth Tokens Service)
- Client → Any Service: API request with
- Bcrypt hashing with configurable rounds (default: 12)
- No plain-text password storage
- Secure password validation
- Only ACTIVE users can obtain JWT tokens
- Status validation prevents unauthorized access
- Missing status treated as security failure (403 Forbidden)
- JWT tokens with configurable expiration (default: 24 hours)
- HS256 algorithm for token signing
- Configurable JWT secret for production security
- Pydantic schemas for all API inputs
- SQL injection prevention via ORM
- CORS configuration for cross-origin requests
auth-test/
├── am/
│ ├── am-user-management/ # User Management microservice
│ │ ├── core/ # Domain kernel (value objects, interfaces)
│ │ ├── modules/ # Feature modules (account management)
│ │ ├── shared_infra/ # Infrastructure (database, events)
│ │ ├── main_integrated.py # FastAPI application entry point
│ │ ├── requirements.txt # Python dependencies
│ │ └── README.md # Service-specific documentation
│ │
│ └── am-auth-tokens/ # Auth Tokens microservice
│ ├── app/
│ │ ├── core/ # JWT security operations
│ │ ├── api/v1/ # API endpoints
│ │ └── services/ # User validation integration
│ ├── shared_infra/ # Configuration management
│ ├── main.py # FastAPI application entry point
│ ├── requirements.txt # Python dependencies
│ └── README.md # Service-specific documentation
│
├── pyproject.toml # Project metadata
└── README.md # This file
cd am/am-user-management
python -m pytestcd am/am-auth-tokens
pytestRegister a user:
curl -X POST "http://localhost:8000/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "securepass123",
"first_name": "Test",
"last_name": "User"
}'Create token (after email verification):
curl -X POST "http://localhost:5000/api/v1/tokens" \
-H "Content-Type: application/json" \
-d '{
"username": "test@example.com",
"password": "securepass123"
}'Both services use environment variables for configuration. Key variables:
User Management Service:
DATABASE_URL- PostgreSQL connection stringBCRYPT_ROUNDS- Password hashing strength (default: 12)REQUIRE_EMAIL_VERIFICATION- Enable/disable email verification
Auth Tokens Service:
JWT_SECRET- Secret key for JWT signing (MUST be changed in production)JWT_EXPIRE_MINUTES- Token expiration time (default: 1440)USER_SERVICE_URL- URL of User Management service
Both services include Docker support. See individual service READMEs for Docker Compose configurations.
- User Management: See
am/am-user-management/README.mdandPRODUCTION_GUIDE.md - Auth Tokens: See
am/am-auth-tokens/README.mdandENVIRONMENT_GUIDE.md - Replit Setup: See
replit.mdfor cloud development environment setup
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
-
2025-10-06: Security hardening and integration fixes
- Fixed circular dependency between services
- Added account status validation
- Improved security for inactive/suspended accounts
-
2025-10-04: Initial Replit setup
- Python 3.11 environment
- FastAPI dependencies installed
- Development workflow configured
- Issues: Open an issue on GitHub for bug reports or feature requests
- Documentation: Check service-specific README files for detailed information
- Community: Use GitHub Discussions for questions and community support
This project is part of the AM Portfolio and is available under the MIT License.
Built with ❤️ by the AM Portfolio team