Search rate limit exemption doesn't work in API

Summary

The search_rate_limit_allowlist application setting is not respected when rate limiting API search endpoints. Users added to the allowlist are still rate limited when using the API, while the same allowlist works correctly for web UI searches.

Steps to reproduce

  1. Add a username (e.g., testuser) to the search rate limit allowlist via Admin > Settings > Network > Search rate limit > Users allowlist
  2. As that user, perform search requests via the API (e.g., GET /api/v4/groups/:id/epics?search=...)
  3. Exceed the configured search rate limit threshold
  4. Observe that the user is still rate limited despite being on the allowlist

Example Project

N/A - This is a core GitLab functionality issue.

What is the current bug behavior?

Users on the search_rate_limit_allowlist are still rate limited when performing searches via the API.

What is the expected correct behavior?

Users added to the search_rate_limit_allowlist should be exempt from search rate limits for both web UI and API requests, consistent with the documented purpose of the allowlist setting.

Relevant logs and/or screenshots

The following error appears in gitlab-rails/auth_json.log:

{
  "severity": "ERROR",
  "time": "2025-11-28T13:54:10.850Z",
  "correlation_id": "01KXXXXXXXXXXXXXXXXXXXX",
  "meta.caller_id": "GET /api/:version/groups/:id/epics",
  "meta.remote_ip": "1.22.33.44",
  "meta.feature_category": "portfolio_management",
  "meta.root_namespace": "cryptomathic",
  "meta.client_id": "ip/11.22.33.44",
  "message": "Application_Rate_Limiter_Request",
  "env": "search_rate_limit_request_limit",
  "remote_ip": "1.22.33.44",
  "method": "GET",
  "path": "/api/v4/groups/668/epics?search=%5BFILTERED%5D",
  "user_id": 666,
  "username": "testuser"
}

Output of checks

N/A

Results of GitLab environment info

N/A

Results of GitLab application Check

N/A

Possible fixes

The issue is in lib/api/helpers.rb in the validate_search_rate_limit! method (lines 868-874).

Current code does not pass the users_allowlist parameter:

# lib/api/helpers.rb
def validate_search_rate_limit!
  if current_user
    check_rate_limit!(:search_rate_limit, scope: [current_user])
  else
    check_rate_limit!(:search_rate_limit_unauthenticated, scope: [ip_address])
  end
end

Compare with the controller concern app/controllers/concerns/search_rate_limitable.rb which correctly passes the allowlist:

# app/controllers/concerns/search_rate_limitable.rb
def check_search_rate_limit!
  if current_user
    check_rate_limit!(:search_rate_limit, scope: [current_user, safe_search_scope].compact,
      users_allowlist: Gitlab::CurrentSettings.current_application_settings.search_rate_limit_allowlist)
  else
    check_rate_limit!(:search_rate_limit_unauthenticated, scope: [request.ip])
  end
end

Proposed fix - Update lib/api/helpers.rb to include the users_allowlist parameter:

def validate_search_rate_limit!
  if current_user
    check_rate_limit!(:search_rate_limit, scope: [current_user],
      users_allowlist: Gitlab::CurrentSettings.current_application_settings.search_rate_limit_allowlist)
  else
    check_rate_limit!(:search_rate_limit_unauthenticated, scope: [ip_address])
  end
end

Patch release information for backports

Edited by 🤖 GitLab Bot 🤖