Skip to content

fix: request read_api OAuth scope when GITLAB_READ_ONLY_MODE is enabled#381

Merged
zereight merged 2 commits intozereight:mainfrom
jannahopp:fix/oauth-scope-read-only-mode
Mar 22, 2026
Merged

fix: request read_api OAuth scope when GITLAB_READ_ONLY_MODE is enabled#381
zereight merged 2 commits intozereight:mainfrom
jannahopp:fix/oauth-scope-read-only-mode

Conversation

@jannahopp
Copy link
Copy Markdown
Contributor

Summary

  • When GITLAB_READ_ONLY_MODE=true, the OAuth flow still requested the full api scope, granting read/write access at the token level. The read-only restriction was only enforced at the MCP tool-filtering layer.
  • This changes the requested OAuth scope to read_api when read-only mode is enabled, enforcing least-privilege at the GitLab token level as well.

Notes

  • Users with an existing cached OAuth token will need to re-authenticate after enabling GITLAB_READ_ONLY_MODE, since the required scope changes.
  • GitLab read_api scope should cover all endpoints used by the tools in the readOnlyTools set, but this is worth verifying against edge cases (e.g. job artifact downloads).

Test plan

  • Enable GITLAB_READ_ONLY_MODE=true with OAuth, verify the authorization URL requests read_api scope
  • Confirm all read-only tools work correctly with the read_api token
  • Disable GITLAB_READ_ONLY_MODE, verify api scope is requested as before

When GITLAB_READ_ONLY_MODE=true, the OAuth flow still requested the
full `api` scope, granting read/write access at the token level. The
read-only restriction was only enforced at the MCP tool-filtering
layer. This changes the requested OAuth scope to `read_api` when
read-only mode is enabled, enforcing least-privilege at the GitLab
token level as well.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jannahopp jannahopp force-pushed the fix/oauth-scope-read-only-mode branch from c76a794 to 6103527 Compare March 20, 2026 15:12
1. Replace Math.random() with crypto.randomUUID() for OAuth state
   parameters and request IDs — CSRF tokens must be cryptographically
   unpredictable.

2. HTML-encode the error query parameter in the OAuth callback page
   to prevent reflected XSS.

3. Redirect pino logger to stderr in oauth.ts to prevent JSON log
   lines from polluting the MCP stdio transport channel.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zereight zereight merged commit 0647f5f into zereight:main Mar 22, 2026
5 checks passed
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.

2 participants