BitzOrcas uses ASP.NET Core’s built-in rate limiting with tenant + caller partitioned policies. Each tenant/caller pair gets its own counter bucket, preventing application callers from sharing anonymous buckets.
Three policies
| Policy | Algorithm | Window | Use case |
|---|---|---|---|
userPolicy | Token Bucket | 1 minute | General REST API endpoints |
sensitivePolicy | Sliding Window | 1 minute | Login, OTP, password reset |
fixedPolicy | Fixed Window | 1 minute | Internal/low-frequency services |
Partition key format
{tenant_id}:{user_id|client_id}This ensures application callers (which have client_id but no user_id) are partitioned correctly instead of all falling into an “anonymous” bucket.
Policy parameters
userPolicy (Token Bucket)
new TokenBucketRateLimiterOptions{ TokenLimit = 2, TokensPerPeriod = 2, ReplenishmentPeriod = TimeSpan.FromMinutes(1), QueueLimit = 0, AutoReplenishment = true,}Allows 2 requests per minute with no queuing.
sensitivePolicy (Sliding Window)
new SlidingWindowRateLimiterOptions{ Window = TimeSpan.FromMinutes(1), SegmentsPerWindow = 4, PermitLimit = 5, QueueLimit = 0,}5 requests per minute — sliding window prevents boundary-burst attacks.
fixedPolicy (Fixed Window)
new FixedWindowRateLimiterOptions{ Window = TimeSpan.FromMinutes(1), PermitLimit = 10, AutoReplenishment = true,}10 requests per minute — simple and predictable for internal services.
429 response
All rate-limited requests return RFC 9457 ProblemDetails:
{ "type": "https://docs.bitzsoft.com/problems/rate-limit-exceeded", "title": "Too Many Requests", "status": 429, "detail": "Rate limit exceeded.", "errorCode": "RateLimit.Exceeded", "retryAfter": 60}HTTP headers included:
Retry-After: 60X-RateLimit-Remaining: 0(when available)
Usage in endpoints
app.MapPost("/api/notes", async (...) => ...) .RequireRateLimiting("userPolicy");
app.MapPost("/api/auth/login", async (...) => ...) .RequireRateLimiting("sensitivePolicy");Middleware order
Rate limiter middleware is placed after authorization in the pipeline:
ExceptionHandler → CorrelationId → Auth → DelegationToken→ TenantResolution → Audit → Authorization → RateLimiter → EndpointsProduction considerations
For multi-instance deployments, consider:
- Redis DistributedRateLimiter — shared counter across instances
- Gateway-level limiting — YARP/Envoy/Nginx before reaching the API
- Per-tenant rate plans — configurable limits from billing subscription