Aller au contenu principal

API Key Rotation

Rotate API keys with zero downtime using STOA's grace period mechanism — both old and new keys work during the transition window.

How It Works

When you rotate a key, STOA doesn't immediately invalidate the old one. Instead, it creates a grace period where both keys are valid:

PhaseOld KeyNew KeyDuration
Before rotationValidN/A
Grace periodValidValid1-168 hours (default: 24h)
After grace periodInvalidValidPermanent

Step-by-Step Rotation

Configure your environment

The examples below use environment variables. Set them for your STOA instance:

export STOA_API_URL="https://api.gostoa.dev"       # Replace with your domain
export STOA_AUTH_URL="https://auth.gostoa.dev" # Keycloak OIDC provider
export STOA_GATEWAY_URL="https://mcp.gostoa.dev" # MCP Gateway endpoint

Self-hosted? Replace gostoa.dev with your domain.

1. Rotate the Key

curl -X POST "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/rotate-key" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"grace_period_hours": 24
}'

Response:

{
"subscription_id": "sub-uuid-123",
"new_api_key": "stoa_sk_e7f8g9h0i1j2k3l4m5n6o7p8q9r0s1t2",
"new_api_key_prefix": "stoa_sk_e7f8",
"old_key_expires_at": "2026-02-14T10:00:00Z",
"grace_period_hours": 24,
"rotation_count": 3
}
Save the New Key

The new_api_key is shown only once. Store it securely before proceeding.

2. Update Your Applications

Deploy the new key to your applications. During the grace period, both keys work:

# Old key — still works during grace period
curl "${STOA_GATEWAY_URL}/apis/acme/billing/v1/invoices" \
-H "X-API-Key: stoa_sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"

# New key — works immediately
curl "${STOA_GATEWAY_URL}/apis/acme/billing/v1/invoices" \
-H "X-API-Key: stoa_sk_e7f8g9h0i1j2k3l4m5n6o7p8q9r0s1t2"

3. Verify the Rotation

Check the rotation status:

curl "${STOA_API_URL}/v1/subscriptions/${SUB_ID}/rotation-info" \
-H "Authorization: Bearer ${TOKEN}"

Response:

{
"subscription_id": "sub-uuid-123",
"api_key_prefix": "stoa_sk_e7f8",
"has_previous_key": true,
"previous_key_expires_at": "2026-02-14T10:00:00Z",
"rotation_count": 3,
"last_rotated_at": "2026-02-13T10:00:00Z"
}

4. Wait for Grace Period to Expire

After the grace period expires, the old key is automatically invalidated. No action needed.

Grace Period Guidelines

ScenarioRecommended Grace Period
Single application, quick deploy1-4 hours
Multiple services, rolling deploy12-24 hours
Partner integrations, external consumers48-72 hours
Compliance rotation (scheduled)24 hours
Emergency rotation (key compromised)1 hour
Emergency Rotation

If a key is compromised, use a 1-hour grace period. This gives your team just enough time to deploy the new key while minimizing the exposure window.

Gateway Caching

The gateway caches API key validation results to reduce latency:

SettingValue
Cache TTL5 minutes
Max entries10,000
InvalidationAutomatic on rotation

When you rotate a key:

  1. The Control Plane notifies the gateway
  2. The gateway invalidates the cache entry for the old key
  3. The next request re-validates against the Control Plane
  4. The new validation result is cached

Worst case: A rotated key may still be cached for up to 5 minutes after the grace period expires. For immediate invalidation, the admin can clear the gateway cache:

curl -X POST "${STOA_GATEWAY_URL}/admin/cache/clear" \
-H "Authorization: Bearer ${ADMIN_TOKEN}"

Rotation via Console

  1. Navigate to Subscriptions in the Console
  2. Find the subscription to rotate
  3. Click the Rotate Key button
  4. Set the grace period (default: 24 hours)
  5. Copy the new key from the confirmation dialog

Monitoring Rotations

Track rotation health via the subscription's rotation_count and last_rotated_at fields:

# List all subscriptions with rotation info
curl "${STOA_API_URL}/v1/subscriptions/tenant/${TENANT_ID}" \
-H "Authorization: Bearer ${TOKEN}" | \
jq '.subscriptions[] | {api_key_prefix, rotation_count, last_rotated_at}'

Rotation Best Practices

  • Rotate regularly — Every 90 days for production keys
  • Automate rotation — Use CI/CD pipelines or scheduled scripts
  • Monitor rotation count — Unusual spikes may indicate issues
  • Test with grace period — Always use a grace period in production
  • Audit trail — Every rotation is logged with timestamp and user

Troubleshooting

ProblemCauseFix
Old key rejected during grace periodGrace period expiredCheck old_key_expires_at timestamp
New key returns 401Subscription not activeVerify subscription status is active
Both keys rejectedSubscription suspended/revokedCheck subscription status
Key rotation returns 404Wrong subscription IDVerify the subscription exists