Model the RackAttack user allowlist as an explicit skip rule

What does this MR do and why?

Implements gitlab-com/gl-infra/production-engineering#29320 (closed).

Before this change, a user listed in the GITLAB_THROTTLE_USER_ALLOWLIST env var was exempted from identity throttles through a side effect. The Labkit classifier returned a blank requester id ('') for that user. A blank id fails both the authenticated rules' presence gate and the unauthenticated rules' nil gate, so no identity throttle counted the request. This exemption was hidden inside a discriminator value and invisible in metrics.

This MR replaces that trick with an explicit user_allowlist :skip rule. The rule is built once at boot and sits with the other synthetic skip rules (bypass_header, path skips, runner_jobs), ahead of every throttle rule on every limiter. It matches requester_type: 'user' and requester_id: { oneOf: [<stringified allowlisted ids>] }. A match terminates evaluation, allows the request, writes nothing to Redis, and is observable as calls_total{action="skip"}. An empty allowlist builds no rule.

This is a full bypass, wider than Rack::Attack's old safelist, which left the aid-keyed product-analytics collector throttle and EE's path-keyed incident-management throttle still counting allowlisted users. Per discussion with Bob Van Landuyt, this widening changes nothing in practice: the collector path has been dead since 13.3, tracked for removal in gitlab-com/gl-infra/production-engineering#29563, and the incident throttle only sees Alertmanager integration traffic, never a user.

ClassifiedRequest#requester now always returns the real (id, type) pair. The blank-id trick and its comments are removed.

The env var keeps working as documented for self-managed. Migrating it to config is out of scope, confirmed by Bob Van Landuyt on the work item.

The oneOf matcher ships in gitlab-labkit 4.4.0 (gitlab-org/ruby/gems/labkit-ruby!341 (merged)), which master already carries. This MR contains no dependency changes.

How to set up and validate locally

  1. Set GITLAB_THROTTLE_USER_ALLOWLIST to a user id.
  2. Enable an authenticated API throttle.
  3. Confirm that user's requests are not counted by any throttle.
  4. Confirm calls_total{action="skip", rule="user_allowlist"} increments for that user's requests.

References

Edited by Sankalp

Merge request reports

Loading
Loading