You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Scope (expanded 2026-07-23): deliver the TOTAL package — a repo-wide rate-limiting audit and comprehensive coverage across every abuse surface in the API, not only the one endpoint originally named.
Background
There was no rate limiting anywhere in apps/api. POST /auth/request-password-reset (anonymous, takes an email, generates a token) was the flagged example — enumeration is closed (indistinguishable responses) but request-volume abuse (token churn, email-send amplification) was not. That endpoint is just the tip; the real fix is comprehensive.
Goal
Audit every endpoint, classify it, and apply an appropriate rate-limiting policy so nothing is unprotected.
Phase 1 — Audit
Enumerate every endpoint (route + verb, auth scope, operation class, abuse/cost risk) and produce a policy matrix at docs/guides/api-rate-limiting.md (endpoint class → policy → default limit/window/partition → the env var that tunes it). This doc is both the implementation spec and the operator reference.
expensive / sensitive (CSV/data exports, bulk operations, anything that sends email, heavy search/list, file uploads, fan-out admin actions): tighter per-user (and per-tenant where it protects a shared tenant resource).
global baseline: a per-IP safety net so every endpoint is at least minimally protected — excluding health/liveness/readiness probes, SSR document routes, and static/asset serving.
Requirements
Correct partition keys: per-IP, per-email, per-user/session, per-tenant as appropriate.
Real client IP behind the Traefik/Dokploy reverse proxy — ForwardedHeaders with a trusted-proxy allow-list (env-driven), so per-IP limiting keys on the actual client and X-Forwarded-For can't be spoofed to evade/poison the limiter.
RFC-7807 application/problem+json429 responses with a stable ResponseKey + translation-keyed message + Retry-After. Never 401/403.
Every limit configurable via AppEnvironment / env vars (tunable in production without a code change), added to .env.example and the compose files, with conservative-but-usable defaults.
Scope (expanded 2026-07-23): deliver the TOTAL package — a repo-wide rate-limiting audit and comprehensive coverage across every abuse surface in the API, not only the one endpoint originally named.
Background
There was no rate limiting anywhere in
apps/api.POST /auth/request-password-reset(anonymous, takes an email, generates a token) was the flagged example — enumeration is closed (indistinguishable responses) but request-volume abuse (token churn, email-send amplification) was not. That endpoint is just the tip; the real fix is comprehensive.Goal
Audit every endpoint, classify it, and apply an appropriate rate-limiting policy so nothing is unprotected.
Phase 1 — Audit
Enumerate every endpoint (route + verb, auth scope, operation class, abuse/cost risk) and produce a policy matrix at
docs/guides/api-rate-limiting.md(endpoint class → policy → default limit/window/partition → the env var that tunes it). This doc is both the implementation spec and the operator reference.Phase 2 — Comprehensive coverage
Policy buckets:
Requirements
application/problem+json429 responses with a stable ResponseKey + translation-keyed message +Retry-After. Never 401/403.AppEnvironment/ env vars (tunable in production without a code change), added to.env.exampleand the compose files, with conservative-but-usable defaults.Acceptance
*.Spec.cs) per class: at-cap allowed / over-cap → 429 RFC-7807 + Retry-After; per-user and per-email partition independence; an expensive endpoint proven tighter; health endpoints proven un-throttled; per-IP keys on the resolved client IP.just build-api+just test-api+just ci-formatgreen.Originally filed narrowly from the PR #806 review-fix loop (round 7). Broadened to the full package by owner request 2026-07-23.