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?checksgit_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?tothrottle_unauthenticated_git_http?is a breaking change. When the newthrottle_unauthenticated_git_lfssetting 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_limitused 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)