Skip to content

security: per-user rate limits + input length caps #40

Description

@jonmatum

Priority: P0 — launch blocker
Parent: #34
Promotes: D-3 from #32

Context

API Gateway throttling is global (100 burst / 50 rate) and does not bind per Cognito user. nodeChat passes user messages directly into Bedrock with no max length, and capture enforces only text.length >= 10 with no upper bound. A single authenticated user can trigger Bedrock spend unbounded.

Requirements

Input length caps (src/shared/validate.ts or per-handler)

  • Capture text: hard cap 50 000 chars, return 413 above
  • Node chat message: hard cap 10 000 chars, return 413 above
  • Enforce on both the handler and via API Gateway request validator where possible

Per-user rate limits

  • Per-user usage plan or a DynamoDB-backed token-bucket in a shared Lambda middleware
  • Thresholds (starting points, tune later):
    • POST /capture: 20 / hour / user
    • POST /capture chat action: 60 / hour / user
    • Write endpoints total: 200 / day / user
  • 429 response includes Retry-After

WAF additions

  • Add AWSManagedRulesAnonymousIpList (optional — evaluate false-positive rate)
  • Add a rate-based rule at the IP level (e.g. 2 000 requests / 5 min)

Acceptance criteria

  • Synthetic test: 21 captures in one hour from a single user yields a 429 on the 21st
  • Synthetic test: 50 001-char capture returns 413 without calling Bedrock
  • CloudWatch metric emitted per rate-limit rejection for observability

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions