Rate Limiting¶
Sistema de rate limiting per-user com 4 políticas configuráveis, aplicado nos endpoint groups via .RequireRateLimiting().
Visão Geral¶
O rate limiting protege a API contra abuso, limitando o número de requisições por usuário (ou IP) em janelas de tempo. A identificação do usuário segue a cadeia: JWT sub claim, IP remoto, "anonymous".
Resposta ao exceder o limite: HTTP 429 Too Many Requests
Arquivos Principais¶
| Arquivo | Descrição |
|---|---|
src/Ciba.Shared/Constants/RateLimitPolicies.cs |
Constantes com nomes das políticas |
src/Ciba.Api/Extensions/ServiceCollectionExtensions.cs |
Configuração das 4 políticas no AddApiRateLimiting() |
Políticas¶
Api (Geral)¶
| Propriedade | Valor |
|---|---|
| Constante | RateLimitPolicies.Api ("api") |
| Algoritmo | Sliding Window |
| Janela | 1 minuto |
| Limite | 100 requisições |
| Segmentos | 6 (janelas de 10s) |
| Fila | 0 (rejeita imediatamente) |
| Partição | JWT sub / IP / "anonymous" |
Aplicada na maioria dos endpoint groups: - Agents, Conversations, Instances, Tenants, Users, LLM, SystemSettings
Login¶
| Propriedade | Valor |
|---|---|
| Constante | RateLimitPolicies.Login ("login") |
| Algoritmo | Fixed Window |
| Janela | 5 minutos |
| Limite | 10 tentativas |
| Fila | 0 |
| Partição | IP apenas (JWT indisponível no login) |
Aplicada exclusivamente no endpoint de autenticação.
Llm (Playground)¶
| Propriedade | Valor |
|---|---|
| Constante | RateLimitPolicies.Llm ("llm") |
| Algoritmo | Fixed Window |
| Janela | 1 minuto |
| Limite | 10 requisições |
| Fila | 0 |
| Partição | JWT sub / IP / "anonymous" |
Aplicada nos endpoints de Playground (chat, transcrição, descrição de imagem).
SendMessage¶
| Propriedade | Valor |
|---|---|
| Constante | RateLimitPolicies.SendMessage ("send-message") |
| Algoritmo | Fixed Window |
| Janela | 1 minuto |
| Limite | 25 mensagens |
| Fila | 0 |
| Partição | JWT sub / IP / "anonymous" |
Aplicada exclusivamente no endpoint de envio manual de mensagens.
Partition Key¶
A chave de partição é resolvida com fallback encadeado:
private static string GetPartitionKey(HttpContext context)
{
return context.User.FindFirst("sub")?.Value
?? context.Connection.RemoteIpAddress?.ToString()
?? "anonymous";
}
| Prioridade | Fonte | Cenário |
|---|---|---|
| 1 | JWT sub claim |
Usuário autenticado |
| 2 | IP remoto | Requisição sem JWT (ex: webhook) |
| 3 | "anonymous" |
Sem JWT e sem IP (edge case) |
Exceção: A política Login usa IP diretamente, pois o JWT ainda não existe no momento do login.
Constantes Centralizadas¶
// src/Ciba.Shared/Constants/RateLimitPolicies.cs
public static class RateLimitPolicies
{
public const string Api = "api";
public const string Login = "login";
public const string Llm = "llm";
public const string SendMessage = "send-message";
}
As constantes são compartilhadas entre Ciba.Api (configuração) e endpoints (aplicação).
Aplicação nos Endpoints¶
Cada endpoint group aplica a política via .RequireRateLimiting():
// Exemplo: AgentEndpoints.cs
var group = app.MapGroup(ApiRoutes.Agents.Base)
.RequireAuthorization()
.RequireRateLimiting(RateLimitPolicies.Api);
Mapeamento Endpoint -> Política¶
| Endpoint Group | Política |
|---|---|
| Auth | Login |
| Agents | Api |
| Conversations | Api |
| SendMessage | SendMessage |
| Instances | Api |
| Tenants | Api |
| Users | Api |
| LLM | Api |
| SystemSettings | Api |
| Playground | Llm |
Configuração no DI¶
// ServiceCollectionExtensions.cs -> AddApiRateLimiting()
services.AddRateLimiter(options =>
{
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
options.AddPolicy(RateLimitPolicies.Api, context => { ... });
options.AddPolicy(RateLimitPolicies.Login, context => { ... });
options.AddPolicy(RateLimitPolicies.Llm, context => { ... });
options.AddPolicy(RateLimitPolicies.SendMessage, context => { ... });
});
Resumo Visual¶
Requisição HTTP
│
├── Identificar usuário: JWT sub → IP → "anonymous"
│
├── Selecionar política: endpoint group → RequireRateLimiting(policy)
│
├── Verificar limite: contador da janela < PermitLimit?
│ ├── Sim → Prossegue normalmente
│ └── Não → HTTP 429 Too Many Requests
Regras¶
- Sempre usar constantes de
RateLimitPolicies-- nunca strings mágicas - Login usa IP -- não há JWT disponível antes da autenticação
- QueueLimit = 0 em todas as políticas -- requisições excedentes são rejeitadas imediatamente
- Sliding Window apenas para
Api-- oferece distribuição mais suave; demais usam Fixed Window - Novas políticas devem ser adicionadas em
RateLimitPolicies.cse configuradas emAddApiRateLimiting()