2.3 KiB
rate-limiter.ts
Purpose
AdminRateLimiter enforces the design §8.4 per-principal rate limits
on every admin endpoint. Read endpoints share a 60-calls-per-minute
bucket; destructive endpoints share a 1-per-minute bucket. Both buckets
are scoped per principal id so a misbehaving operator cannot starve
the host of admin throughput for everyone else.
The limiter is a thin wrapper around @suaveplan/rate-limiter's
TokenBucket — one bucket per (principalId, kind) pair, allocated
lazily on first contact. The refill rate is set so the bucket starts
full and drains to zero after capacity consecutive calls in a
minute; refill is linear, so a steady stream is permitted at the
documented rate. Bursts up to capacity are allowed.
Features
- Per-principal isolation — one bucket pair per id.
- Lazy allocation — principals that never hit admin are zero-cost.
- Token-bucket refill maps
capacitycalls to one minute. - Injectable clock for deterministic tests.
Usage: Basic
import { AdminRateLimiter } from "@suaveplan/api-host/admin-api";
const limiter = new AdminRateLimiter(60, 1);
limiter.consume("alice", "read"); // true
limiter.consume("alice", "destructive"); // true
limiter.consume("alice", "destructive"); // false (until refill)
Usage: Advanced
let now = 0;
const limiter = new AdminRateLimiter(60, 1, () => now);
limiter.consume("alice", "destructive"); // true
limiter.consume("alice", "destructive"); // false
now = 60_001;
limiter.consume("alice", "destructive"); // true — refilled
API Reference
new AdminRateLimiter(readPerMinute, destructivePerMinute, clock?)consume(principalId, kind): boolean—trueon success,falsewhen rate-limited.
Implementation Notes
TokenBucket's consume(1) updates the bucket's internal counter and
returns a RateLimitResult. The admin API only cares about the
allowed boolean — it surfaces 429 + Retry-After purely from
constants when consume returns false.
The principal-id key is the rate-limit cardinality bound. A deployment with many distinct admin principals carries a small memory cost (~80 bytes per bucket pair) — gateways should rate-limit admin traffic at the edge before it reaches the host if extreme multi-tenant cardinality is anticipated.