Skip to content

Fall back to access_token query param when token/info rejects the Bearer header - #640

Open
zaporylie wants to merge 3 commits into
zereight:mainfrom
zaporylie:token-info-query-fallback
Open

Fall back to access_token query param when token/info rejects the Bearer header#640
zaporylie wants to merge 3 commits into
zereight:mainfrom
zaporylie:token-info-query-fallback

Conversation

@zaporylie

Copy link
Copy Markdown

Problem

Some GitLab instances sit behind an edge cache that strips the Authorization header on /oauth/* paths while passing it through on /api/v4/*. Observed on git.drupalcode.org (Drupal's GitLab, fronted by Varnish):

  • GET /oauth/token/info with Authorization: Bearer <valid token>401 {"error":"invalid_token","error_description":"The access token is invalid"}
  • GET /oauth/token/info?access_token=<same token>200
  • GET /api/v4/user with the same Bearer header → 200

Since verifyAccessToken() in the MCP OAuth proxy only uses the Bearer-header form, every /mcp request fails bearer validation on such instances — clients (e.g. claude.ai's connector) complete the full OAuth flow successfully, then loop refresh → 401 → refresh and give up. Nothing is logged server-side, which makes this painful to diagnose (found it via tcpdump inside the container's network namespace).

Fix

On a 401 from the Bearer-header call, retry /oauth/token/info once with the RFC 6750 access_token query parameter, which Doorkeeper also accepts. All other responses keep the existing behavior.

Verified against git.drupalcode.org: with this change the claude.ai connector completes OAuth, initializes an MCP session, and lists tools normally.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1be76ab2-7729-47cc-94ac-08647fdf9576

📥 Commits

Reviewing files that changed from the base of the PR and between 4b33084 and ca9caa9.

📒 Files selected for processing (1)
  • test/mcp-oauth-tests.ts
📜 Recent review details
🔇 Additional comments (3)
test/mcp-oauth-tests.ts (3)

515-519: LGTM!

Also applies to: 549-562


575-606: LGTM!


608-636: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved GitLab token validation by retrying with an alternate authentication format when the initial request is unauthorized.
    • Preserved existing handling for valid tokens and other validation failures.

Walkthrough

verifyAccessToken retries GitLab token introspection with an encoded access_token query parameter after a 401 bearer-header response. Tests cover retry, success, and non-401 failure behavior.

Changes

OAuth token verification

Layer / File(s) Summary
Token introspection fallback
oauth-proxy.ts, test/mcp-oauth-tests.ts
verifyAccessToken retries /oauth/token/info with an encoded access_token query parameter after a 401 response. Tests verify the retry, successful bearer authentication without retry, and non-401 failures without fallback.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: zereight

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: retrying with the access_token query parameter when Bearer authentication fails.
Description check ✅ Passed The description directly explains the GitLab cache problem, the fallback behavior, and the observed verification results.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@oauth-proxy.ts`:
- Around line 672-681: Add fallback-specific regression tests for the token
validation flow around the 401 retry in the relevant OAuth proxy test suite.
Mock the first request to return 401 when sent with the Bearer Authorization
header, then verify the retry uses a correctly URL-encoded access_token query
parameter and succeeds; also verify non-401 responses perform no retry.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: dc588d91-b9e9-4bae-9652-f9cc7d78ad23

📥 Commits

Reviewing files that changed from the base of the PR and between 926d42c and 0a33bc8.

📒 Files selected for processing (1)
  • oauth-proxy.ts
📜 Review details
🔇 Additional comments (2)
oauth-proxy.ts (2)

679-681: 🔒 Security & Privacy

Security Misconfiguration (CWE-319): Cleartext Transmission of Sensitive Information

Reachability: External

Require HTTPS for the fallback request.

Line 680 sends the token in the request target. This class does not validate that _gitlabBaseUrl uses https:. Verify that provider creation rejects http: URLs before this fallback can run. If it does not, enforce an HTTPS base URL.


679-681: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Sensitive Data Exposure (CWE-598)

Reachability: External

Protect the token when the fallback uses a query parameter.

Line 680 puts a replayable bearer token in the request URL. encodeURIComponent prevents syntax injection. It does not prevent retention in access logs, traces, or cache keys.

Make this fallback an explicit deployment opt-in for instances with verified query-token redaction. Confirm that GitLab and the edge cache do not persist access_token values. Otherwise, a user with access to those records can replay the token.

Comment thread oauth-proxy.ts
@coderabbitai
coderabbitai Bot requested a review from zereight August 7, 2026 06:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/mcp-oauth-tests.ts`:
- Line 519: Update the request tracking and assertions around the OAuth retry
test to validate the full authentication contract: the initial request must use
the Authorization header with Bearer ${TOKEN}, while the query-parameter retry
must omit the authorization header. Replace the boolean-only hasAuthHeader check
in the request records and assert both the header value and retry behavior for
the relevant requests.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 94e6fd26-3ff6-4e5c-bb1b-a18e09f7765b

📥 Commits

Reviewing files that changed from the base of the PR and between 0a33bc8 and 4b33084.

📒 Files selected for processing (1)
  • test/mcp-oauth-tests.ts
📜 Review details
🔇 Additional comments (3)
test/mcp-oauth-tests.ts (3)

566-597: LGTM!


599-626: LGTM!


515-515: 🎯 Functional Correctness

No duplicate requests declaration to fix.

Comment thread test/mcp-oauth-tests.ts Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant