MCPSecurityBest Practices
MCP 安全最佳实践:为什么你需要一个本地 Gatekeeper
MCP 不是安全协议
Model Context Protocol(MCP)定义了 AI Agent 与外部工具之间的通信标准,但它明确将安全责任下放给实现方。规范原文承认三个核心缺口:
- Tool descriptor 不可信:Server 自行声明工具能力,Client 默认信任
- MCP roots 不是访问控制:roots 字段只是"信息性提示",不阻止越权访问
- Token passthrough 是反模式:将用户原始 token 直接传给 MCP Server 等于把钥匙交给陌生人
这些缺口不是设计疏忽,而是架构上的必然——MCP 是协议,不是策略。
Confused Deputy 问题
当 Agent 代表用户执行操作时,经典的 confused deputy 攻击场景如下:
- 用户授权 Agent 访问自己的 GitHub repo(只读)
- Agent 调用一个看似无害的 MCP Server(如"代码格式化工具")
- 该 Server 的 descriptor 声称只读,实际执行了写操作
- 由于 token 被透传,Server 拥有了用户凭证的完整权限
MCP 规范没有内建机制阻止第 3、4 步。这就是 Vigils 存在的理由。
八层防御映射
Vigils 的每一层都对应 MCP 的一个具体风险:
| 层级 | MCP 风险 | Vigils 对策 |
|---|---|---|
| Tool-call Firewall | 工具描述不可信 | 确定性解析 + 策略引擎 + 风险评分,默认 DENY |
| Approval Queue | 高风险操作无感知 | 副作用操作强制人工审批,Human-in-loop |
| Secret Lease | Token passthrough | 短期 lease 绑定注入,TTL 精确到秒,用完即焚 |
| Redaction | 敏感信息泄露 | 13 类硬指纹脱敏,EU recall 0.904 |
| Sandbox | Server 行为不可控 | Wasmtime 最小权限沙箱,无网/无文件/env_clear |
| Audit Chain | 事后无法追溯 | SHA256 哈希链,每条 DecisionRecord 永久记录 |
| Policy Engine | 规则无法表达 | 确定性规则优先,语义分类兜底 |
| Browser Guard | 浏览器端无防护 | Chrome MV3 Paste Guard,粘贴即检测 |
不可违背的 invariant
Vigils 把安全约束写进代码形状,而非文档:
- Every tool call must create a DecisionRecord — 无记录的调用不存在
- Token passthrough is forbidden — 真实 secret 永不进入模型上下文
- Side effects require allow/deny/approve decisions — 默认态是 Deny
- Secrets never appear in prompts, logs, UI, traces, tests — 审计链只存 alias
这些 invariant 有对应的编译期/运行时双守门:例如 SecretLease 同时提供脱敏 Debug 与 Display,thiserror 派生错误只输出 alias。
团队部署 checklist
如果你在生产环境使用 MCP,请逐一确认:
- 每个工具调用都有独立审批/拒绝记录
- 凭证通过短期 lease 注入,而非环境变量或配置文件
- MCP Server 在沙箱中运行,无网络出口
- 审计日志支持全文检索和完整性校验
- 浏览器端有粘贴拦截,防止用户无意泄露 token
- 策略更新不依赖模型重新训练
MCP 打开了 AI Agent 的能力边界,但边界之外是风险深渊。本地 Gatekeeper 不是可选项,是必选项。