Skip to content

security: add rate limiting (Upstash sliding window) to abusable paths (PR 1.5) - #14

Merged
Jeston10 merged 2 commits into
milestone/p1-securityfrom
security/rate-limiting
Sep 20, 2026
Merged

Jeston10 merged 2 commits into
milestone/p1-securityfrom
security/rate-limiting

Conversation

@Jeston10

Copy link
Copy Markdown
Owner

Summary

PR 1.5 of docs/MILESTONES.md (Phase 1). SECURITY §2.5 / GUARDRAILS B7.

  • config/limits.ts — the authoritative limits + the verified Upstash free tier (500k commands/month, 256 MB, 10 GB, no card) — R3 for Upstash done
  • server/ratelimit/ — RateLimiter interface; Upstash sliding-window adapter; in-memory limiter for dev/CI/tests; enforceLimit → AppError('RATE_LIMITED') with reset time. Production refuses to boot without Upstash
  • Keys: IPs hashed before they touch Redis; uids namespaced
  • Applied: signIn/signUp (IP), createFeedback/updateProfile (uid), Vapi webhook (uid → 429)

Type

  • security

Verification

  • pnpm lint ✔ · typecheck ✔ · knip ✔ · vitest 55/55 (window semantics, per-limit isolation, hashing, actions short-circuit on limit) · next build ✔
  • Live: the app's limiter against the real Upstash database — 1..10 ok, 11 DENIED, 12 DENIED; production server boots on the Upstash adapter (no fallback warning)

Server checklist

  • Limits on every abusable entry point that exists today; later endpoints listed in SECURITY §2.5 with their planned values
  • No raw IPs stored; no PII in keys

Risk watch-list

  • Rows checked: R3 (Upstash verified from the pricing page and recorded; remaining vendors at their sign-up), R24 (global caps come with the quota service in P2.x)

Docs

  • docs/TECH_STACK.md (verified limits), docs/SECURITY.md §2.5, docs/RISKS.md, .env.example

Config note: add UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN to Vercel before the Phase 1 release — production will not start without them.

🤖 Generated with Claude Code

PR 1.5 of docs/MILESTONES.md (SECURITY §2.5, GUARDRAILS B7).

- config/limits.ts: authoritative limits (sign-in/up 10 per 10 min by
  IP; interview create 5/h, feedback 10/day, profile update 20/h by
  uid) and the verified Upstash free tier (500k commands/month, 256 MB,
  10 GB, no card — RISKS R3).
- server/ratelimit: RateLimiter interface; Upstash adapter
  (@upstash/ratelimit sliding window, one limiter per limit name);
  in-memory limiter for dev/CI/tests; enforceLimit throws
  AppError('RATE_LIMITED') with the reset time in the message.
  Production refuses to boot without Upstash (config/env.ts).
- keys: IPs hashed before becoming Redis keys; uid namespaced.
- Applied to signIn/signUp (IP), createFeedback/updateProfile (uid),
  and the Vapi webhook (uid → 429).

Verified: pnpm lint, typecheck, knip, vitest 55/55 (sliding-window
semantics, per-name isolation, key hashing, actions return the limit
message and skip work); next build; live burst against the real
Upstash database: 10 allowed, 11th and 12th denied.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 20, 2026 10:58
@vercel

vercel Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
just-prep-ai-interview-z3cv Error Error Sep 20, 2026 11:06am UTC

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Jeston10
Jeston10 merged commit a49ac70 into milestone/p1-security Sep 20, 2026
6 of 7 checks passed
@Jeston10
Jeston10 deleted the security/rate-limiting branch September 20, 2026 11:26

This branch had an error being deployed

1 failed deployment
Preview — f7259981 Deployed Sep 20, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants