Rate Limiting

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

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:

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

Endpoints Autenticados

Endpoints Pesados (ML, Processamento)

Endpoints Administrativos

Boas Práticas

  1. Use Redis em produção: Permite rate limiting consistente
  2. Configure limites apropriados: Balance entre segurança e usabilidade
  3. Monitore rate limits: Alerte quando limites são frequentemente excedidos
  4. Documente limites: Informe usuários sobre limites de API
  5. Diferencie por tipo de endpoint: Endpoints pesados devem ter limites menores
  6. Considere whitelist: Para IPs confiáveis ou usuários premium

Troubleshooting

Rate limit muito restritivo

  1. Aumente RATE_LIMIT_PER_MINUTE
  2. Verifique se múltiplos limites não estão conflitando
  3. Considere limites diferentes por endpoint

Rate limit não funciona com múltiplas instâncias

  1. Certifique-se de que RATE_LIMIT_USE_REDIS=true
  2. Verifique conexão com Redis
  3. Verifique se todas as instâncias usam o mesmo Redis

Headers não aparecem

  1. Verifique se middleware foi adicionado corretamente
  2. Verifique se response não está sendo modificado por outro middleware
  3. Verifique logs para erros

Próximos Passos

  1. ✅ Módulo de rate limiting criado
  2. ⏳ Integrar em todos os apps
  3. ⏳ Configurar limites apropriados por app/endpoint
  4. ⏳ Monitorar métricas de rate limiting
  5. ⏳ Implementar whitelist para IPs/usuários confiáveis
  6. ⏳ Adicionar rate limiting no Traefik (camada de API Gateway)

🔊 Text-to-Speech

1.0x
1.0
Pronto para reproduzir