Rate Limiting - C-Suite
Visão Geral
Este documento descreve o sistema de rate limiting padronizado para proteger APIs contra abuso, com suporte a limites por IP, usuário, organização e endpoint.
Módulo de Rate Limiting
Localização
O módulo principal está em: common_rate_limit.py (raiz do projeto)
Características
- Limites configuráveis: Por minuto, hora e dia
- Múltiplos identificadores: IP, usuário, organização
- Redis ou memória: Suporte a storage distribuído (Redis) ou local (memória)
- Middleware FastAPI: Rate limiting automático em todos os endpoints
- Decorator: Rate limiting por endpoint específico
- Headers padrão: Headers HTTP padrão de rate limiting
Uso Básico
1. Middleware Global
from fastapi import FastAPI
from common_rate_limit import create_rate_limit_middleware
app = FastAPI()
# Adiciona rate limiting global (60 requests/minuto)
app.middleware("http")(create_rate_limit_middleware(requests_per_minute=60))
@app.get("/api/endpoint")
async def endpoint():
return {"data": "..."}
2. Rate Limiting por Endpoint
from common_rate_limit import rate_limit
@app.get("/api/sensitive")
@rate_limit(requests_per_minute=10, requests_per_hour=100)
async def sensitive_endpoint():
return {"data": "sensitive"}
3. Rate Limiting por Usuário
from common_rate_limit import create_rate_limit_middleware
from common_auth import get_current_user
def get_user_identifier(request: Request) -> Optional[str]:
"""Extrai user_id do request"""
# Se autenticação estiver configurada, pode extrair do token
# Por enquanto, retorna None (usa IP)
return None
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=60,
identifier_func=get_user_identifier
)
)
4. Configuração via Variáveis de Ambiente
# Limites padrão
RATE_LIMIT_PER_MINUTE=60
RATE_LIMIT_PER_HOUR=1000
RATE_LIMIT_PER_DAY=10000
# Redis (para múltiplas instâncias)
RATE_LIMIT_USE_REDIS=true
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
REDIS_PASSWORD=
Estratégias de Rate Limiting
Por IP (Padrão)
# Limita por IP do cliente
app.middleware("http")(create_rate_limit_middleware(requests_per_minute=60))
Uso: Proteção básica contra abuso
Por Usuário
def get_user_id(request: Request) -> Optional[str]:
# Extrai user_id do token JWT ou session
if hasattr(request.state, "user_id"):
return str(request.state.user_id)
return None
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=100,
identifier_func=get_user_id
)
)
Uso: Limites personalizados por usuário autenticado
Por Organização
def get_org_id(request: Request) -> Optional[str]:
# Extrai org_id do token ou path
if hasattr(request.state, "org_id"):
return f"org:{request.state.org_id}"
return None
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=1000, # Limite maior para organização
identifier_func=get_org_id
)
)
Uso: Limites compartilhados por organização
Por Endpoint
# Limites diferentes por endpoint
@app.get("/api/public")
@rate_limit(requests_per_minute=100)
async def public_endpoint():
return {"data": "public"}
@app.get("/api/expensive")
@rate_limit(requests_per_minute=10, requests_per_hour=100)
async def expensive_endpoint():
return {"data": "expensive"}
Uso: Proteger endpoints específicos com limites mais restritivos
Headers HTTP
O módulo adiciona automaticamente headers padrão de rate limiting:
X-RateLimit-Limit: Limite total de requestsX-RateLimit-Remaining: Requests restantes no períodoX-RateLimit-Reset: Timestamp de quando o limite será resetadoRetry-After: Segundos até poder fazer nova request (quando excedido)
Exemplo de Resposta
Request permitido:
HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1701436800
Rate limit excedido:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1701436800
Retry-After: 30
{
"error": "Rate limit exceeded",
"message": "Too many requests. Limit: 60 requests per minute",
"retry_after": 30
}
Storage
Redis (Recomendado para Produção)
Usa Redis para storage distribuído, permitindo rate limiting consistente em múltiplas instâncias:
# Configuração automática via env vars
RATE_LIMIT_USE_REDIS=true
REDIS_HOST=redis.example.com
REDIS_PORT=6379
Vantagens:
- Funciona com múltiplas instâncias
- Persistência entre restarts
- Melhor performance
Memória Local (Fallback)
Se Redis não estiver disponível, usa memória local:
RATE_LIMIT_USE_REDIS=false
Limitações:
- Não funciona com múltiplas instâncias
- Perde contadores ao reiniciar
- Usa memória do processo
Configuração por App
4c Decision API
from common_rate_limit import create_rate_limit_middleware
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=100, # Limite maior para API de decisão
requests_per_hour=5000
)
)
csuite-executive
from common_rate_limit import create_rate_limit_middleware
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=60,
requests_per_hour=1000
)
)
4c-suite
from common_rate_limit import create_rate_limit_middleware
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=30, # Limite menor para orquestrador
requests_per_hour=500
)
)
Integração com Autenticação
from common_rate_limit import create_rate_limit_middleware
from common_auth import get_current_user
def get_user_identifier(request: Request) -> Optional[str]:
"""Extrai user_id para rate limiting"""
try:
# Tenta obter user_id do token JWT
# (requer middleware de autenticação configurado)
if hasattr(request.state, "user_id"):
return str(request.state.user_id)
except Exception:
pass
return None
app.middleware("http")(
create_rate_limit_middleware(
requests_per_minute=60,
identifier_func=get_user_identifier
)
)
Limites Recomendados
Endpoints Públicos
- Por IP: 60 requests/minuto, 1000/hora
- Por usuário autenticado: 100 requests/minuto, 5000/hora
Endpoints Autenticados
- Por usuário: 100 requests/minuto, 5000/hora
- Por organização: 1000 requests/minuto, 50000/hora
Endpoints Pesados (ML, Processamento)
- Por usuário: 10 requests/minuto, 100/hora
- Por organização: 100 requests/minuto, 1000/hora
Endpoints Administrativos
- Por usuário admin: 200 requests/minuto, 10000/hora
- Por IP: 30 requests/minuto (backup)
Boas Práticas
- Use Redis em produção: Permite rate limiting consistente
- Configure limites apropriados: Balance entre segurança e usabilidade
- Monitore rate limits: Alerte quando limites são frequentemente excedidos
- Documente limites: Informe usuários sobre limites de API
- Diferencie por tipo de endpoint: Endpoints pesados devem ter limites menores
- Considere whitelist: Para IPs confiáveis ou usuários premium
Troubleshooting
Rate limit muito restritivo
- Aumente
RATE_LIMIT_PER_MINUTE - Verifique se múltiplos limites não estão conflitando
- Considere limites diferentes por endpoint
Rate limit não funciona com múltiplas instâncias
- Certifique-se de que
RATE_LIMIT_USE_REDIS=true - Verifique conexão com Redis
- Verifique se todas as instâncias usam o mesmo Redis
Headers não aparecem
- Verifique se middleware foi adicionado corretamente
- Verifique se response não está sendo modificado por outro middleware
- Verifique logs para erros
Próximos Passos
- ✅ Módulo de rate limiting criado
- ⏳ Integrar em todos os apps
- ⏳ Configurar limites apropriados por app/endpoint
- ⏳ Monitorar métricas de rate limiting
- ⏳ Implementar whitelist para IPs/usuários confiáveis
- ⏳ Adicionar rate limiting no Traefik (camada de API Gateway)