From 39593f228464b259b7fa9556fdbf1f7a0b7a0014 Mon Sep 17 00:00:00 2001 From: Edward Oliveira Date: Wed, 20 May 2026 14:34:59 -0300 Subject: [PATCH] Remove whitelist references from rate limiter plan docs Co-Authored-By: Claude Sonnet 4.6 --- plan/RATE-LIMITER-PLAN.md | 5 ++--- plan/rate-limiter-v2.md | 11 ++--------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/plan/RATE-LIMITER-PLAN.md b/plan/RATE-LIMITER-PLAN.md index c881d1122..9c81f1479 100644 --- a/plan/RATE-LIMITER-PLAN.md +++ b/plan/RATE-LIMITER-PLAN.md @@ -668,7 +668,6 @@ Decision flow inside `RateLimitMiddleware.__call__()` / `_evaluate()`: 0. /api/ path AND consumer daily/weekly quota exceeded? → 429 reason=quota_daily / quota_weekly (per-consumer: auth users by pk, anon by masked IP; fail-open when Redis unavailable) -1. IP in allowlist? → pass (no further checks) 1a. UA matches BOT_UA_FRAGMENTS list? → 429 reason=known_ua 1b. UA token hash in rl:bot:ua:blocked SET? → 429 reason=redis_ua 2. Anonymous AND IP in rl:ip:{ip}:blocked? → 429 reason=ip_blocked @@ -755,7 +754,7 @@ Roll out to canary pods first; promote check-by-check in order of false-positive | 3rd | `ip_blocked` | Marker set by prior proven-bad requests | Zero | Fast-path only, no new blocks created | | 4th | `ip_rate` | Rolling IP counter ≥ 120/min | Low | Threshold calibrated from canary logs | | 5th | `suspicious_headers` | No Accept-Language **and** no Accept | Medium | Confirmed no legitimate clients omit both headers | -| 6th | `ua_rotation` (ns/window) | NS/IP clock-aligned bucket ≥ 120 | Medium | NAT IP allowlist in place (see Open Questions) | +| 6th | `ua_rotation` (ns/window) | NS/IP clock-aligned bucket ≥ 120 | Medium | | | 7th | `404_scan` | Anonymous IP accumulates ≥ 20 404s/min | Low | Catches path probes without known extensions | ### Decorator migration @@ -1494,6 +1493,6 @@ changes. | # | Question | Status | Blocks | |---|----------|--------|--------| | 1 | Does Chrome/98.0.4758 impersonator appear consistently in nginx access logs? | Needs investigation | UA block safety | -| 2 | Which legislative house IPs can be pre-allowlisted in `RATE_LIMIT_ALLOWLIST_IPS`? | No list yet — obtain in the future. Setting is **optional / future**. | Enforcement safety for NAT users | + | 3 | `CONN_MAX_AGE` tuning | Currently **300 s** (`sapl/settings.py`). Evaluate whether to reduce given worker recycling at 400 MB. | Gunicorn tuning | | 4 | WebSocket voting panel priority | Separate project. Resumes after Redis is on k8s, bot siege addressed, and OOM pressure reduced. | Phase 5 sequencing | diff --git a/plan/rate-limiter-v2.md b/plan/rate-limiter-v2.md index cd2973125..6236663c8 100644 --- a/plan/rate-limiter-v2.md +++ b/plan/rate-limiter-v2.md @@ -400,7 +400,7 @@ mv /tmp/GeoLite2-ASN_*/GeoLite2-ASN.mmdb /etc/nginx/geoip/GeoLite2-ASN.mmdb nginx -s reload ``` -**Tradeoff**: Blocks datacenter ASNs where bots originate. May over-block VPN users and developers on cloud instances — mitigate with a per-namespace IP allowlist once available (see Open Question 2). +**Tradeoff**: Blocks datacenter ASNs where bots originate. May over-block VPN users and developers on cloud instances. --- @@ -1108,12 +1108,6 @@ RATE_LIMITER_RATE = config('RATE_LIMITER_RATE', defa RATE_LIMITER_RATE_AUTHENTICATED = config('RATE_LIMITER_RATE_AUTHENTICATED', default='120/m') RATE_LIMITER_RATE_BOT = config('RATE_LIMITER_RATE_BOT', default='5/m') -# Optional / future — see Open Question 2 -RATE_LIMIT_ALLOWLIST_IPS = config( - 'RATE_LIMIT_ALLOWLIST_IPS', - default='', - cast=lambda v: [x.strip() for x in v.split(',') if x.strip()] -) ``` --- @@ -1128,7 +1122,7 @@ Roll out to canary pods first; promote check-by-check in order of false-positive | 2nd | `ip_blocked` | Zero | Key only set by prior proven-bad requests | | 3rd | `ip_rate` | Low | Threshold calibrated from canary logs | | 4th | `suspicious_headers` | Medium | Confirmed no legitimate clients omit all 3 headers | -| 5th | `ua_rotation` (ns/window) | Medium | NAT IP allowlist in place (see Open Question 2) | +| 5th | `ua_rotation` (ns/window) | Medium | | --- @@ -1220,7 +1214,6 @@ class PesquisarMateriaView(FilterView): | # | Question | Status | Blocks | |---|---|---|---| | 1 | Does Chrome/98.0.4758 impersonator appear consistently in nginx access logs? | Needs investigation | Phase 0 UA block safety | -| 2 | Which legislative house IPs can be pre-allowlisted in `RATE_LIMIT_ALLOWLIST_IPS`? | We don't have this list yet — plan to obtain in the future. Setting is **optional / future**. | Phase 2 enforcement safety | | 3 | Dockerfile scope | Single image for all tenants (confirmed). All path-based Redis keys include `{ns}`. | — | | 4 | WebSocket voting panel priority | Separate project. Resumes after Redis is on k8s, bot siege addressed, and OOM pressure reduced. | Phase 5 sequencing | | 5 | `CONN_MAX_AGE` tuning | Currently **300 s** (`sapl/settings.py:272`). Evaluate whether to reduce given worker recycling at 400 MB. | Phase 0 tuning |