使用说明
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-serverOAuth 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.nameOAuthClient资源的
- 默认为
-
OAUTH_REDIRECT_URIS(可选):以逗号分隔的附加重定向URI列表- 默认重定向URI是从以下位置自动生成的
OAUTH_AUTHORIZATION_SERVERS和INSPECTOR_ORIGIN - 例子:
https://custom-redirect.example.com/callback,https://another.example.com/callback
- 默认重定向URI是从以下位置自动生成的
-
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服务器 -使用prometheus mcp服务器进行部署的完整指南
- 洛基MCP服务器 -使用loki mcp服务器部署的完整指南
- Kubernetes MCP服务器 -使用kubernetes mcp服务器进行部署的完整指南
- MCP网关 -使用mcp网关进行部署的完整指南
MCP服务器端点差异
不同的MCP服务器对HTTP请求使用不同的端点路径:
-
普罗米修斯MCP服务器:用途
/mcpHTTP请求的端点- 配置:
MCP_BACKEND_PATH=/mcp(这是默认设置)
- 配置:
-
洛基MCP服务器:用途
/streamHTTP请求的端点- 配置:
MCP_BACKEND_PATH=/stream - 注:洛基
/mcp端点用于SSE(服务器发送事件),而不是HTTP POST请求 - 还需要
sessionIdJSON-RPC请求中的注入(由MCP Shield自动处理)
- 配置:
-
Kubernetes MCP服务器:用途
/mcpHTTP请求的端点- 配置:
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
流程步骤说明
-
发现阶段:
- 客户端请求OAuth发现元数据以了解可用端点
- 客户端自行注册(或接收静态客户端配置)
-
授权阶段:
- 客户端使用动态localhost重定向URI启动OAuth流
- MCP Shield拦截并将其替换为固定的回调URL
- 用户使用OpenShift进行身份验证
- OpenShift重定向到固定回调URL
- MCP Shield从状态参数中提取原始重定向URI并重定向客户端
-
代币交换阶段:
- 客户端交换访问令牌的授权码
- MCP Shield修复了redirect_uri以匹配授权步骤
- MCP屏蔽滤出
resource=undefined参数(OpenShift拒绝它) - MCP Shield添加了带有client_id的基本身份验证(OpenShift要求)
- MCP Shield从OpenShift接收真实用户令牌
- MCP Shield生成代理令牌 并存储映射(proxy_token->real_token)
- 客户端接收代理令牌 (不是真正的用户令牌)
- 代理令牌仅适用于此MCP Shield实例
-
MCP请求阶段:
- 代理CLI客户端在本地缓存代理令牌 (客户端)收到后
- 客户端使用代理令牌发出MCP请求
Authorization: Bearer <proxy_token>头球 - MCP Shield将代理令牌兑换为真实用户令牌 转发到MCP服务器之前
- MCP Shield在中使用真实用户令牌转发请求
AuthorizationMCP服务器的标头 - 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
运作原理:
- 用户使用OpenShift OAuth进行身份验证
- MCP Shield从OpenShift接收真实用户令牌
- MCP Shield生成安全的随机代理令牌
- MCP Shield存储映射:
proxy_token -> real_token(在内存中,未持久化) - 代理CLI客户端接收并缓存代理令牌
- 当代理CLI客户端发出MCP请求时,MCP Shield会将代理令牌交换为真实令牌
- 真实令牌仅在服务器端使用,从不向客户端公开
比较
有关与替代解决方案的详细比较,请参阅 比较,其中包括:
- 为什么不使用官方的OpenShift oauth代理? -身份验证方法、OAuth发现端点和用例的差异
- 为什么不使用mcp网关? -架构差异、OAuth实现差异和用例指南