Rate limit release evidence collection through the API

What does this MR do and why?

Context

Each call to the release evidence API (POST /projects/:id/releases/:tag_name/evidence) collects a new evidence for the release, and nothing bounds how often one user calls it. This MR is part 2 of the plan in https://gitlab.com/gitlab-org/gitlab/-/work_items/638257#note_4197891367, which has the figures and the approach; parts 1 and 3 have their own MRs.

This MR

  • The evidence API counts toward a new per-user rate limit (release_evidence_collections_limit_per_user, default 10 per minute). It is a rate_limits application setting in the Releases API rate limits block on Admin > Settings > Network and in the application settings API, and 0 disables it.
  • The check runs after the access check, so users without access to a project don't spend their budget, and before the release lookup. It doesn't apply to the evidence collected when a release is created or on a scheduled release's date.
  • The key starts in log mode: calls over the limit are logged until the flag is enabled, and then the API returns 429 Too Many Requests.
  • Docs: the existing Releases API rate limits page, the releases API, and the settings API. The Changelog entry comes with the flag-removal MR.

Feature Flag: rate_limit_release_evidence_collections_per_user

References

Screenshots or screen recordings

The Releases API rate limits block on Admin > Settings > Network gets a third field. Before (master) and After (this branch) are attached at the end of this description.

How to set up and validate locally

  1. In a Rails console, set a small limit:
    ApplicationSetting.current.update!(release_evidence_collections_limit_per_user: 1)
  2. Wait a minute for the settings cache. With a personal access token (api scope) for a project with a release that you can create evidence for, collect evidence twice:
    for i in 1 2; do
      curl --include --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
        "http://gdk.test:3000/api/v4/projects/<project_id>/releases/<tag_name>/evidence"
    done
    Both return 202, and log/api_json.log shows rate_limit_state with limit_release_evidence_collections_by_user_log:log for the second request.
  3. Run Feature.enable(:rate_limit_release_evidence_collections_per_user), wait for the next minute, and repeat. The first returns 202, the second 429 with Retry-After.
  4. Clean up: Feature.remove(:rate_limit_release_evidence_collections_per_user) and reset the setting to 10.

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.

before after

Edited by Leaminn Ma

Merge request reports

Loading
Loading