OAuth2 token refresh ignores configured subfolder
Checklist
- I'm using the latest version of the extension (Run
glab --version)- Extension version:
- Operating system and version: AlmaLinux 10
- Gitlab.com or self-managed instance? self-managed instance
- GitLab version (if self-managed)
v19.2.4 - I have performed
glab auth statusto check for authentication issues - Run the command in debug mode and attach any useful output
Summary
When refreshing an expired OAuth2 access token for a self-managed GitLab instance installed under a subfolder, glab ignores hosts.<hostname>.subfolder.
The refresh request is sent to:
https://gitlab.example.com/oauth/token
instead of: Related: #8399 (closed) fixed the equivalent problem for the OAuth authorization URL, but the token-refresh path still does not use subfolder.
Environment
- SHELL: bash
- TERM: xterm-256color
- GLAB: glab 1.116.0 (e8436ca8)
Other:
- GitLab instance URL:
https://gitlab.example.com/<subfolder> hosts.gitlab.example.com.subfolder:<subfolder>
Steps to reproduce
-
Use a self-managed GitLab instance installed under a subfolder, for example
https://gitlab.example.com/gitlab. -
Authenticate with OAuth2 using
glab auth login, so the host configuration includes:hosts: gitlab.example.com: subfolder: gitlab is_oauth2: "true" -
Wait for the OAuth2 access token to expire.
-
Run a command that makes an authenticated API request, for example:
GLAB_DEBUG=true glab repo list --hostname gitlab.example.com
What is the current bug behavior?
glab attempts to refresh the OAuth2 token through /oauth/token at the host root, without the configured subfolder. The refresh request therefore reaches the wrong endpoint and fails.
What is the expected correct behavior?
glab should include the configured subfolder when constructing the token endpoint URL. For the example above, it should refresh through:
https://gitlab.example.com/gitlab/oauth/token
Relevant logs and/or screenshots
GLAB_DEBUG=true glab auth status
gitlab.example.com
x gitlab.example.com: API call failed: oauth2: cannot fetch token: 404 Not Found
✓ Git operations for gitlab.example.com configured to use https protocol.
✓ API calls for gitlab.example.com are made over https protocol.
✓ REST API Endpoint: https://gitlab.example.com/git/api/v4/
✓ GraphQL Endpoint: https://gitlab.example.com/git/api/graphql/
✓ Subfolder: git
✓ Token found in configuration file (plaintext): **************************
! To store this token more securely, run glab auth login --hostname gitlab.example.com to move it into the operating system keyring.
ERROR
could not authenticate to one or more of the configured GitLab instances. GLAB_DEBUG=true glab repo list
ERROR
Oauth2: cannot fetch token: 404 Not Found
Response: <!DOCTYPE html>
<html>
<head>
<meta content="width=device-width, initial-scale=1" name="viewport">
<title>The page you're looking for could not be found (404)</title>
<style>
body {
color: #333238;
text-align: center;
font-family: "Nunito Sans", -apple-system, ".SFNSText-Regular", "San Francisco", BlinkMacSystemFont, "Segoe
UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
}
h1 {
font-size: 1.75rem;
line-height: 2.25rem;
margin: 1rem 0;
}
p {
margin-bottom: .5rem;
}
img {
display: block;
margin: 0 auto;
}
a {
text-decoration: none;
color: #1068bf;
}
a:hover {
text-decoration: underline;
}
.error-container {
max-width: 65ch;
margin: auto;
padding: 1rem 0;
}
.action-container {
margin-top: 1.5rem;
}
.go-back {
display: none;
}
</style>
</head>
<body>
<div class="error-container">
<img src='/-/error-illustrations/error-404-lg.svg' alt="404 error"/>
<h1>404: Page not found</h1>
<p>Make sure the address is correct and the page has not moved.</p>
<p>Please contact your GitLab administrator if you think this is a mistake.</p>
<div class="action-container">
<a href="javascript:history.back()" class="js-go-back go-back">Go back</a>
</div>
</div>
<script>
(function () {
var goBack = document.querySelector('.js-go-back');
if (history.length > 1) {
goBack.style.display = 'inline';
}
})();
</script>
</body>
</html>
. Possible fixes
oauthBaseURL already reads subfolder and builds the correct authentication base URL for the authorization flow:
https://gitlab.com/gitlab-org/cli/-/blob/main/internal/oauth2/oauth2.go
However, NewConfigTokenSource constructs the OAuth2 base URL directly from protocol and hostname, without reading subfolder:
https://gitlab.com/gitlab-org/cli/-/blob/main/internal/oauth2/token_source.go
Using the same subfolder-aware base URL construction for token refresh should address the issue.