Feat/add rate limit tiers - #132
Conversation
Every authenticated key shared one @withApiKey rate limit block, so raising a limit for one customer raised it for all of them. The raised values also only existed as a manual edit to a tracked file on the API host, where a reset, stash or fresh clone silently reverts them. Limits now live in apikeys/limits.yaml as nine endpoint bases and three tier multipliers, and apikeys.py compiles them together with the keys into the snippet caddy already imports. docker-compose.rate_limit.yaml drops from 273 lines to 70. keys.csv gains an optional tier column; two-column rows read as standard, so the existing file works untouched. Anonymous and standard limits are unchanged from what is deployed today. Premium is 5x standard. @withApiKey is still generated even though rate limiting no longer matches on it: /check_authentication handles on that matcher, for keys of any tier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ENTRYPOINT without brackets makes Docker run /bin/sh -c and discard all arguments, so the CMD ["docker-proxy"] below it could never take effect, and /bin/sh was PID 1 — SIGTERM never reached caddy, so docker stop always ended in a SIGKILL with no graceful shutdown. Latent because the compose file overrides the entrypoint with a form compose word-splits into exec form. Surfaced when running the image directly to validate a generated config. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rate limits become their own section rather than a subsection of Prerequisites, and are findable from the table of contents. Lists anonymous, standard and premium limits, with one contact line covering both key tiers. States up front that the limits apply to Gnosis Mainnet and that Chiado is unlimited, which was previously mentioned twice and half-implied. Drops the note about event-based triggers not being fully operational on Mainnet, which is no longer true. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jannikluhn
left a comment
There was a problem hiding this comment.
Looks good to me. A bit suspicious that there are no tests and that the code is not very testable (sys.exit in functions instead of exceptions for errors), but since it's just a small script it's fine with me.
As an alternative to tiers we could have just put the multiplier in the keys.csv file to remove one layer of abstraction.
I don't think backwards compatibility is necessary, updating the existing keys.csv file once is minimal work and would save some complexity. But again, it's a small script, so fine by me.
Validation could not be tested while it called sys.exit, so read_limits and read_users raise ConfigError and __main__ exits with the message. The four public functions take an optional path so tests can use temp files. Adds tests for read_limits, read_users, dump_users and compile, the last compared against saved copies of the generated snippet in testdata/. Malformed-key errors now name the user instead of printing the key, keeping key material out of logs. The generated snippet is byte-identical to the previous version. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Thanks. Added tests for the functions in The rate limits themselves are a separate thing. I checked those by hand on the droplet rather than porting the test scripts, and added a README section on how to check them against a deployment if that's needed. On backwards compatibility: it's already there and working. A two-column On the tiers, I think naming them makes it clearer what the limits are for than a bare set of numbers. |
No description provided.