Repository navigation
Send GitLab the right auth on the right host - #2125
Merged
Merged
Conversation
ppXD
force-pushed
the
fix/send-gitlab-the-right-auth-on-the-right-host
branch
from
October 18, 2026 07:00
a4eb9c4 to
c7d5fba
Compare
ppXD
force-pushed
the
fix/resolve-the-git-credential-at-each-push
branch
from
October 18, 2026 11:20
79cdf48 to
707475b
Compare
ppXD
force-pushed
the
fix/send-gitlab-the-right-auth-on-the-right-host
branch
from
October 18, 2026 11:20
c7d5fba to
0afe394
Compare
ppXD
force-pushed
the
fix/resolve-the-git-credential-at-each-push
branch
from
October 18, 2026 12:08
707475b to
420f458
Compare
A GitLab credential stopped working, without the token being wrong, in two ways. The typed client (NGitLab, on HttpWebRequest) sent only Authorization: Bearer and dropped it on a 301; the raw HTTP calls sent Bearer and PRIVATE-TOKEN together and kept PRIVATE-TOKEN across a redirect to any host. Behind a redirecting base URL a PAT worked, an OAuth token read 401, and the PAT went wherever the redirect pointed. GitLab 13.0 to 17.7 also reads a Bearer of 41 or more characters as an OAuth token alone, so a long access token was refused as a Bearer. - Every call now sends the one header its credential type names: PRIVATE-TOKEN for personal, project and group access tokens, Bearer for OAuth. NGitLab's two construction sites share a RequestOptions that rewrites the header and follows a GET or HEAD redirect inside one origin itself; the raw calls share one client behind OriginScopedRedirectHandler, which gains opt-in FollowsCrossOrigin = false and RepeatsWritesOnly = true. - A redirect to another scheme, host or port is not followed and fails with the typed provider_base_url_redirects, naming the URL GitLab pointed at. So does the next page of a list when its Link header names another origin: NGitLab builds that request itself, and the options now refuse it before the credential is attached. NGitLab never re-sends a write, and a raw write is repeated only by a 307 or 308; a 301, 302 or 303 that would turn it into a GET is refused rather than read as the write's answer. - A tokened git command that its remote sends to another origin fails naming the redirect (the same code and the origin git was sent to) instead of git's own prompt for a username. It stays a WorkspaceException, so the push retry, the per-repo push isolation and the workflow nodes that catch one keep treating it as a git failure. - Adding a provider, or moving its API address, asks GET /api/v4/version once, with no credential, and refuses an address that redirects to another origin. An edit that leaves the address as stored asks nothing, so an existing connection is never rewritten or blocked. - An edit that only upgrades http to https on the same host (80 to 443, or one explicit port) is no longer a move past connected tokens, so the self-service fix for a redirecting base URL does not require disconnecting every member; the edit form mirrors the rule. While tokens are connected the new address must also answer HTTP, any status: a mistaken upgrade cannot be edited back (that is a move) and would break every token, so it is refused with provider_endpoint_unreachable and the stored address stays. With no token connected nothing is asked. - Resolving a credentialed GitLab clone logs a Warning when the clone URL's origin is not the base URL's. Nothing is rewritten.
ppXD
changed the base branch from
fix/resolve-the-git-credential-at-each-push
to
main
October 18, 2026 12:09
ppXD
force-pushed
the
fix/send-gitlab-the-right-auth-on-the-right-host
branch
from
October 18, 2026 12:09
0afe394 to
cd25e9d
Compare
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.
Summary
PRIVATE-TOKENfor personal, project and group access tokens,Authorization: Bearerfor OAuth, never both), through NGitLab (GitLabRequestOptions) and every raw call (GitLabHttp). Behind a redirecting base URL a PAT used to work and an OAuth token read 401, and GitLab 13.0 to 17.7 refused a 41+ character access token sent as a Bearer.Link: rel="next"names another origin, are refused before any credential is attached and fail with the typedprovider_base_url_redirects, naming the URL. NGitLab never re-sends a write; a raw write is repeated only by a 307 or 308, and a 301, 302 or 303 that would turn it into a GET is refused instead of being read as the write's answer (OriginScopedRedirectHandler.RepeatsWritesOnly, opt-in).ls-remoteor push whose remote sends git to another origin now fails naming that redirect (same code, with the origin git was sent to) instead of git'scould not read Usernameprompt. It remains aWorkspaceException, so existing catch sites behave as before.GET /api/v4/versiononce, with no credential, and refuses an address that redirects to another origin. An edit that leaves the address as stored asks nothing; no stored base URL is ever rewritten.provider_endpoint_unreachableand the stored address stays, because undoing a mistaken upgrade would itself be a refused move. With no token connected nothing is asked.Behaviour to review: an instance whose GitLab emits
Linkheaders naming a different origin than its stored base URL (a misconfiguredexternal_urlor proxy) previously had paged NGitLab reads follow that link with the token. Those reads now fail withprovider_base_url_redirectsnaming the origin; editing the base URL to it (an http to https upgrade is allowed while tokens are connected) fixes it.Test plan
WorkspaceExceptionmapping, probe answer check (any status, redirect, TLS to a plain port, down, silent, cancel), failure code pins (full unit suite 14094 passed)provider_endpoint_unreachablewhile the token keeps working at the stored address (full E2E project green)provider_base_url_redirectson paged reads after deploy