Skip to content

feat: OAuth bearer token verification via userinfo endpoint#107

Open
r33drichards wants to merge 2 commits intomainfrom
feat/oauth-bearer-token-auth
Open

feat: OAuth bearer token verification via userinfo endpoint#107
r33drichards wants to merge 2 commits intomainfrom
feat/oauth-bearer-token-auth

Conversation

@r33drichards
Copy link
Copy Markdown
Owner

Summary

  • Adds --oauth-userinfo-url CLI flag (and OAUTH_USERINFO_URL env var) for validating opaque OAuth bearer tokens
  • Calls the configured userinfo endpoint (e.g. https://api.github.com/user) with the Bearer token to validate and extract user claims
  • Merges verified claims (sub, login) into mcp_headers for OPA policy evaluation
  • Adds --oauth-sub-key to configure which response field maps to sub (defaults to id for GitHub)
  • Works alongside existing --jwks-url JWT verification (they can be used independently or together)

This enables GitHub OAuth tokens from a backend like NextAuth.js to flow through to filesystem isolation policies without requiring JWKS/JWT infrastructure.

Test plan

  • Build with cargo build — compiles cleanly
  • Run with --oauth-userinfo-url=https://api.github.com/user and pass a valid GitHub token as Authorization: Bearer <token>
  • Verify claims are merged into mcp_headers (check logs)
  • Verify invalid tokens are rejected (userinfo returns 401)
  • Verify OPA filesystem policy can use input.mcp_headers.sub from OAuth claims

🤖 Generated with Claude Code

Add --oauth-userinfo-url flag that validates opaque OAuth bearer tokens
(e.g. GitHub access tokens) by calling a userinfo endpoint. Verified
claims (sub, login) are merged into mcp_headers for OPA policy evaluation.

This enables GitHub OAuth tokens from a Next.js backend to flow through
to filesystem isolation policies without requiring JWKS/JWT infrastructure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 8, 2026

MCP-V8 Load Test Benchmark Report

Comparison of single-node vs 3-node cluster at various request rates.

Results

Topology Target Rate Actual Iter/s HTTP Req/s Exec Avg (ms) Exec p95 (ms) Exec p99 (ms) Success % Dropped Max VUs
cluster-stateful 100/s 48 1896.6 1929.67 5110.57 5132.74 70.3% 2879 100
cluster-stateful 200/s 51 3742 3678.45 5135.81 5152.5 40.3% 8680 200
cluster-stateless 1000/s 410.1 1503.2 2287.87 10000.28 12611.57 47% 34162 1000
cluster-stateless 100/s 99.9 317.1 61.35 104.08 107.11 100% 4 14
cluster-stateless 200/s 199.4 683.6 75.89 113.43 208.79 100% 22 39
cluster-stateless 500/s 443.2 1287.5 766.25 3229.01 5479.06 78% 2781 500
single-stateful 100/s 19.2 1872.8 4951.64 5137.74 5146.48 6.7% 4755 100
single-stateful 200/s 37.8 3815.7 5124.22 5152.5 5167.91 0% 9601 200
single-stateless 1000/s 1000 1000 0 0 0 0% 0 100
single-stateless 100/s 99.9 302.4 53.92 54.96 103.95 100% 1 11
single-stateless 200/s 199.5 614.9 60.49 106.14 124.68 100% 10 30
single-stateless 500/s 399.8 992.1 454.93 3034.59 7413.36 14.8% 6012 500

P95 Latency

Topology Rate P95 (ms)
cluster-stateful 100/s 5110.57 ████████████████████████████
cluster-stateful 200/s 5135.81 ████████████████████████████
cluster-stateless 100/s 104.08 ███████████████
cluster-stateless 200/s 113.43 ███████████████
cluster-stateless 500/s 3229.01 ██████████████████████████
cluster-stateless 1000/s 10000.28 ██████████████████████████████
single-stateful 100/s 5137.74 ████████████████████████████
single-stateful 200/s 5152.5 ████████████████████████████
single-stateless 100/s 54.96 █████████████
single-stateless 200/s 106.14 ███████████████
single-stateless 500/s 3034.59 ██████████████████████████
single-stateless 1000/s 0 ``

Notes

  • Target Rate: The configured constant-arrival-rate (requests/second k6 attempts)
  • Actual Iter/s: Achieved iterations per second (each iteration = 1 POST /api/exec)
  • HTTP Req/s: Total HTTP requests per second (1 per iteration)
  • Dropped: Iterations k6 couldn't schedule because VUs were exhausted (indicates server saturation)
  • Topology: single = 1 MCP-V8 node; cluster = 3 MCP-V8 nodes with Raft

…m compat

deno_core provides a bare V8 runtime without Web APIs. Libraries like
isomorphic-git expect Buffer, Blob, btoa, atob, and process to exist.

Add minimal JS polyfills injected before user code runs:
- Buffer: Uint8Array subclass with Node.js Buffer API
- Blob: spec-compatible with arrayBuffer/text/slice/stream
- btoa/atob: base64 encode/decode (needed by esm.sh node shims)
- process: stub with env/browser/version for npm package compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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