Service Communication
How SVA services communicate securely with each other.
Overview
SVA OAuth consists of three main services that need to communicate:
- SVA OAuth Provider (
sva_oauth) - Public-facing OAuth server - SVA Core (
sva_server) - User account and vault management - SVA Client (
sva_client) - User-facing consent UI
Communication Model
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ SVA Client │────────▶│ SVA Core │────────▶│ SVA OAuth │
│ (Frontend) │ │ (Server) │ │ Provider │
└──────────────┘ └──────────────┘ └──────────────┘
Service Token Authentication
All inter-service communication uses a shared secret token.
Configuration
Both services must have the same INTERNAL_SERVICE_TOKEN:
# sva_oauth/backend/config/settings.py
INTERNAL_SERVICE_TOKEN = os.getenv('INTERNAL_SERVICE_TOKEN', 'dev-shared-secret')
# sva_server/backend/settings.py
INTERNAL_SERVICE_TOKEN = os.getenv('INTERNAL_SERVICE_TOKEN', 'dev-shared-secret')
Header
Service-to-service requests include the token in headers:
headers = {
'X-Service-Token': INTERNAL_SERVICE_TOKEN
}
Internal Endpoints
SVA OAuth Internal Endpoints
These endpoints are only accessible with service token authentication:
Get Auth Request Details
GET /api/auth/internal/auth-request-details/?auth_request_id={id}
Headers: {
"X-Service-Token": "shared-secret"
}
Response:
{
"auth_request_id": "uuid",
"status": "pending",
"expires_at": "2024-01-01T00:00:00Z",
"requested_scopes": ["email", "profile"],
"scope_details": [...],
"state": "state-parameter",
"redirect_uri": "https://app.com/callback/",
"client": {
"client_id": "client_id",
"name": "App Name",
"logo": "https://...",
"description": "App description"
}
}
Consent Complete
POST /api/auth/internal/consent-complete/
Headers: {
"X-Service-Token": "shared-secret"
}
Body: {
"auth_request_id": "uuid",
"user_id": "user_id",
"approved_scopes": ["email", "profile"],
"data_token": "jwt-token"
}
Response:
{
"redirect_uri": "https://app.com/callback/",
"authorization_code": "code",
"state": "state-parameter"
}
SVA Core Internal Endpoints
These endpoints proxy requests to SVA OAuth:
Get Auth Request (Proxy)
GET /api/internal/oauth/requests/{auth_request_id}/
Headers: {
"Authorization": "Bearer user-session-token"
}
Flow:
- SVA Client calls SVA Core
- SVA Core validates user session
- SVA Core proxies to SVA OAuth with service token
- SVA Core returns response to SVA Client
Attest Data
POST /api/internal/attest-data/
Headers: {
"Authorization": "Bearer user-session-token"
}
Body: {
"auth_request_id": "uuid",
"user_id": "user_id",
"audience": "client_id",
"claims": {
"email": "[email protected]",
"name": "John Doe"
}
}
Response:
{
"data_token": "jwt-token"
}
Consent Complete (Proxy)
POST /api/internal/oauth/requests/{auth_request_id}/complete/
Headers: {
"Authorization": "Bearer user-session-token"
}
Body: {
"approved_scopes": ["email", "profile"],
"data_token": "jwt-token"
}
Flow:
- SVA Client calls SVA Core
- SVA Core validates user session
- SVA Core proxies to SVA OAuth with service token
- SVA Core returns response to SVA Client
Security Model
Service Token
- Purpose: Authenticate service-to-service requests
- Storage: Environment variable
- Strength: Strong, randomly generated secret
- Rotation: Should be rotated periodically
Network Isolation
- Services communicate via internal network addresses
- Production: Use private network (e.g., Docker network)
- Development: Use localhost with different ports
HTTPS
- All production communication over HTTPS
- Internal services can use HTTP if on private network
- Public endpoints must use HTTPS
Error Handling
Invalid Service Token
# Returns 401 Unauthorized
{
"error": "Invalid service token"
}
Service Unavailable
# Returns 503 Service Unavailable
{
"error": "Service temporarily unavailable"
}
Timeout Configuration
# sva_server/backend/settings.py
INTERNAL_SERVICE_TIMEOUT = 5 # seconds
Example: Service-to-Service Call
import requests
from django.conf import settings
def get_auth_request_details(auth_request_id):
"""Call SVA OAuth from SVA Core"""
url = f"{settings.SVA_AUTH_SERVER_BASE_URL}/api/auth/internal/auth-request-details/"
headers = {
'X-Service-Token': settings.INTERNAL_SERVICE_TOKEN
}
params = {
'auth_request_id': auth_request_id
}
response = requests.get(url, headers=headers, params=params, timeout=5)
response.raise_for_status()
return response.json()
Best Practices
- Use environment variables - Never hardcode service tokens
- Rotate tokens regularly - Change service tokens periodically
- Use HTTPS in production - Encrypt all communication
- Implement timeouts - Prevent hanging requests
- Log service calls - Monitor inter-service communication
- Handle errors gracefully - Implement retry logic
- Validate responses - Check response structure
Next Steps
- Learn about the OAuth Flow
- Understand Data Tokens
- Read about Zero-Knowledge architecture