Browse Source

Remove whitelist references from rate limiter plan docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
rate-limiter-2026
Edward Ribeiro 1 week ago
parent
commit
39593f2284
  1. 5
      plan/RATE-LIMITER-PLAN.md
  2. 11
      plan/rate-limiter-v2.md

5
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 |

11
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 |

Loading…
Cancel
Save