SEQN Auth Rate-Limit Policy

The Silver Auth API includes a built-in in-process request limiter that returns 429 rate_limited with Retry-After. Current service defaults are 240 requests per 60 seconds for the app-level bucket. Treat this as a safety floor, not the complete SaaS abuse-control layer.

The current runtime does not expose production .env knobs for the app limiter. Do not add fake rate-limit variables to .env until config.mjs and server.mjs read them. Use Caddy, a CDN/WAF, or an upstream reverse proxy for route-specific tuning today.

Policy goals

  • Protect sign-in, sign-up, backend-key health, setup-context, admin, and webhook routes from bursts.
  • Preserve enough room for normal SDK startup checks and local development.
  • Return structured errors with Retry-After instead of timing out.
  • Avoid blocking whole customer organizations because one client is noisy.

Current app behavior

  • Default window: 60_000 ms.
  • Default maximum: 240 requests per window.
  • Error code: rate_limited.
  • HTTP status: 429.
  • Header: Retry-After.
  • Scope: in-process memory, so each API process has its own bucket.

Because the bucket is in memory, use a shared edge limiter if the API is horizontally scaled.

Recommended edge limits

| Surface | Suggested policy | Notes | | --- | --- | --- | | /healthz | 60 requests/minute per source | Synthetic checks should stay far below this. | | /v1/config | 120 requests/minute per source | Public and safe, but still cacheable. | | /v1/client/config | 120 requests/minute per source and publishable key | Browser SDK startup path. | | /v1/setup/agent-context | 30 requests/minute per source and publishable key | Used by IDE/AI agents, not hot path. | | /v1/backend/application | 60 requests/minute per source and secret-key prefix | Server boot and health checks. | | /auth/login and /auth/callback | 30 requests/minute per source | Protect OIDC handoff and callback loops. | | Admin mutation routes | 60 requests/minute per authenticated admin | Keep room for console use. | | Webhook test/delivery routes | 60 requests/minute per org | Protect downstream receivers. |

Tuning procedure

1. Confirm whether traffic is legitimate, broken-client retry behavior, or abuse. 2. Check the route and identity shape in logs before changing a global limit. 3. Raise edge limits only for a route, key, org, or trusted source when possible. 4. Keep the app limiter enabled as the final circuit breaker. 5. Alert on sustained 429 above the normal baseline, not isolated bursts. 6. If a customer is blocked by a plan limit, use the subscription runbook instead of rate-limit changes.

Emergency abuse response

  • Add a temporary edge block for a confirmed hostile source.
  • If the source is a customer backend, contact the customer through the support channel and ask them to back off to Retry-After.
  • Rotate exposed sk_live_ or whsec_ secrets if abuse follows a single secret prefix.
  • Review admin audit logs for suspicious project, user, role, webhook, or secret-rotation changes.
  • Capture the rule, reason, timestamp, and owner in the incident notes.

Future env knobs

If production env tuning is added later, prefer explicit names and document them here before adding them to .env.example:


RATE_LIMIT_ENABLED=true
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX=240

These names are reserved documentation placeholders only until the service reads them.