rate-limit.middleware.ts
Cuts off API abuse — brute-force logins, scraping, expensive admin POSTs, runaway worker calls. Policies live in MongoDB and can be edited live from the admin app without redeploying.
The full design (policies, algorithms, stores, admin UI, default seeds, kill switches) is documented in API rate limiting. This page describes just the middleware glue in
src/middleware/rate-limit.middleware.ts.
Where it runs
Mounted globally after CORS and request-id, before any route:
app.use('*', cors(...))
app.use('*', requestIdMiddleware)
app.use('*', rateLimitMiddleware)What it does on every request
- Pulls the cached
RateLimitConfig(singleton, ~30s in-process cache). - Resolves the identity:
- prefers
c.get('userId')(fromauthMiddlewareif it ran), - else decodes a Bearer JWT in
Authorizationwithout running full auth, - else falls back to client IP (
CF-Connecting-IP→ lastX-Forwarded-For→'unknown'), - flags super admin (cached 30s) and internal worker (
x-internal-keytiming-safe equal toNOTIFICATION_WORKER_KEY).
- prefers
- Calls the policy engine to score the request against every matching policy.
- Sets
RateLimit-Limit,RateLimit-Remaining,RateLimit-Resetheaders. - Decides one of:
- Allowed (most cases) — calls
next(). With probabilityRATE_LIMIT_EVENT_SAMPLE_RATE(default 1%), writes a sampledallowedevent. - Shadow violation —
next()runs, but writes ashadow_violationevent so dashboards show what would have blocked. - Blocked — returns
429withRetry-After, aRATE_LIMITEDcode, the offendingpolicyid, andrequestId. Writes ablockedevent.
- Allowed (most cases) — calls
Fail-open
If anything throws (DB outage, malformed config), the middleware logs RATE_LIMITER_DEGRADED via logServerError(...) and still calls next(). The product would rather serve traffic than be taken down by its own limiter.
Factory for tests
createRateLimitMiddleware({ store, loadConfig, now, eventSampleRate, recordEvent }) lets unit tests swap the store (memory vs mongo), the config loader (snapshot in memory), and the clock. Tests live in src/__tests__/rate-limit-*.test.ts.
Related
- API rate limiting — admin UI, env vars, default policies
- Admin routes —
/api/v1/admin/rate-limitseditor services/rate-limit/— algorithms, stores, policy engine, config cachemodels/rate-limit-*.model.ts—RateLimitConfig,RateLimitCounter,RateLimitEvent,RateLimitRollup,RateLimitAudit