feat: rate-limit /generate/* endpoints (5 req/60s per IP) #336

Open
pook wants to merge 42 commits from feat/generate-rate-limit into main
Owner

Summary

  • Adds per-IP rate limiting middleware to all /generate/* endpoints (privacy-policy, terms-of-service, DPA)
  • Limits to 5 requests per 60-second window per client IP, returning 429 with { error: "Too many generation requests" } on excess
  • Uses X-Forwarded-For / X-Real-IP headers for accurate client identification behind reverse proxy
  • Returns standard RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, and Retry-After headers

Files changed

  • packages/api/src/middleware/rate-limit.ts — new in-memory sliding-window rate limiter middleware
  • packages/api/src/index.ts — import and apply rate limiter to /generate/* routes
  • packages/api/tests/unit/rate-limit.test.ts — 4 tests covering limit enforcement, 429 on 6th request, per-IP isolation, and header presence

Test plan

  • 4 unit tests pass: allows 5 requests, returns 429 on 6th, tracks IPs independently, includes standard headers
  • Pre-existing test suite unaffected (179/180 pass; 1 pre-existing failure in document-generator unrelated)

Closes #296

## Summary - Adds per-IP rate limiting middleware to all `/generate/*` endpoints (privacy-policy, terms-of-service, DPA) - Limits to 5 requests per 60-second window per client IP, returning 429 with `{ error: "Too many generation requests" }` on excess - Uses `X-Forwarded-For` / `X-Real-IP` headers for accurate client identification behind reverse proxy - Returns standard `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, and `Retry-After` headers ## Files changed - `packages/api/src/middleware/rate-limit.ts` — new in-memory sliding-window rate limiter middleware - `packages/api/src/index.ts` — import and apply rate limiter to `/generate/*` routes - `packages/api/tests/unit/rate-limit.test.ts` — 4 tests covering limit enforcement, 429 on 6th request, per-IP isolation, and header presence ## Test plan - [x] 4 unit tests pass: allows 5 requests, returns 429 on 6th, tracks IPs independently, includes standard headers - [x] Pre-existing test suite unaffected (179/180 pass; 1 pre-existing failure in document-generator unrelated) Closes #296
feat: add rate limiting to /generate/* endpoints (5 req/60s per IP)
Some checks are pending
CI Quality Gate / Lint / Typecheck / Test / Build (pull_request) Waiting to run
fdb3802dbc
Prevents abusive clients from burning through OpenAI API credits by
limiting generation requests to 5 per minute per client IP. Uses
X-Forwarded-For for accurate IP detection behind reverse proxy.
Includes standard RateLimit-* headers and Retry-After on 429 responses.

Closes #296

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
feat: issue #330 stale-issue-296-8h-without-rate-limiting (agent task agent-ta)
Some checks failed
CI Quality Gate / Lint / Typecheck / Test / Build (pull_request) Has been cancelled
3f117f9d94
Some checks failed
CI Quality Gate / Lint / Typecheck / Test / Build (pull_request) Has been cancelled
This pull request has changes conflicting with the target branch.
  • .forgejo/workflows/ci.yml
  • packages/api/src/db/schema.ts
  • packages/api/src/index.ts
  • packages/api/src/middleware/rate-limit.ts
  • packages/api/src/middleware/security-headers.ts
  • packages/api/src/routes/generate-tos.ts
  • packages/api/src/routes/generate.ts
  • packages/api/src/routes/health.ts
  • packages/api/src/routes/questionnaire.ts
  • packages/api/src/services/document-generator.ts
  • packages/api/src/services/llm.ts
  • packages/api/src/templates/index.ts
  • packages/shared/src/types.ts
  • packages/web/src/app/questionnaire/page.tsx
  • packages/web/src/components/documents/DocumentList.tsx
  • packages/web/src/components/questionnaire/ReviewStep.tsx
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/generate-rate-limit:feat/generate-rate-limit
git switch feat/generate-rate-limit
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pook/compliancebot!336
No description provided.