Forward the client's refspec on cached lock walks and probes - #61
Merged
Merged
Conversation
Lock snapshots are keyed by the ?refspec= a client listed under, because the locking API treats the ref as an authentication input and upstream may answer differently per ref. But BuildLockListRequest had no refspec, so both the walk that fills a snapshot and the one-page probe that admits a caller to it asked upstream the unscoped question. With the cache warm, a ref-scoped listing got the no-ref answer, and a credential upstream would refuse for that ref was admitted anyway. BuildLockListRequest now takes the refspec and LockListRefresher passes key.Ref from both RefreshAsync and ProbeAsync. CredentialAdmission keys on the ref as well, so an admission earned under one ref does not admit the same credential to another ref's snapshot without its own probe. Fixes #47 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016wsoxnwaqMuAzvkm2xnzYh
This was referenced Sep 28, 2026
…s-refspec # Conflicts: # GitLfsCache.Tests/Integration/LockListCachingTests.cs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015u9u95HXjY2mDagnzGzxK2
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #47
What was wrong
Lock snapshots are cached per
?refspec=because the locking API treats the ref as an authentication input. The upstream requests behind a snapshot never sent that ref, though.UpstreamRequests.BuildLockListRequesthad no refspec parameter, so two requests asked upstream the unscoped question:LockListRefresher.RefreshAsync, the page walk that fills the snapshot.LockListRefresher.ProbeAsync, the one-page check that admits a caller to the snapshot.With the cache warm, a ref-scoped listing got the no-ref answer. A credential that upstream would refuse for that ref was admitted anyway.
Change
BuildLockListRequesttakes arefspecand sends it as an escapedrefspec=query parameter when it is not null.RefreshAsyncandProbeAsyncboth passkey.Ref.CredentialAdmissionshould key on the ref. I made it do so:ICredentialAdmission.IsAdmittedandAdmittake the ref, andLockListServicepasseskey.Ref. Without this, a probe that succeeded under one ref would let the same credential read another ref's snapshot without a probe of its own. That would undo the point of forwarding the ref on the probe.Tests
LockListCachingTests.CachedListing_ForwardsTheClientsRefspecOnTheWalkAndTheProberecords upstream query strings through a newRecordedRequest.QueryonStubUpstream.GET /locks?refspec=refs/heads/mainproduces a walk and a probe that both carryrefspec=refs%2Fheads%2Fmain.CredentialAdmissionTests.IsAdmitted_ADifferentRef_IsNotAdmittedchecks that an admission underrefs/heads/maindoes not carry over to another ref, to no ref, or to an empty ref. The existing admission tests now pass anullref.Checked both directions:
key.Refswapped fornullin the refresher and the service, the refspec case of the integration test fails. The no-refspec case is a control and passes either way.🤖 Generated with Claude Code
https://claude.ai/code/session_016wsoxnwaqMuAzvkm2xnzYh
Generated by Claude Code