Skip to main content
This guide covers the transition from the legacy X-API-Key authentication to the new token hierarchy.

Overview

The migration is non-breaking. Both authentication methods work simultaneously during the transition period.
Phase 1: Deploy         Both methods work, legacy gets deprecation header
Phase 2: Bootstrap      Generate tokens for existing customers
Phase 3: Migrate        Customers switch to token auth
Phase 4: Cutover        Disable legacy auth path

Phase 1: Deploy

Deploy the auth service and database migration. No changes to existing API behavior.
# 1. Run the auth schema migration
python scripts/migrate.py

# 2. Start the auth service
docker compose up -d auth
What changes for existing customers: Nothing. X-API-Key continues to work exactly as before. The only visible difference is a new response header on legacy-authenticated requests:
X-Quint-Deprecation: X-API-Key auth is deprecated; migrate to Bearer token auth

Phase 2: Bootstrap

Generate signing keys and app tokens for each existing customer.
python scripts/bootstrap_auth.py
Output (per customer):
Customer: Acme Corp (550e8400-...)
  Signing Key ID: key-uuid
  App Token: qt_app_eyJhbGciOiJFUzI1NiIs...
  Token Hash: a1b2c3d4...
Distribute app tokens to customers through a secure channel.

Phase 3: Migrate

Customers derive their token chain and switch their integration.

Step 1: Get a Bearer Token

curl -X POST https://api.quint.ai/auth/tokens/bearer \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "your-customer-id",
    "app_token_hash": "sha256-hash-of-your-app-token",
    "environment": "production"
  }'

Step 2: Create Agent Tokens

curl -X POST https://api.quint.ai/auth/tokens/agent \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "your-customer-id",
    "bearer_jti": "jti-from-bearer-token",
    "agent_id": "my-agent",
    "rbac": {
      "allowed_actions": ["*:*:*"],
      "denied_actions": [],
      "allowed_resources": ["*"],
      "denied_resources": [],
      "max_sensitivity_level": 4
    }
  }'

Step 3: Switch Authentication Headers

X-API-Key: sk-your-api-key

Step 4: Verify

curl -X POST https://api.quint.ai/events \
  -H "Authorization: Bearer qt_agent_eyJhbGciOiJFUzI1NiIs..." \
  -H "Content-Type: application/json" \
  -d '{
    "action": "data:read:user_profile",
    "agent_id": "my-agent"
  }'
If successful, the response will not include the X-Quint-Deprecation header.

Phase 4: Cutover

After all customers have migrated (monitor for X-Quint-Deprecation header in access logs):
  1. Remove the _handle_legacy_auth() method from AuthMiddleware
  2. Remove the X-API-Key header check
  3. Return 401 for any request without Authorization: Bearer qt_*
  4. Remove api_key_hash column from public.customers (optional cleanup)

Comparison: Before and After

Request Flow — Before

Client → X-API-Key header → SHA-256 hash → DB lookup → customer_id
  • No agent identity
  • No RBAC
  • No delegation
  • No revocation (except deleting customer)
  • No audit trail of which agent performed which action

Request Flow — After

Client → Bearer qt_agent_* header
       → Prefix detection (0.01ms)
       → JWT ES256 verify (0.5ms)
       → Bloom filter revocation check (1-2ms)
       → Chain verification (0.01ms)
       → RBAC enforcement (0.1ms)
       → Event ingestion with agent_id attribution
  • Full agent identity and delegation chain
  • RBAC with glob pattern matching
  • O(1) revocation via bloom filter
  • Action signatures for non-repudiation
  • Session-scoped event counting
  • Human override flow for high-risk events

FAQ

Q: Will my existing integration break? No. X-API-Key auth continues to work during the transition. You’ll see a deprecation header in responses. Q: How long is the migration window? TBD — we’ll communicate a timeline. Expect at least 90 days after bootstrap. Q: What if I lose my app token? Contact support. A new app token can be generated, but the old one cannot be recovered. The old one will be revoked. Q: Can I use both auth methods simultaneously? Yes, but not in the same request. The middleware checks Authorization: Bearer qt_* first, then falls back to X-API-Key. Q: What happens to my API key after migration? It continues to work until Phase 4 cutover. After cutover, API keys are no longer accepted. Q: How do I handle token expiry? Agent tokens expire after 24 hours by default. Your integration should detect 401 responses and re-derive tokens from your bearer token (90-day TTL). Q: What if the bloom filter has a false positive on my valid token? You’ll receive a 401 with a revocation error. Re-derive the token from your bearer. This affects ~0.8% of tokens at most. Contact support if persistent.