Add separate unauthenticated Git LFS rate limiting configuration

Problem

There's an inconsistency in how Git HTTP and Git LFS rate limiting is configured for authenticated vs unauthenticated requests.

Authenticated requests have separate, independent rate limiters:

  • throttle_authenticated_git_http - for Git HTTP operations (explicitly excludes LFS via !git_lfs_path?)
  • throttle_authenticated_git_lfs - specifically for Git LFS operations

Unauthenticated requests only have:

  • throttle_unauthenticated_git_http - covers both Git HTTP and Git LFS operations (no exclusion)

This asymmetry prevents administrators from independently controlling rate limits for unauthenticated Git LFS traffic separately from regular Git HTTP traffic.

Current Implementation

In lib/gitlab/rack_attack/request.rb:

def throttle_unauthenticated_git_http?
  git_path? &&
    Gitlab::Throttle.settings.throttle_unauthenticated_git_http_enabled &&
    unauthenticated?
end

def throttle_authenticated_git_http?
  git_path? && !git_lfs_path? &&  # ← Excludes LFS
    Gitlab::Throttle.settings.throttle_authenticated_git_http_enabled
end

def throttle_authenticated_git_lfs?
  git_lfs_path? &&
    Gitlab::Throttle.settings.throttle_authenticated_git_lfs_enabled
end

Notice that:

  • throttle_unauthenticated_git_http? checks git_path? which includes LFS paths
  • throttle_authenticated_git_http? explicitly excludes LFS paths with !git_lfs_path?
  • throttle_authenticated_git_lfs? has its own dedicated check

Proposed Solution

Add a new throttle_unauthenticated_git_lfs configuration to match the authenticated pattern, following the implementation from !191552 (merged).

Implementation Steps

1. Update app/models/application_setting.rb

Add new JSONB accessor fields in the rate_limits definition:

throttle_unauthenticated_git_lfs_enabled: [:boolean, { default: false }],
throttle_unauthenticated_git_lfs_requests_per_period: [:integer, { default: 1000 }],
throttle_unauthenticated_git_lfs_period_in_seconds: [:integer, { default: 60 }]

Add to visible_attributes array:

:throttle_unauthenticated_git_lfs_enabled,
:throttle_unauthenticated_git_lfs_period_in_seconds,
:throttle_unauthenticated_git_lfs_requests_per_period,

2. Update app/models/application_setting_implementation.rb

Add defaults:

throttle_unauthenticated_git_lfs_enabled: false,
throttle_unauthenticated_git_lfs_period_in_seconds: 60,
throttle_unauthenticated_git_lfs_requests_per_period: 1000,

3. Update lib/gitlab/rack_attack/request.rb

Modify existing method to exclude LFS:

def throttle_unauthenticated_git_http?
  git_path? && !git_lfs_path? &&  # ← Add exclusion
    Gitlab::Throttle.settings.throttle_unauthenticated_git_http_enabled &&
    unauthenticated?
end

Add new method:

def throttle_unauthenticated_git_lfs?
  git_lfs_path? &&
    Gitlab::Throttle.settings.throttle_unauthenticated_git_lfs_enabled &&
    unauthenticated?
end

4. Update lib/gitlab/throttle.rb

Add throttle options method:

def self.throttle_unauthenticated_git_lfs_options
  limit_proc = proc { |req| settings.throttle_unauthenticated_git_lfs_requests_per_period }
  period_proc = proc { |req| settings.throttle_unauthenticated_git_lfs_period_in_seconds.seconds }

  { limit: limit_proc, period: period_proc }
end

5. Update lib/gitlab/rack_attack.rb

Add to throttle_definitions:

'throttle_unauthenticated_git_lfs' => ThrottleDefinition.new(
  Gitlab::Throttle.throttle_unauthenticated_git_lfs_options,
  ->(req) { req.ip if req.throttle_unauthenticated_git_lfs? }
)

6. Update Admin UI

Update app/views/admin/application_settings/_git_http_limits.html.haml to add fields for the new unauthenticated Git LFS rate limit settings.

7. Update app/helpers/application_settings_helper.rb

Add the new settings to the visible attributes list.

8. Update JSON Schema

Update app/validators/json_schemas/application_setting_rate_limits.json with the new fields.

9. Update Documentation

Update doc/api/settings.md to document the new API settings.

10. Add Tests

  • Unit tests in spec/lib/gitlab/rack_attack/request_spec.rb
  • Integration tests in spec/requests/rack_attack_global_spec.rb
  • View tests in spec/views/admin/application_settings/network.html.haml_spec.rb
  • Model tests in spec/models/application_setting_spec.rb

Benefits

  • Consistency: Matches the pattern used for authenticated requests (established in !191552 (merged))
  • Flexibility: Allows administrators to set different rate limits for Git LFS vs regular Git operations for unauthenticated users
  • Use case: Git LFS operations typically involve larger files and may need different rate limiting strategies than regular Git HTTP operations

Implementation Considerations

  • Backward compatibility: The change to add && !git_lfs_path? to throttle_unauthenticated_git_http? is a breaking change. When the new throttle_unauthenticated_git_lfs setting is disabled (default), LFS traffic would no longer be rate-limited by the Git HTTP throttle
  • Migration strategy: Consider enabling the new LFS throttle by default with the same limits as the existing Git HTTP throttle to maintain current behavior
  • Feature flag: Consider using a feature flag similar to git_authenticated_http_limit used in !191552 (merged)
  • Update admin UI to expose the new configuration options
  • Add appropriate i18n strings in locale/gitlab.pot

Related

  • !191552 (merged) - Added authenticated Git HTTP rate limiter (reference implementation)
Edited Feb 04, 2026 by 🤖 GitLab Bot 🤖
Assignee Loading
Time tracking Loading