OAuth代理服务

MCP Shield是为OpenShift上的MCP服务器提供的OAuth代理服务,支持OAuth 2.0发现、客户端注册和令牌交换,并具有增强安全性的代理令牌系统。

  • by jpinsonneau
  • Go
  • 本地部署
  • 5 星标
  • 更新于
在 GitHub 查看 jpinsonneau/mcp-shield

使用说明

MCP屏蔽

MCP Shield是OpenShift上MCP服务器的OAuth代理。它为MCP服务器提供OAuth 2.0发现、客户端注册和令牌交换,具有特定于OpenShift的处理和用于增强安全性的代理令牌系统。

支持的MCP服务器:

备注:MCP Shield已经与Claude(Anthropic的人工智能助理)作为MCP客户进行了测试。该实现旨在与任何遵循OAuth 2.0流并具有承载令牌身份验证的MCP客户端一起工作。

特性

  • OAuth发现:实施 /.well-known/oauth-authorization-server OAuth 2.0发现的端点
  • 客户注册:实施 /oauth/register 静态客户端配置的端点
  • OAuth启动流:实施 /oauth2/start 重定向到具有回调代理支持的OpenShift OAuth的端点
  • OAuth回调:实施 /oauth/callback 处理OpenShift回调和重定向到原始客户端重定向URI的端点
  • 代币交换:实施 /oauth/token 具有过滤功能的端点 resource=undefined 参数和redirect_uri修复
  • 代理令牌系统:为客户端生成代理令牌,而不是公开真实的用户令牌,从而增强安全性
  • MCP代理:代理人 /mcp 根路径(/)向MCP服务器后端发出请求,将代理令牌交换为真实令牌
  • CORS支持:为基于浏览器的OAuth流正确配置CORS标头
  • 动态重定向URI支持:通过回调代理机制处理来自MCP客户端(如代理CLI)的动态localhost重定向URI

环境变量

  • OAUTH_AUTHORIZATION_SERVERS (必填):以逗号分隔的授权服务器URL列表(应为可访问MCP Shield的公共URL)

    • 用于导出网关URL和回调URL
    • 例子: https://prometheus-mcp-server.apps.example.com
  • INSPECTOR_ORIGIN (可选):MCP检查器的源URL(用于CORS标头)

    • 默认为 * (允许所有来源)如果未设置
    • 例子: https://mcp-inspector.apps.example.com
  • OAUTH_CLIENT_ID (可选):OAuth客户端ID必须与OpenShift中的OAuthClient名称匹配

    • 默认为 prometheus-mcp-server 如果未设置
    • 必须匹配 metadata.name OAuthClient资源的
  • OAUTH_REDIRECT_URIS (可选):以逗号分隔的附加重定向URI列表

    • 默认重定向URI是从以下位置自动生成的 OAUTH_AUTHORIZATION_SERVERS 和 INSPECTOR_ORIGIN
    • 例子: https://custom-redirect.example.com/callback,https://another.example.com/callback
  • OPENSHIFT_OAUTH_TOKEN_URL (可选):OpenShift OAuth令牌端点URL

    • 汽车衍生自 OAUTH_AUTHORIZATION_SERVERS 如果未设置
    • 格式: https://oauth-openshift.apps.<cluster-domain>/oauth/token
    • 通常不需要手动设置
  • MCP_BACKEND_URL (可选):MCP服务器后端容器的URL

    • 默认为 http://localhost:8080 如果未设置
    • 自动网关检测:MCP Shield通过调用其 /status 端点
    • 如果被检测为网关:MCP Shield会自动发现上游服务器,并将工具调用直接路由到它们。会话管理通过以下方式自动处理 initialize 在JSON正文和HTTP标头中都包含会话ID的调用(mcp-session-id)
    • 如果未检测到网关:MCP Shield将其用作所有MCP请求(包括工具调用)的常规回退。不尝试直接路由,请求按原样转发到后端
    • 例子: http://localhost:8080 (适用于同一吊舱中的侧车)或 http://mcp-gateway:8080 (用于网关发现)
    • 看 直接工具布线 详见
  • MCP_BACKEND_PATH (可选):将请求转发到的后端路径端点

    • 默认为 /mcp 如果未设置(适用于Prometheus MCP服务器)
    • 对于Loki MCP服务器,设置为 /stream (洛基使用 /stream 对于HTTP, /mcp 适用于SSE)
    • 例子: MCP_BACKEND_PATH=/stream (适用于洛基MCP服务器)
  • PROXY_TOKEN_TTL (可选):代理令牌的生存时间

    • 默认为 24h 如果未设置
    • 格式:Go持续时间字符串(例如。, 24h, 12h, 1h30m)
    • 代理令牌在此持续时间后过期,必须刷新
    • 例子: PROXY_TOKEN_TTL=12h

