trustgraph/docs/tech-specs/mcp-tool-bearer-token.zh-cn.md

563 lines
22 KiB
Markdown
Raw Normal View History

---
layout: default
title: "MCP 工具承载令牌身份验证规范"
parent: "Chinese (Beta)"
---
# MCP 工具承载令牌身份验证规范
> **Beta Translation:** This document was translated via Machine Learning and as such may not be 100% accurate. All non-English languages are currently classified as Beta.
> **⚠️ 重要提示:仅限单租户环境**
>
> 本规范描述了一种用于 MCP 工具的**基本服务级别身份验证机制**。它**不是**一个完整的身份验证解决方案,**不适用于**以下情况:
> - 多用户环境
> - 多租户部署
> - 联合身份验证
> - 用户上下文传播
> - 基于用户的授权
>
> 此功能为**每个 MCP 工具提供一个静态令牌**,该令牌在所有用户和会话中共享。 如果您需要基于用户的身份验证或基于租户的身份验证,则此功能不适合您。
## 概述
**功能名称**: MCP 工具承载令牌身份验证支持
**作者**: Claude 代码助手
**日期**: 2025-11-11
**状态**: 正在开发中
### 执行摘要
允许 MCP 工具配置指定可选的承载令牌,用于对受保护的 MCP 服务器进行身份验证。 这允许 TrustGraph 安全地调用托管在需要身份验证的服务器上的 MCP 工具,而无需修改代理或工具调用接口。
**重要提示**: 这是一个基本身份验证机制,旨在用于单租户、服务到服务的身份验证场景。 它**不适用于**以下情况:
需要不同用户凭据的多用户环境
需要每个租户隔离的多租户部署
联合身份验证场景
基于用户的身份验证或授权
动态凭据管理或令牌刷新
此功能为每个 MCP 工具配置提供一个静态、系统范围的承载令牌,该令牌在所有用户和该工具的调用中共享。
### 问题陈述
目前MCP 工具只能连接到公共可访问的 MCP 服务器。 许多生产 MCP 部署需要通过承载令牌进行身份验证以提高安全性。 如果没有身份验证支持:
MCP 工具无法连接到受保护的 MCP 服务器
用户必须要么公开 MCP 服务器,要么实现反向代理
没有一种标准化的方法将凭据传递给 MCP 连接
无法在 MCP 终端节点上强制执行安全最佳实践
### 目标
[ ] 允许 MCP 工具配置指定可选的 `auth-token` 参数
[ ] 更新 MCP 工具服务,使其在连接到 MCP 服务器时使用承载令牌
[ ] 更新 CLI 工具以支持设置/显示身份验证令牌
[ ] 保持与未进行身份验证的 MCP 配置的向后兼容性
[ ] 记录令牌存储的安全注意事项
### 非目标
动态令牌刷新或 OAuth 流程(仅限静态令牌)
存储令牌的加密(配置系统安全性不在范围之内)
替代身份验证方法基本身份验证、API 密钥等)
令牌验证或到期检查
**基于用户的身份验证**: 此功能**不支持**用户特定的凭据
**多租户隔离**: 此功能**不提供**基于租户的令牌管理
**联合身份验证**: 此功能**不与**身份提供商SSO、OAuth、SAML 等)集成
**基于上下文的身份验证**: 令牌不是基于用户上下文或会话传递的
## 背景和上下文
### 当前状态
MCP 工具配置存储在 `mcp` 配置组中,具有以下结构:
```json
{
"remote-name": "tool_name",
"url": "http://mcp-server:3000/api"
}
```
MCP 工具服务使用 `streamablehttp_client(url)` 连接到服务器,而无需任何身份验证头信息。
### 限制
**当前系统限制:**
1. **不支持身份验证:** 无法连接到需要身份验证的 MCP 服务器。
2. **安全风险:** MCP 服务器必须是公开可访问的,或者仅使用网络级别的安全措施。
3. **生产部署问题:** 无法遵循 API 端点的安全最佳实践。
**此解决方案的限制:**
1. **仅支持单租户:** 每个 MCP 工具只有一个静态令牌,所有用户共享该令牌。
2. **不支持按用户身份验证:** 无法以不同的用户身份进行身份验证,也无法传递用户上下文。
3. **不支持多租户:** 无法按租户或组织隔离凭据。
4. **仅支持静态令牌:** 不支持令牌刷新、轮换或过期处理。
5. **服务级别身份验证:** 仅对 TrustGraph 服务进行身份验证,而不是对单个用户进行身份验证。
6. **共享安全上下文:** 对 MCP 工具的所有调用都使用相同的凭据。
### 使用场景适用性
**✅ 适用场景:**
单租户 TrustGraph 部署。
服务到服务身份验证TrustGraph → MCP 服务器)。
开发和测试环境。
TrustGraph 系统访问的内部 MCP 工具。
所有用户共享相同 MCP 工具访问级别的场景。
静态、长期有效的服务凭据。
**❌ 不适用场景:**
需要按用户身份验证的多用户系统。
需要租户隔离的多租户 SaaS 部署。
联合身份验证场景SSO、OAuth、SAML
需要将用户上下文传播到 MCP 服务器的系统。
需要动态令牌刷新或短生命周期的令牌的环境。
不同的用户需要不同权限级别的应用程序。
用户级别审计跟踪的合规性要求。
**示例适用场景:**
单个组织的 TrustGraph 部署,其中所有员工都使用相同的内部 MCP 工具例如公司数据库查询。MCP 服务器需要身份验证以防止外部访问,但所有内部用户都具有相同的访问级别。
**示例不适用场景:**
一个多租户 TrustGraph SaaS 平台,其中租户 A 和租户 B 需要访问各自隔离的 MCP 服务器,并使用不同的凭据。此功能不支持按租户管理令牌。
### 相关组件
**trustgraph-flow/trustgraph/agent/mcp_tool/service.py**: MCP 工具调用服务。
**trustgraph-cli/trustgraph/cli/set_mcp_tool.py**: 用于创建/更新 MCP 配置的 CLI 工具。
**trustgraph-cli/trustgraph/cli/show_mcp_tools.py**: 用于显示 MCP 配置的 CLI 工具。
**MCP Python SDK**: `streamablehttp_client` from `mcp.client.streamable_http`
## 要求
### 功能性要求
1. **MCP 配置身份验证令牌:** MCP 工具配置必须支持一个可选的 `auth-token` 字段。
2. **Bearer 令牌使用:** 当配置了 auth-token 时MCP 工具服务必须发送 `Authorization: Bearer {token}` 头信息。
3. **CLI 支持:** `tg-set-mcp-tool` 必须接受一个可选的 `--auth-token` 参数。
4. **令牌显示:** `tg-show-mcp-tools` 必须指示是否配置了 auth-token出于安全考虑已屏蔽
5. **向后兼容性:** 现有不带 auth-token 的 MCP 工具配置必须继续正常工作。
### 非功能性要求
1. **向后兼容性:** 对于现有的 MCP 工具配置,不得有任何破坏性更改。
2. **性能:** 对 MCP 工具的调用不会产生任何显著的性能影响。
3. **安全性:** 令牌存储在配置中(请注意安全隐患)。
### 用户故事
1. 作为 **DevOps 工程师**,我希望配置 MCP 工具的 bearer 令牌,以便我可以保护 MCP 服务器端点。
2. 作为 **CLI 用户**,我希望在创建 MCP 工具时设置身份验证令牌,以便我可以连接到受保护的服务器。
3. 作为 **系统管理员**,我希望查看哪些 MCP 工具配置了身份验证,以便我可以审计安全设置。
## 设计
### 高级架构
扩展 MCP 工具配置和服务以支持 bearer 令牌身份验证:
1. 向 MCP 工具配置模式添加一个可选的 `auth-token` 字段。
2. 修改 MCP 工具服务以读取 auth-token 并将其传递给 HTTP 客户端。
3. 更新 CLI 工具以支持设置和显示身份验证令牌。
4. 记录安全注意事项和最佳实践。
### 配置模式
**当前模式:**
```json
{
"remote-name": "tool_name",
"url": "http://mcp-server:3000/api"
}
```
**新的模式**(带可选的认证令牌):
```json
{
"remote-name": "tool_name",
"url": "http://mcp-server:3000/api",
"auth-token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```
**字段描述**:
`remote-name` (可选): MCP 服务器使用的名称(默认为配置键)
`url` (必需): MCP 服务器端点 URL
`auth-token` (可选): 用于身份验证的 Bearer token
### 数据流
1. **配置存储**: 用户运行 `tg-set-mcp-tool --id my-tool --tool-url http://server/api --auth-token xyz123`
2. **配置加载**: MCP 工具服务通过 `on_mcp_config()` 回调接收配置更新
3. **工具调用**: 当工具被调用时:
服务从配置中读取 `auth-token`(如果存在)
创建 headers 字典:`{"Authorization": "Bearer {token}"}`
将 headers 传递给 `streamablehttp_client(url, headers=headers)`
MCP 服务器验证 token 并处理请求
### API 变更
没有外部 API 变更,仅为配置模式扩展。
### 组件详情
#### 组件 1: service.py (MCP 工具服务)
**文件**: `trustgraph-flow/trustgraph/agent/mcp_tool/service.py`
**目的**: 在远程服务器上调用 MCP 工具
**所需变更**(在 `invoke_tool()` 方法中):
1. 检查 `auth-token` 是否在 `self.mcp_services[name]` 配置中
2. 如果 token 存在,则构建包含 Authorization header 的 headers 字典
3. 将 headers 传递给 `streamablehttp_client(url, headers=headers)`
**当前代码**42-89 行):
```python
async def invoke_tool(self, name, parameters):
try:
if name not in self.mcp_services:
raise RuntimeError(f"MCP service {name} not known")
if "url" not in self.mcp_services[name]:
raise RuntimeError(f"MCP service {name} URL not defined")
url = self.mcp_services[name]["url"]
if "remote-name" in self.mcp_services[name]:
remote_name = self.mcp_services[name]["remote-name"]
else:
remote_name = name
logger.info(f"Invoking {remote_name} at {url}")
# Connect to a streamable HTTP server
async with streamablehttp_client(url) as (
read_stream,
write_stream,
_,
):
# ... rest of method
```
**修改后的代码**:
```python
async def invoke_tool(self, name, parameters):
try:
if name not in self.mcp_services:
raise RuntimeError(f"MCP service {name} not known")
if "url" not in self.mcp_services[name]:
raise RuntimeError(f"MCP service {name} URL not defined")
url = self.mcp_services[name]["url"]
if "remote-name" in self.mcp_services[name]:
remote_name = self.mcp_services[name]["remote-name"]
else:
remote_name = name
# Build headers with optional bearer token
headers = {}
if "auth-token" in self.mcp_services[name]:
token = self.mcp_services[name]["auth-token"]
headers["Authorization"] = f"Bearer {token}"
logger.info(f"Invoking {remote_name} at {url}")
# Connect to a streamable HTTP server with headers
async with streamablehttp_client(url, headers=headers) as (
read_stream,
write_stream,
_,
):
# ... rest of method (unchanged)
```
#### 组件 2: set_mcp_tool.py (命令行配置工具)
**文件**: `trustgraph-cli/trustgraph/cli/set_mcp_tool.py`
**目的**: 创建/更新 MCP 工具配置
**所需更改**:
1. 向 argparse 添加 `--auth-token` 可选参数
2. 在提供时,将 `auth-token` 包含在配置 JSON 中
**当前参数**:
`--id` (必需): MCP 工具标识符
`--remote-name` (可选): 远程 MCP 工具名称
`--tool-url` (必需): MCP 工具 URL 端点
`-u, --api-url` (可选): TrustGraph API URL
**新参数**:
`--auth-token` (可选): 用于身份验证的 Bearer token
**修改后的配置构建**:
```python
# Build configuration object
config = {
"url": args.tool_url,
}
if args.remote_name:
config["remote-name"] = args.remote_name
if args.auth_token:
config["auth-token"] = args.auth_token
# Store configuration
api.config().put([
ConfigValue(type="mcp", key=args.id, value=json.dumps(config))
])
```
#### 组件 3show_mcp_tools.py (命令行显示工具)
**文件**: `trustgraph-cli/trustgraph/cli/show_mcp_tools.py`
**目的**: 显示 MCP 工具的配置
**需要修改的内容**:
1. 在输出表中添加 "Auth" 列
2. 根据是否存在 auth-token 显示 "是" 或 "否"
3. 不要显示实际的 token 值(出于安全考虑)
**当前输出**:
```
ID Remote Name URL
---------- ------------- ------------------------
my-tool my-tool http://server:3000/api
```
**新的输出:**
```
ID Remote Name URL Auth
---------- ------------- ------------------------ ------
my-tool my-tool http://server:3000/api Yes
other-tool other-tool http://other:3000/api No
```
#### 组件 4文档
**文件**: `docs/cli/tg-set-mcp-tool.md`
**需要修改的内容**:
1. 文档新的 `--auth-token` 参数
2. 提供带有身份验证的示例用法
3. 文档安全注意事项
## 实施计划
### 第一阶段:创建技术规范
[x] 编写全面的技术规范,记录所有更改
### 第二阶段:更新 MCP 工具服务
[ ] 修改 `invoke_tool()` 中的 `service.py` 以从配置文件读取 auth-token
[ ] 构建 headers 字典并传递给 `streamablehttp_client`
[ ] 使用经过身份验证的 MCP 服务器进行测试
### 第三阶段:更新 CLI 工具
[ ] 向 `set_mcp_tool.py` 添加 `--auth-token` 参数
[ ] 在配置 JSON 中包含 auth-token
[ ] 向 `show_mcp_tools.py` 的输出添加 "Auth" 列
[ ] 测试 CLI 工具的更改
### 第四阶段:更新文档
[ ] 在 `tg-set-mcp-tool.md` 中记录 `--auth-token` 参数
[ ] 添加安全注意事项部分
[ ] 提供示例用法
### 第五阶段:测试
[ ] 测试 MCP 工具是否能够使用 auth-token 成功连接
[ ] 测试向后兼容性(没有 auth-token 的工具仍然可以工作)
[ ] 测试 CLI 工具是否能够正确接受和存储 auth-token
[ ] 测试 "show" 命令是否能够正确显示身份验证状态
### 代码更改摘要
| 文件 | 更改类型 | 行数 | 描述 |
|------|------------|-------|-------------|
| `service.py` | 修改 | ~52-66 | 添加 auth-token 读取和 header 构建 |
| `set_mcp_tool.py` | 修改 | ~30-60 | 添加 --auth-token 参数和配置存储 |
| `show_mcp_tools.py` | 修改 | ~40-70 | 向显示添加 Auth 列 |
| `tg-set-mcp-tool.md` | 修改 | 各种 | 文档新的参数 |
## 测试策略
### 单元测试
**Auth Token 读取**: 测试 `invoke_tool()` 是否能够正确从配置文件读取 auth-token
**Header 构建**: 测试 Authorization header 是否能够使用 Bearer 前缀正确构建
**向后兼容性**: 测试没有 auth-token 的工具是否能够正常工作
**CLI 参数解析**: 测试 `--auth-token` 参数是否能够正确解析
### 集成测试
**经过身份验证的连接**: 测试 MCP 工具服务是否能够连接到经过身份验证的服务器
**端到端**: 测试 CLI → 配置文件存储 → 服务调用,并使用 auth token
**不需要 Token**: 测试连接到未经过身份验证的服务器是否仍然可以工作
### 手动测试
**真实的 MCP 服务器**: 使用需要 bearer token 身份验证的实际 MCP 服务器进行测试
**CLI 工作流程**: 测试完整的流程:使用 auth 设置工具 → 调用工具 → 验证成功
**显示屏蔽**: 验证身份验证状态显示,但 token 值不暴露
## 迁移和发布
### 迁移策略
不需要迁移 - 这是一个纯粹的附加功能:
现有的 MCP 工具配置,如果没有 `auth-token`,可以继续正常工作
新的配置可以选择包含 `auth-token` 字段
CLI 工具接受,但不要求 `--auth-token` 参数
### 发布计划
1. **第一阶段**: 将核心服务更改部署到开发/测试环境
2. **第二阶段**: 部署 CLI 工具更新
3. **第三阶段**: 更新文档
4. **第四阶段**: 生产发布,并进行监控
### 回滚计划
核心更改是向后兼容的 - 现有的工具不受影响
如果出现问题,可以通过删除 header 构建逻辑来禁用身份验证 token 处理
CLI 更改是独立的,并且可以单独回滚
## 安全注意事项
### ⚠️ 关键限制:仅支持单租户身份验证
**此身份验证机制不适用于多用户或多租户环境。**
**共享凭据**: 所有用户和调用都共享每个 MCP 工具的相同 token
**没有用户上下文**: MCP 服务器无法区分不同的 TrustGraph 用户
**没有租户隔离**: 所有租户共享每个 MCP 工具的相同凭据
**审计跟踪限制**: MCP 服务器日志显示来自相同凭据的所有请求
**权限范围**: 无法为不同的用户强制执行不同的权限级别
**不要使用此功能,如果:**
您的 TrustGraph 部署服务于多个组织(多租户)
您需要跟踪哪些用户访问了哪些 MCP 工具
不同的用户需要不同的权限级别
您需要遵守用户级别的审计要求
您的 MCP 服务器强制执行每个用户的速率限制或配额
**多用户/多租户场景的替代方案:**
通过自定义头部实现用户上下文传播
为每个租户部署独立的 TrustGraph 实例
使用网络级别隔离VPCs、服务网格
实现一个代理层,该层处理每个用户的身份验证
### 令牌存储
**风险:** 身份验证令牌以明文形式存储在配置系统中
**缓解措施:**
记录令牌以明文形式存储
尽可能推荐使用短寿命令牌
推荐对配置存储进行适当的访问控制
考虑未来增强功能,用于加密令牌存储
### 令牌泄露
**风险:** 令牌可能出现在日志或 CLI 输出中
**缓解措施:**
不要记录令牌值(仅记录“身份验证已配置:是/否”)
CLI 显示命令仅显示屏蔽状态,不显示实际令牌
不要将令牌包含在错误消息中
### 网络安全
**风险:** 令牌通过未加密的连接传输
**缓解措施:**
记录推荐使用 HTTPS URL 进行 MCP 服务器访问
警告用户使用 HTTP 传输的明文风险
### 配置访问
**风险:** 未授权访问配置系统会暴露令牌
**缓解措施:**
记录保护配置系统访问的重要性
推荐对配置访问采用最小权限原则
考虑对配置更改进行审计日志记录(未来增强功能)
### 多用户环境
**风险:** 在多用户部署中,所有用户共享相同的 MCP 凭据
**风险理解:**
用户 A 和用户 B 在访问 MCP 工具时都使用相同的令牌
MCP 服务器无法区分不同的 TrustGraph 用户
没有办法强制执行每个用户的权限或速率限制
MCP 服务器上的审计日志显示来自相同凭据的所有请求
如果一个用户的会话被盗,攻击者将拥有与所有用户相同的 MCP 访问权限
**这不是一个错误 - 这是一个该设计的基本限制。**
## 性能影响
**最小开销:** 头部构建添加了可忽略的处理时间
**网络影响:** 额外的 HTTP 头部增加了每个请求约 50-200 字节
**内存使用:** 存储在配置中的令牌字符串会增加可忽略的内存
## 文档
### 用户文档
[ ] 使用 `--auth-token` 参数更新 `tg-set-mcp-tool.md`
[ ] 添加安全注意事项部分
[ ] 提供使用 bearer 令牌的示例
[ ] 记录令牌存储的影响
### 开发人员文档
[ ] 在 `service.py` 中添加身份验证令牌处理的内联注释
[ ] 记录头部构建逻辑
[ ] 更新 MCP 工具配置模式文档
## 开放问题
1. **令牌加密:** 我们是否应该在配置系统中实现加密令牌存储?
2. **令牌刷新:** 未来是否支持 OAuth 刷新流程或令牌轮换?
3. **替代身份验证方法:** 我们是否应该支持 Basic 身份验证、API 密钥或其他方法?
## 考虑过的替代方案
1. **环境变量用于令牌:** 将令牌存储在环境变量中而不是配置中
**已拒绝:** complicates deployment and configuration management (使部署和配置管理复杂化)
2. **单独的密钥存储:** 使用专用的密钥管理系统
**推迟:** Out of scope for initial implementation, consider future enhancement (超出初始实现的范围,考虑未来增强)
3. **多种身份验证方法:** 支持 Basic、API 密钥、OAuth 等。
**已拒绝:** Bearer tokens cover most use cases, keep initial implementation simple (Bearer 令牌涵盖大多数用例,保持初始实现的简单性)
4. **加密令牌存储:** 在配置系统中加密令牌
**推迟:** Configuration system security is broader concern, defer to future work (配置系统安全是一个更广泛的问题,推迟到未来工作)
5. **按调用令牌:** 允许在调用时传递令牌
**已拒绝:** Violates separation of concerns, agent shouldn't handle credentials (违反了关注点分离,代理不应处理凭据)
## 引用
[MCP 协议规范](https://github.com/modelcontextprotocol/spec)
[HTTP Bearer 身份验证 (RFC 6750)](https://tools.ietf.org/html/rfc6750)
[Current MCP Tool Service](../trustgraph-flow/trustgraph/agent/mcp_tool/service.py)
[MCP 工具参数规范](./mcp-tool-arguments.md)
## 附录
### 用法示例
**设置带有身份验证的 MCP 工具:**
```bash
tg-set-mcp-tool \
--id secure-tool \
--tool-url https://secure-server.example.com/mcp \
--auth-token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
**展示 MCP 工具:**
```bash
tg-show-mcp-tools
ID Remote Name URL Auth
----------- ----------- ------------------------------------ ------
secure-tool secure-tool https://secure-server.example.com/mcp Yes
public-tool public-tool http://localhost:3000/mcp No
```
### 配置示例
**存储在配置系统中**:
```json
{
"type": "mcp",
"key": "secure-tool",
"value": "{\"url\": \"https://secure-server.example.com/mcp\", \"auth-token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\"}"
}
```
### 安全最佳实践
1. **使用 HTTPS**: 始终为具有身份验证的 MCP 服务器使用 HTTPS URL。
2. **短生命周期令牌**: 尽可能使用具有过期时间的令牌。
3. **最小权限**: 授予令牌最低要求的权限。
4. **访问控制**: 限制对配置系统的访问。
5. **令牌轮换**: 定期轮换令牌。
6. **审计日志记录**: 监控配置更改以检测安全事件。