Summary
backend/auth/src/services/otp.py:39 enforces a per-email cooldown but nothing per-IP. An attacker spraying emails across accounts hits no limit. Same for Register and Login.
Gateway issue PlaceBrain/gateway#7 covers the outer wall; this is defence-in-depth at the gRPC layer, useful if the gateway is bypassed in a future deployment (e.g. mTLS sidecar).
Changes
backend/auth/src/infra/grpc/interceptors.py — new rate-limit interceptor keyed off peer address passed via gateway metadata (x-peer-addr).
- Buckets in Redis (re-use the devices redis instance):
10/min Login, 5/min Register, 3/min SendOtp.
- Exceeded → return
RESOURCE_EXHAUSTED.
- Config via env:
AUTH__RL__LOGIN=10/minute etc.
Verification
- 11 logins from same IP in under a minute — 11th returns
RESOURCE_EXHAUSTED.
- Different IPs remain independent.
Summary
backend/auth/src/services/otp.py:39enforces a per-email cooldown but nothing per-IP. An attacker spraying emails across accounts hits no limit. Same forRegisterandLogin.Gateway issue PlaceBrain/gateway#7 covers the outer wall; this is defence-in-depth at the gRPC layer, useful if the gateway is bypassed in a future deployment (e.g. mTLS sidecar).
Changes
backend/auth/src/infra/grpc/interceptors.py— new rate-limit interceptor keyed off peer address passed via gateway metadata (x-peer-addr).10/minLogin,5/minRegister,3/minSendOtp.RESOURCE_EXHAUSTED.AUTH__RL__LOGIN=10/minuteetc.Verification
RESOURCE_EXHAUSTED.