建筑

本地建设

go build ./cmd/mcp-shield

Docker构建

# Build the image
docker build -t quay.io/<MY_USER>/mcp-shield:dev .

# Or use the Makefile
make docker-build

推送到注册表

# Push the image
docker push quay.io/<MY_USER>/mcp-shield:dev

# Or use the Makefile
make docker-push

跑步

本地

./mcp-shield -listen :8080 -log-level info

码头工人

docker run -p 8080:8080 \
  -e OAUTH_AUTHORIZATION_SERVERS=https://your-mcp-server.apps.example.com \
  -e INSPECTOR_ORIGIN=https://mcp-inspector.apps.example.com \
  quay.io/<MY_USER>/mcp-shield:dev

端点

OAuth端点

  • GET /.well-known/oauth-authorization-server -OAuth 2.0发现元数据

    • 返回OAuth授权服务器元数据,包括颁发者、端点、支持的授权类型等。
    • MCP客户端用于发现OAuth配置
  • GET/POST /oauth/register -客户端注册端点

    • 返回静态客户端配置(client_id、redirect_uris等)
    • 同时支持GET和POST方法
    • MCP Inspector用于动态客户端注册
  • GET /oauth2/start -OAuth授权流启动

    • 接受OAuth授权请求参数
    • 拦截动态本地主机重定向URI,并替换为固定回调URL
    • 在状态参数中存储原始重定向URI
    • 重定向到OpenShift OAuth授权端点
  • GET /oauth/callback -OAuth回调处理程序

    • 从OpenShift OAuth服务器接收授权码
    • 从状态参数中提取原始重定向URI
    • 将客户端重定向到具有授权码的原始重定向URI
  • POST /oauth/token -令牌交换端点

    • 接受授权码并交换访问令牌
    • 过滤掉 resource=undefined 参数(OpenShift拒绝它)
    • 修复了redirect_uri以匹配授权步骤
    • 添加带有client_id的Basic Auth标头(OpenShift要求)
    • 代理对OpenShift OAuth令牌端点的请求
    • 将访问令牌返回给客户端

MCP代理端点

  • POST /mcp -MCP协议端点

    • 将MCP协议请求代理到MCP服务器后端
    • 转发 Authorization 带有Bearer令牌的标头(代理CLI在每次请求时都会发送令牌)
    • 转发所有请求标头和Cookie
    • 返回MCP服务器响应
    • 备注:MCP服务器是无状态的-它从每个请求的Authorization标头中提取令牌
  • POST /mcp/ -MCP协议端点(尾随斜线)

    • 同 /mcp 但带有尾随斜线支持
  • POST / -根路径MCP代理

    • 处理对根路径的POST请求(由某些MCP客户端(如代理CLI)使用)
    • 转发给MCP处理程序
    • 非POST请求返回404

公用设施端点

  • GET /healthz -健康检查端点
    • 退货 200 OK 与身体 ok
    • 用于活性和准备状态探针

用法

MCP Shield被设计为与MCP服务器一起作为sidecar容器运行。每个受支持的MCP服务器都有详细的部署指南:

