Add improvements

This commit is contained in:
Urtzi Alfaro
2026-01-12 14:24:14 +01:00
parent 6037faaf8c
commit 230bbe6a19
61 changed files with 1668 additions and 894 deletions

View File

@@ -190,6 +190,197 @@ graph TD
- Gateway validates access to requested tenant
- Prevents tenant ID spoofing attacks
## JWT Service Token Architecture
### Overview
The Auth Service implements **JWT service tokens** for secure service-to-service (S2S) authentication across all microservices. This eliminates the need for internal API keys and provides a unified, secure authentication mechanism for both user and service requests.
### Service Token vs User Token
**User Tokens** (for frontend/API consumers):
- `type: "access"` - Regular user authentication
- Contains user ID, email, tenant membership
- Expires in 15-30 minutes
- Used by browsers and mobile apps
**Service Tokens** (for microservice communication):
- `type: "service"` - Internal service authentication
- Contains service name, optional tenant context
- Expires in 1 hour (longer for batch operations)
- Used by backend services calling other services
### Service Token Payload Structure
```json
{
"sub": "demo-session",
"user_id": "demo-session-service",
"email": "demo-session-service@internal",
"service": "demo-session",
"type": "service",
"role": "admin",
"tenant_id": "optional-tenant-uuid",
"exp": 1735693199,
"iat": 1735689599,
"iss": "bakery-auth"
}
```
### Key Features
#### 1. Unified JWT Handler
- **File**: `shared/auth/jwt_handler.py`
- **Purpose**: Single source of truth for token creation and validation
- **Method**: `create_service_token(service_name, tenant_id=None)`
- **Shared JWT Secret**: All services use same `JWT_SECRET_KEY` from `shared/config/base.py`
#### 2. Internal Service Registry
- **File**: `shared/config/base.py`
- **Constant**: `INTERNAL_SERVICES` set containing all 21 microservice names
- **Purpose**: Automatic access grants for registered services
- **Services**: gateway, auth, tenant, inventory, production, recipes, suppliers, orders, sales, procurement, pos, forecasting, training, ai-insights, orchestrator, notification, alert-processor, demo-session, external, distribution
#### 3. Service Authentication Flow
```
┌─────────────────┐
│ Service A │
│ (e.g., demo) │
└────────┬────────┘
│ 1. Create service token
│ jwt_handler.create_service_token(
│ service_name="demo-session",
│ tenant_id=tenant_id
│ )
┌─────────────────────────────────────────┐
│ HTTP Request │
│ -------------------------------- │
│ POST /api/v1/tenant/clone │
│ Headers: │
│ Authorization: Bearer {token} │
│ X-Service: demo-session-service │
└────────┬────────────────────────────────┘
┌─────────────────┐
│ Service B │
│ (e.g., tenant) │
└────────┬────────┘
│ 2. Validate token
│ jwt_handler.verify_token(token)
│ 3. Check internal service
│ if is_internal_service(user_id):
│ grant_admin_access()
┌─────────────────┐
│ Authorized │
│ Response │
└─────────────────┘
```
#### 4. Automatic Admin Privileges
- Services in `INTERNAL_SERVICES` registry get automatic admin access
- No need for tenant membership checks
- Optimizes database queries (skips membership lookups)
- Used in:
- `shared/auth/decorators.py` - JWT authentication decorator
- `services/tenant/app/api/tenant_operations.py` - Tenant access verification
- `services/tenant/app/repositories/tenant_member_repository.py` - Skip membership queries
### Migration from Internal API Keys
**Previous System (Deprecated):**
```python
# Old approach - REMOVED
headers = {
"X-Internal-API-Key": "dev-internal-key-change-in-production"
}
```
**New System (Current):**
```python
# New approach - JWT service tokens
from shared.auth.jwt_handler import JWTHandler
jwt_handler = JWTHandler(settings.JWT_SECRET_KEY, settings.JWT_ALGORITHM)
service_token = jwt_handler.create_service_token(
service_name="my-service",
tenant_id=tenant_id # Optional tenant context
)
headers = {
"Authorization": f"Bearer {service_token}",
"X-Service": "my-service"
}
```
### Security Benefits
1. **Token Expiration** - Service tokens expire (1 hour), unlike permanent API keys
2. **Signature Verification** - JWT signatures prevent token forgery
3. **Tenant Context** - Service tokens can include tenant scope for proper authorization
4. **Audit Trail** - All service requests are authenticated and logged
5. **No Secret Distribution** - Shared JWT secret is managed via environment variables
6. **Rotation Ready** - JWT secret can be rotated without changing code
### Performance Characteristics
- **Token Creation**: <1ms (in-memory JWT signing)
- **Token Validation**: <1ms (in-memory JWT verification)
- **Cache Enabled**: Gateway caches validated tokens for 5 minutes
- **No HTTP Calls**: Service-to-service auth happens locally
### Implementation Examples
#### Example 1: Demo Session Service Cloning Data
```python
# services/demo_session/app/services/clone_orchestrator.py
service_token = self.jwt_handler.create_service_token(
service_name="demo-session",
tenant_id=virtual_tenant_id
)
response = await client.post(
f"{service.url}/internal/demo/clone",
params={...},
headers={
"Authorization": f"Bearer {service_token}",
"X-Service": "demo-session-service"
}
)
```
#### Example 2: Gateway Validating Demo Sessions
```python
# gateway/app/middleware/auth.py
service_token = jwt_handler.create_service_token(service_name="gateway")
response = await client.get(
f"http://demo-session-service:8000/api/v1/demo/sessions/{session_id}",
headers={"Authorization": f"Bearer {service_token}"}
)
```
#### Example 3: Deletion Orchestrator
```python
# services/auth/app/services/deletion_orchestrator.py
service_token = self.jwt_handler.create_service_token(
service_name="auth",
tenant_id=tenant_id
)
headers = {
"Authorization": f"Bearer {service_token}",
"X-Service": "auth-service"
}
```
### API Endpoints (Key Routes)
### Authentication