OptionaldefaultThe limiter used when a rule names none. Defaults to memory.
OptionalglobalA rule applied to every route that declares none.
Undeclared by default: a limit nobody asked for is a limit nobody sized, and the first thing it breaks is a legitimate burst.
OptionalheadersHeaders named after the caller's remaining budget, when the response can carry them.
Standard by default (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, and
Retry-After on a refusal). Set false to say nothing: a public API may prefer not to publish
the shape of its budget.
OptionallimitersThe limiters this application configures.
OptionaltrustedWhich request headers may carry the caller's real address, in order of preference.
Empty by default, and that default matters: a forwarded header is client-spoofable unless a proxy you trust overwrites it, so reading one by default would hand every caller an unlimited supply of identities. Name the header your own edge guarantees.
How rate limiting is configured (
stone.rateLimit.*).The rule this module exists to serve: throttle the subject, never the address alone. Throttling by address assumes one address is one person. On mobile networks using carrier-grade NAT, the norm across much of the world, hundreds of unrelated subscribers share one public address. A per-address quota then punishes legitimate users at random, and hardest exactly where the audience is largest.
So the budget belongs to the thing actually being protected: the account, the mailbox, the phone number. The address keeps a much looser bucket whose only job is to stop bulk enumeration from one machine.