Add a per-user rate limit to the to-do list API
What does this MR do and why?
Adds a configurable per-user rate limit to GET /api/v4/todos (300 requests per minute by default), behind the todos_list_api_rate_limit feature flag (gitlab_com_derisk, disabled by default).
Listing to-do items renders the full target entity for each item. For merge requests that includes detailed_merge_status, which runs the mergeability checks, so a page of merge request to-do items can take seconds. The only limit today is the generic authenticated API throttle, which isn't sized for an endpoint this expensive. 300 per minute sits well above normal use, including CLI and integration polling.
- New
todos_list_api_limitapplication setting in therate_limitsJSONB column (default300,0disables the limit), settable through the application settings API. No migration needed. - New
todos_list_apikey in the labkit rate limit registry (limit_todos_list_api_by_user, per user, per minute), reading its limit from that setting, following theGitlab::ApplicationRateLimiterguidelines. GET /todoschecks it when the flag is enabled for the current user, and returns429withRetry-Afterwhen the limit is exceeded. The check runs before any to-do work.- Documented in the API and Rails console rate limits list and the application settings API, as disabled by default. No changelog entry while the flag is off.
References
- https://gitlab.com/gitlab-org/gitlab/-/work_items/636103
- Rollout issue: #636396
Screenshots or screen recordings
Not applicable, no UI change.
How to set up and validate locally
- In the Rails console, enable the flag for your user:
Feature.enable(:todos_list_api_rate_limit, User.find_by_username('root')) - Lower the limit for testing:
ApplicationSetting.current.update!(todos_list_api_limit: 3) - Call the endpoint repeatedly with a personal access token:
for i in $(seq 1 5); do curl -s -o /dev/null -w "%{http_code}\n" --header "PRIVATE-TOKEN: <token>" "http://gdk.test:3000/api/v4/todos"; done - After the limit is reached, requests return
429with aRetry-Afterheader andRateLimit-Name: todos_list_api. With the flag disabled, or withtodos_list_api_limitset to0, all requests return200.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.