- agent.py: Fail closed when gateway lookup returns None instead of
silently dropping the organization filter (cross-tenant board leak)
- board_webhooks.py: Read request body via streaming chunks so an
oversized payload is rejected before it is fully loaded into memory
- rate_limit.py: Add periodic sweep of expired keys to prevent
unbounded memory growth from inactive clients
- test_rate_limit.py: Add test for the new sweep behavior
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Agent token auth performed O(n) PBKDF2 operations per request with no
rate limiting, enabling CPU exhaustion attacks. Webhook ingest had no
rate limits either. Add an in-memory token-bucket rate limiter:
- Agent auth: 20 requests/minute per IP
- Webhook ingest: 60 requests/minute per IP
Includes unit tests for the rate limiter.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>