mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-04-25 08:26:21 +02:00
563 lines
22 KiB
Markdown
563 lines
22 KiB
Markdown
|
|
---
|
|||
|
|
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))
|
|||
|
|
])
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 组件 3:show_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. **审计日志记录**: 监控配置更改以检测安全事件。
|