165 lines
3.3 KiB
Markdown
165 lines
3.3 KiB
Markdown
# Quick Start: Service Tokens
|
|
|
|
**Status**: ✅ Ready to Use
|
|
**Date**: 2025-10-31
|
|
|
|
---
|
|
|
|
## Generate a Service Token (30 seconds)
|
|
|
|
```bash
|
|
# Generate token for orchestrator
|
|
python scripts/generate_service_token.py tenant-deletion-orchestrator
|
|
|
|
# Output includes:
|
|
# - Token string
|
|
# - Environment variable export
|
|
# - Usage examples
|
|
```
|
|
|
|
---
|
|
|
|
## Use in Code (1 minute)
|
|
|
|
```python
|
|
import os
|
|
import httpx
|
|
|
|
# Load token from environment
|
|
SERVICE_TOKEN = os.getenv("SERVICE_TOKEN")
|
|
|
|
# Make authenticated request
|
|
async def call_service(tenant_id: str):
|
|
headers = {"Authorization": f"Bearer {SERVICE_TOKEN}"}
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
response = await client.delete(
|
|
f"http://orders-service:8000/api/v1/orders/tenant/{tenant_id}",
|
|
headers=headers
|
|
)
|
|
return response.json()
|
|
```
|
|
|
|
---
|
|
|
|
## Protect an Endpoint (30 seconds)
|
|
|
|
```python
|
|
from shared.auth.access_control import service_only_access
|
|
from shared.auth.decorators import get_current_user_dep
|
|
from fastapi import Depends
|
|
|
|
@router.delete("/tenant/{tenant_id}")
|
|
@service_only_access # ← Add this line
|
|
async def delete_tenant_data(
|
|
tenant_id: str,
|
|
current_user: dict = Depends(get_current_user_dep),
|
|
db = Depends(get_db)
|
|
):
|
|
# Your code here
|
|
pass
|
|
```
|
|
|
|
---
|
|
|
|
## Test with Curl (30 seconds)
|
|
|
|
```bash
|
|
# Set token
|
|
export SERVICE_TOKEN='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
|
|
|
|
# Test deletion preview
|
|
curl -k -H "Authorization: Bearer $SERVICE_TOKEN" \
|
|
"https://localhost/api/v1/orders/tenant/<tenant-id>/deletion-preview"
|
|
|
|
# Test actual deletion
|
|
curl -k -X DELETE -H "Authorization: Bearer $SERVICE_TOKEN" \
|
|
"https://localhost/api/v1/orders/tenant/<tenant-id>"
|
|
```
|
|
|
|
---
|
|
|
|
## Verify a Token (10 seconds)
|
|
|
|
```bash
|
|
python scripts/generate_service_token.py --verify '<token>'
|
|
```
|
|
|
|
---
|
|
|
|
## Common Commands
|
|
|
|
```bash
|
|
# Generate for all services
|
|
python scripts/generate_service_token.py --all
|
|
|
|
# List available services
|
|
python scripts/generate_service_token.py --list-services
|
|
|
|
# Generate with custom expiration
|
|
python scripts/generate_service_token.py auth-service --days 90
|
|
|
|
# Help
|
|
python scripts/generate_service_token.py --help
|
|
```
|
|
|
|
---
|
|
|
|
## Kubernetes Deployment
|
|
|
|
```bash
|
|
# Create secret
|
|
kubectl create secret generic service-tokens \
|
|
--from-literal=orchestrator-token='<token>' \
|
|
-n bakery-ia
|
|
|
|
# Use in deployment
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
spec:
|
|
template:
|
|
spec:
|
|
containers:
|
|
- name: orchestrator
|
|
env:
|
|
- name: SERVICE_TOKEN
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: service-tokens
|
|
key: orchestrator-token
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Getting 401?
|
|
```bash
|
|
# Verify token is valid
|
|
python scripts/generate_service_token.py --verify '<token>'
|
|
|
|
# Check Authorization header format
|
|
curl -H "Authorization: Bearer <token>" ... # ✅ Correct
|
|
curl -H "Token: <token>" ... # ❌ Wrong
|
|
```
|
|
|
|
### Getting 403?
|
|
- Check endpoint has `@service_only_access` decorator
|
|
- Verify token type is 'service' (use --verify)
|
|
|
|
### Token Expired?
|
|
```bash
|
|
# Generate new token
|
|
python scripts/generate_service_token.py <service-name> --days 365
|
|
```
|
|
|
|
---
|
|
|
|
## Full Documentation
|
|
|
|
See [SERVICE_TOKEN_CONFIGURATION.md](SERVICE_TOKEN_CONFIGURATION.md) for complete guide.
|
|
|
|
---
|
|
|
|
**That's it!** You're ready to use service tokens. 🚀
|