MCP服务器端点差异

不同的MCP服务器对HTTP请求使用不同的端点路径:

  • 普罗米修斯MCP服务器:用途 /mcp HTTP请求的端点

    • 配置: MCP_BACKEND_PATH=/mcp (这是默认设置)
  • 洛基MCP服务器:用途 /stream HTTP请求的端点

    • 配置: MCP_BACKEND_PATH=/stream
    • 注:洛基 /mcp 端点用于SSE(服务器发送事件),而不是HTTP POST请求
    • 还需要 sessionId JSON-RPC请求中的注入(由MCP Shield自动处理)
  • Kubernetes MCP服务器:用途 /mcp HTTP请求的端点

    • 配置: MCP_BACKEND_PATH=/mcp (这是默认设置)
    • 注意:虽然kubernetes mcp服务器支持外部OAuth(代理众所周知的端点),但它没有实现完整的OAuth流程。MCP Shield提供完整的OAuth 2.0流程实现。

这 MCP_BACKEND_PATH 环境变量允许您为MCP服务器类型配置正确的端点。

地方发展

对于本地开发和测试:

# Build the binary
go build ./cmd/mcp-shield

# Run with environment variables
export OAUTH_AUTHORIZATION_SERVERS="https://your-mcp-server.apps.example.com"
export INSPECTOR_ORIGIN="https://mcp-inspector.apps.example.com"
./mcp-shield -listen :8080 -log-level debug

建筑

MCP Shield被设计为与MCP服务器一起作为sidecar服务运行,处理需要特殊处理以实现OpenShift集成的OAuth相关端点。

OAuth流程图

下图说明了完整的OAuth身份验证流程:

sequenceDiagram
    participant Client as MCP Client<br/>(Agentic CLI, Inspector)
    participant Proxy as MCP Shield<br/>(Sidecar)
    participant OpenShift as OpenShift<br/>OAuth Server
    participant MCP as MCP Server<br/>(prometheus-mcp-server)

    Note over Client,MCP: 1. Discovery Phase
    Client->>Proxy: GET /.well-known/oauth-authorization-server
    Proxy-->>Client: OAuth discovery metadata<br/>(issuer, endpoints, etc.)

    Client->>Proxy: POST /oauth/register
    Proxy-->>Client: Client registration info<br/>(client_id, redirect_uris)

    Note over Client,MCP: 2. Authorization Phase
    Client->>Proxy: GET /oauth2/start?<br/>response_type=code&<br/>client_id=...&<br/>redirect_uri=localhost:XXXX/callback
    Note over Proxy: Intercepts localhost redirect_uri<br/>Replaces with fixed callback URL<br/>Stores original in state parameter
    Proxy->>OpenShift: Redirect to /oauth/authorize<br/>with fixed redirect_uri
    OpenShift->>Client: User login page
    Client->>OpenShift: User credentials
    OpenShift->>Proxy: Redirect to /oauth/callback<br/>with authorization code
    Note over Proxy: Extracts original redirect_uri<br/>from state parameter
    Proxy->>Client: Redirect to original<br/>localhost:XXXX/callback<br/>with authorization code

    Note over Client,MCP: 3. Token Exchange Phase
    Client->>Proxy: POST /oauth/token<br/>grant_type=authorization_code&<br/>code=...&<br/>redirect_uri=localhost:XXXX/callback
    Note over Proxy: Fixes redirect_uri to<br/>match authorization step<br/>Filters resource=undefined<br/>Adds Basic Auth (client_id)
    Proxy->>OpenShift: POST /oauth/token<br/>with fixed parameters
    OpenShift-->>Proxy: Real user access token
    Note over Proxy: Generates proxy token<br/>Stores mapping:<br/>proxy_token -> real_token
    Proxy-->>Client: Proxy token<br/>(not real user token)

    Note over Client,MCP: 4. MCP Requests Phase
    Client->>Proxy: POST /mcp<br/>Authorization: Bearer <proxy_token>
    Note over Proxy: Exchanges proxy token<br/>for real user token
    Proxy->>MCP: Forward request<br/>Authorization: Bearer <real_token>
    MCP->>MCP: Validate real token<br/>Extract user info
    MCP->>Proxy: MCP response
    Proxy-->>Client: MCP response

