Conversation
… Bearer Static mode (PAT) now uses GitLab's canonical PRIVATE-TOKEN header. OAuth mode continues to use Authorization: Bearer as before. Closes #187
Test Coverage ReportOverall Coverage: 93.64%
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR fixes the authentication header format for Personal Access Tokens (PATs) to use GitLab's canonical PRIVATE-TOKEN header instead of Authorization: Bearer. OAuth mode continues to use Authorization: Bearer as expected.
Changes:
- Renamed
getAuthorizationHeader()togetAuthHeaders()returning header objects based on auth mode (PAT vs OAuth) - Updated
ConnectionManagerto usePRIVATE-TOKENheader for static/PAT mode - Updated all affected unit tests to expect
PRIVATE-TOKENinstead ofAuthorization: Bearerin static mode
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/utils/fetch.ts | Refactored authentication header logic to return appropriate headers based on auth mode (PRIVATE-TOKEN for PAT, Bearer for OAuth) |
| src/services/ConnectionManager.ts | Updated GraphQL client initialization to use PRIVATE-TOKEN header in static/PAT mode |
| tests/unit/utils/fetch.test.ts | Updated test assertions to expect PRIVATE-TOKEN header instead of Authorization Bearer |
| tests/unit/services/ConnectionManagerEnhanced.test.ts | Updated test assertion to expect PRIVATE-TOKEN header in ConnectionManager initialization |
Cover getAuthHeaders() for PAT, OAuth, and no-token scenarios. Cover ConnectionManager OAuth mode initializing without static headers.
|
🎉 This PR is included in version 6.41.4 🎉 The release is available on: Your semantic-release bot 📦🚀 |
polaz
added a commit
that referenced
this pull request
Jan 24, 2026
* feat: detect token scopes at startup with graceful degradation (#188) Add TokenScopeDetector service that calls /api/v4/personal_access_tokens/self at startup to discover token scopes. Based on detected scopes: - Skip GraphQL introspection when token lacks api/read_api (no 401 stack traces) - Register only tools matching the token's permissions - Show clean INFO messages with actionable fix URLs - Warn when token expires within 7 days Also adds comprehensive authentication documentation (docs/guide/authentication.md) with PAT and OAuth walkthroughs, scope comparison table, and troubleshooting. Links added across all installation/deployment docs. * chore(release): 6.41.4 [skip ci] ## [6.41.4](v6.41.3...v6.41.4) (2026-01-24) ### Bug Fixes * **auth:** use PRIVATE-TOKEN header for PAT authentication instead of Bearer ([#189](#189)) ([7799dde](7799dde)), closes [#187](#187) * fix(auth): use enhancedFetch and UTC dates in token scope detection - Replace global fetch with enhancedFetch in detectTokenScopes and detectVersionViaREST (respects timeouts, proxy, TLS settings) - Parse expires_at as UTC date to avoid timezone off-by-one errors - Use URL/URLSearchParams for proper encoding in getTokenCreationUrl - Derive totalTools count dynamically from getToolScopeRequirements() - Use jest.useFakeTimers() for deterministic expiry tests - Test project/group token types, REST fallback, scope-gated paths * fix(auth): deduplicate getTokenCreationUrl call, remove as-any casts - Cache getTokenCreationUrl result in logTokenScopeInfo to avoid double URL construction - Replace `as any` with proper GitLabScope[] type in test fixtures * fix(token-scope): validate API response with Zod, remove manage_context from scope map Replace unsafe `as` type cast on /personal_access_tokens/self response with Zod schema validation via safeParse(). Returns null with a debug log if the response shape doesn't match expectations. Remove manage_context from TOOL_SCOPE_REQUIREMENTS since it manages local session state and never calls GitLab API — it's always available. * fix(token-scope): deep-clone scope map, preserve URL subpath, align doc counts - getToolScopeRequirements() now returns deep clone (arrays copied too) - getTokenCreationUrl() preserves subpath for self-hosted instances - Documentation updated: 43 scope-gated tools, read_user=2, read_api=23 - Example log output fixed to show URL-encoded comma (%2C) * fix(token-scope): validate scopes via z.enum, remove unreliable token type heuristic - Replace unsafe `as GitLabScope[]` cast with z.enum validation that filters unknown scopes (future GitLab scopes are silently ignored) - Derive GitLabScope type from const array via z.infer - Remove token type detection by name prefix — token names are user-controlled and cannot reliably determine token type * fix(token-scope): clarify log wording, use unknown token type, add scope filter test - Log message now says "scope-gated tools" to clarify count excludes always-available tools like manage_context - tokenType defaults to "unknown" since type cannot be reliably inferred - Add RegistryManager unit test verifying scope-based tool filtering * fix(test): update tokenType assertion to match unknown default * fix(token-scope): handle schemeless URL, fix expiry-today logic, update docs - getTokenCreationUrl() now catches URL parse errors for schemeless baseUrl and falls back to string concatenation - daysUntilExpiry === 0 now logs "expires today" instead of "has expired" - Troubleshooting docs updated to match current log format * Update src/services/ConnectionManager.ts Co-authored-by: Copilot <[email protected]> * Update src/services/TokenScopeDetector.ts Co-authored-by: Copilot <[email protected]> * fix(test): update schemeless URL assertion for URLSearchParams encoding --------- Co-authored-by: semantic-release-bot <[email protected]> Co-authored-by: Copilot <[email protected]>
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-TOKENheader instead ofAuthorization: BearerAuthorization: Beareras beforegetAuthorizationHeader()togetAuthHeaders()returning a header object based on auth modeTest plan
Closes #187