Cache auth result in SafeRequestStore to avoid double call
What does this MR do and why?
Cache auth result in SafeRequestStore to avoid double call
Contributes to https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/28578
Problem
With throttle_authenticated_git_http enabled, Rack::Attack
calls find_with_user_password (bcrypt 1) to identify the user
for throttling, then GitHttpClientController calls it again
(bcrypt 2) for authentication — doubling the cost per request.
Solution
Wrap the authenticator loop in find_with_user_password with
Gitlab::SafeRequestStore.fetch so the second call within the
same request returns the cached result. The cache key uses
SHA256(password) (never stores plaintext). Side effects
(user_auth_attempt!, logging) remain outside the cache and
run on every call. SafeRequestStore is thread-local process
memory cleared at end of request — not Redis or any persistent
store. When RequestStore is inactive (e.g. background jobs),
NullStore executes the block every time with no caching.
This also fixes the same double-bcrypt problem for
throttle_authenticated_git_lfs.
References
https://gitlab.com/gitlab-com/gl-infra/production-engineering/-/work_items/28578+
Screenshots or screen recordings
Raw data
git clone http://gdk.test:3000/toolbox/gitlab-smoke-tests.git## When Rate limiter is off
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011373
/toolbox/gitlab-smoke-tests.git/info/refs | 0.414914
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.41861
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.40202
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011216
/toolbox/gitlab-smoke-tests.git/info/refs | 0.396547
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.553983
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.390911
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011555
/toolbox/gitlab-smoke-tests.git/info/refs | 0.392771
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.414144
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.391313
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011197
/toolbox/gitlab-smoke-tests.git/info/refs | 0.396814
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.399443
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.407287
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011259
/toolbox/gitlab-smoke-tests.git/info/refs | 0.388194
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.392385
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.394397
## When Rate limiter is on
### Before fix
/toolbox/gitlab-smoke-tests.git/info/refs | 0.053492
/toolbox/gitlab-smoke-tests.git/info/refs | 0.951372
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 1.165686
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 1.188724
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011681
/toolbox/gitlab-smoke-tests.git/info/refs | 0.758207
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.790359
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.788036
/toolbox/gitlab-smoke-tests.git/info/refs | 0.012445
/toolbox/gitlab-smoke-tests.git/info/refs | 0.751753
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.777891
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.779285
/toolbox/gitlab-smoke-tests.git/info/refs | 0.020705
/toolbox/gitlab-smoke-tests.git/info/refs | 0.819522
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.783056
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.779211
### After fix
/toolbox/gitlab-smoke-tests.git/info/refs | 0.025602
/toolbox/gitlab-smoke-tests.git/info/refs | 0.457709
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.473295
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.486024
/toolbox/gitlab-smoke-tests.git/info/refs | 0.011363
/toolbox/gitlab-smoke-tests.git/info/refs | 0.430626
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.706403
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.429267
/toolbox/gitlab-smoke-tests.git/info/refs | 0.021732
/toolbox/gitlab-smoke-tests.git/info/refs | 0.427658
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.432949
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.439658
/toolbox/gitlab-smoke-tests.git/info/refs | 0.010926
/toolbox/gitlab-smoke-tests.git/info/refs | 0.418633
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.427774
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.431993
/toolbox/gitlab-smoke-tests.git/info/refs | 0.025345
/toolbox/gitlab-smoke-tests.git/info/refs | 0.419998
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.438933
/toolbox/gitlab-smoke-tests.git/git-upload-pack | 0.423816How to set up and validate locally
- Enable the throttle: in Admin > Settings > Network > Throttling, enable "Authenticated Git HTTP requests" with e.g. 5 requests per 60 seconds.
- Clone or fetch a repo repeatedly using HTTP Basic Auth with a password (not a PAT):
git -c credential.helper='' clone http://user:password@localhost:3000/group/repo.git - Observe that after 5 requests the server returns
429 Too Many Requests. - To confirm bcrypt is no longer doubled, add a temporary log line in
Gitlab::Auth.find_with_user_passwordand verify it appears only once per request inlog/application.log.
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.

