Febasi Docs
Reference

Rate limits

Default budgets, per-route overrides, brute-force protection, and how to handle 429s.

The Auth API rate-limits requests with @fastify/rate-limit. The defaults are generous for normal usage and aggressive on the routes attackers care about.

Default budget

ScopeBudget
Global100 req/min per IP
POST /login5 req/min per IP

Other routes inherit the global budget unless overridden in the service config. Authenticated and unauthenticated traffic both count against the same per-IP bucket.

Hitting the limit

HTTP/1.1 429 Too Many Requests
Retry-After: 42
{ "success": false, "error": "Rate limit exceeded", "code": "RATE_LIMIT_EXCEEDED" }

Retry-After is in seconds. Clients should wait at least that long before retrying — anything faster will be denied again.

Why login is so tight

Five requests per minute is enough for legitimate retries (typo, wrong caps lock) and far below what's needed to brute-force a typical password. It combines with the dummy-bcrypt timing-attack mitigation and the tenant security metrics to make password attacks expensive and noisy.

Brute-force detection

The Auth API exposes two metric endpoints that surface attack patterns:

GET /api/v1/tenants/me/metrics/security

Returns:

  • 24h login summary — total, successful, failed, success rate.
  • 5-minute window — failed attempts and unique IPs.
  • IP analysis — top offenders, IPs with ≥ 5 failures in 24 hours flagged as suspicious.

The threshold for "possible brute force" is >10 failures in 5 minutes. Wire alerts on top of these numbers — the Auth API does not page you, but it gives you the inputs to do so.

Distributed deployments

The default @fastify/rate-limit store is in-memory per process. For a multi-instance deployment behind a load balancer, you have two choices:

  1. Sticky sessions — same IP always lands on the same process. Cheap, keeps the in-memory store correct.
  2. Redis store — switch the limiter to Redis-backed. The Auth API ships with ioredis and BullMQ already installed; the wiring is a small config change in src/server.ts.

For high-volume tenants, the platform team can lift the budget per-tenant. Open a ticket with traffic projections and the desired budget.

Trust proxy

The service runs with trustProxy: true, so it honors X-Forwarded-For when the request arrives via a reverse proxy. Make sure your proxy strips or sanitizes that header for untrusted clients — the Auth API trusts what it sees.

What clients should do

Honor Retry-After

Always. It's the minimum safe wait. Don't add fixed jitter on top — the server is already telling you the right answer.

Backoff on repeated 429s

If two consecutive Retry-Afters are needed, your traffic shape is the problem. Drop to a fraction of your usual rate.

Separate keys per integration

For Client Keys, isolate workloads. A misbehaving exporter shouldn't starve the production traffic that shares its key.

Watch the security metrics

For tenants you operate, periodically poll /tenants/me/metrics/security. The 5-minute window is the most useful real-time signal.

On this page