流程步骤说明

  1. 发现阶段:

    • 客户端请求OAuth发现元数据以了解可用端点
    • 客户端自行注册(或接收静态客户端配置)
  2. 授权阶段:

    • 客户端使用动态localhost重定向URI启动OAuth流
    • MCP Shield拦截并将其替换为固定的回调URL
    • 用户使用OpenShift进行身份验证
    • OpenShift重定向到固定回调URL
    • MCP Shield从状态参数中提取原始重定向URI并重定向客户端
  3. 代币交换阶段:

    • 客户端交换访问令牌的授权码
    • MCP Shield修复了redirect_uri以匹配授权步骤
    • MCP屏蔽滤出 resource=undefined 参数(OpenShift拒绝它)
    • MCP Shield添加了带有client_id的基本身份验证(OpenShift要求)
    • MCP Shield从OpenShift接收真实用户令牌
    • MCP Shield生成代理令牌 并存储映射(proxy_token->real_token)
    • 客户端接收代理令牌 (不是真正的用户令牌)
    • 代理令牌仅适用于此MCP Shield实例
  4. MCP请求阶段:

    • 代理CLI客户端在本地缓存代理令牌 (客户端)收到后
    • 客户端使用代理令牌发出MCP请求 Authorization: Bearer <proxy_token> 头球
    • MCP Shield将代理令牌兑换为真实用户令牌 转发到MCP服务器之前
    • MCP Shield在中使用真实用户令牌转发请求 Authorization MCP服务器的标头
    • MCP服务器无状态 -它从每个请求的Authorization标头中提取Bearer令牌
    • MCP服务器使用真实令牌代表用户向Prometheus/Thanos进行身份验证
    • 安全利益:代理CLI客户端永远无法访问真实的用户令牌-它们只能将代理令牌用于此MCP Shield实例
    • 不维护服务器端会话-每个请求都是独立的

代理令牌安全模型

代理令牌系统提供了一个重要的安全层:

问题:如果没有代理令牌,代理CLI客户端将缓存真正的OpenShift OAuth令牌,它可能是:

  • 用于访问用户有权访问的任何OpenShift资源
  • 从客户端缓存中提取并恶意使用
  • 如果客户端受到威胁,则存在安全风险

解决方案:MCP Shield生成的代理令牌:

  • ✅ 不能在MCP屏蔽之外使用:代理令牌仅对此特定的MCP Shield实例有效
  • ✅ 适用于MCP访问:通过MCP Shield发出MCP请求时,代理令牌只能兑换为真实令牌
  • ✅ 时间有限:代理令牌在可配置的TTL后过期(默认值:24小时)
  • ✅ 没有直接的OpenShift访问权限:即使代理令牌被泄露,它也不能直接用于访问OpenShift资源——它必须通过MCP Shield

运作原理:

  1. 用户使用OpenShift OAuth进行身份验证
  2. MCP Shield从OpenShift接收真实用户令牌
  3. MCP Shield生成安全的随机代理令牌
  4. MCP Shield存储映射: proxy_token -> real_token (在内存中,未持久化)
  5. 代理CLI客户端接收并缓存代理令牌
  6. 当代理CLI客户端发出MCP请求时,MCP Shield会将代理令牌交换为真实令牌
  7. 真实令牌仅在服务器端使用,从不向客户端公开

比较

有关与替代解决方案的详细比较,请参阅 比较,其中包括:

  • 为什么不使用官方的OpenShift oauth代理? -身份验证方法、OAuth发现端点和用例的差异
  • 为什么不使用mcp网关? -架构差异、OAuth实现差异和用例指南