Skip to main content
The auth service runs as a separate container alongside the API service.

Architecture

                    ┌─────────────┐
                    │   Railway    │
                    │   (or local  │
                    │   Docker)    │
                    └──────┬──────┘

          ┌────────────────┼────────────────┐
          │                │                │
   ┌──────▼──────┐ ┌──────▼──────┐ ┌───────▼──────┐
   │  API :8000  │ │ Auth :8001  │ │  Orch :8002  │
   │ (Dockerfile │ │ (Dockerfile │ │              │
   │  .api)      │ │  .auth)     │ │              │
   └──────┬──────┘ └──────┬──────┘ └──────────────┘
          │                │
     ┌────┴────────────────┴────┐
     │                          │
┌────▼────┐              ┌──────▼──────┐
│Postgres │              │    Redis    │
│ (auth   │              │  (bloom     │
│ schema) │              │  filter)    │
└─────────┘              └─────────────┘

Docker

Dockerfile

docker/Dockerfile.auth:
  • Base: python:3.11-slim
  • Runs python scripts/migrate.py on startup (includes 004_auth_schema.sql)
  • Starts uvicorn on port 8001 with 2 workers
  • Same build pattern as Dockerfile.api

Docker Compose

The auth service is defined in docker-compose.yml:
auth:
  build:
    context: .
    dockerfile: docker/Dockerfile.auth
  ports:
    - "8001:8001"
  environment:
    AUTH_DATABASE_URL: postgresql+asyncpg://quint:quint_local_dev@postgres:5432/quint
    REDIS_URL: redis://redis:6379/0
    AUTH_PORT: "8001"
    AUTH_MASTER_KEY: "local-dev-master-key-do-not-use-in-prod"
  depends_on:
    postgres: { condition: service_healthy }
    redis: { condition: service_healthy }
  volumes:
    - ./src:/app/src
The API service connects to the auth service via:
AUTH_SERVICE_URL: http://auth:8001

Starting locally

# Start everything
docker compose up -d

# Start just auth + dependencies
docker compose up -d postgres redis auth

# View auth service logs
docker compose logs -f auth

Environment Variables

Auth Service (src/auth_service/config.py)

VariableDefaultDescription
AUTH_DATABASE_URL(required)Postgres connection string
REDIS_URLredis://localhost:6379/0Redis connection
AUTH_PORT8001Service port
AUTH_MASTER_KEY(required)AES-256-GCM encryption key for private keys
AUTH_APP_TOKEN_TTL_DAYS365Default app token TTL
AUTH_BEARER_TOKEN_TTL_DAYS90Default bearer token TTL
AUTH_AGENT_TOKEN_TTL_HOURS24Default agent token TTL
AUTH_SUBAGENT_TOKEN_TTL_HOURS4Default subagent token TTL
AUTH_SESSION_TOKEN_TTL_MINUTES60Default session token TTL
AUTH_OVERRIDE_TOKEN_TTL_MINUTES5Default override token TTL

API Service (additional)

VariableDefaultDescription
AUTH_SERVICE_URLhttp://localhost:8001Auth service base URL

Database Migration

Migration 004_auth_schema.sql creates the auth schema. It is idempotent — safe to run multiple times.
# Run manually
python scripts/migrate.py

# Or it runs automatically on container startup

Railway Deployment

CI/CD Pipeline (.github/workflows/deploy.yml)

test → deploy-api ─────────────┐
     → deploy-auth ─────────────┤→ smoke-test
     → deploy-orchestrator ─────┘
The deploy-auth job:
  1. Uses Railway CLI (railwayapp/cli-action@v2)
  2. Deploys from docker/Dockerfile.auth
  3. Detects environment (production/staging) from branch
  4. Sets AUTH_MASTER_KEY from GitHub Secrets

Required GitHub Secrets

SecretUsed by
RAILWAY_TOKENAll deploy jobs
AUTH_MASTER_KEYdeploy-auth job

Railway Service Configuration

The auth service should be configured as a separate Railway service with:
  • Custom start command: python scripts/migrate.py && uvicorn src.auth_service.main:create_app --factory --host 0.0.0.0 --port 8001 --workers 2
  • Health check: GET /health
  • Private networking enabled (only API service needs to reach it)

Bootstrap Script

For existing deployments migrating from X-API-Key auth:
python scripts/bootstrap_auth.py
This script:
  1. Reads all customers from public.customers
  2. For each customer:
    • Generates an ES256 key pair
    • Encrypts the private key with AES-256-GCM
    • Stores the signing key in auth.signing_keys
    • Creates an app token in auth.app_tokens
    • Outputs the raw app token (for customer distribution)
Run this script once after deploying the auth schema. The output includes raw app tokens — distribute them securely to customers.