MCP 选中工具之后,到安全执行之间还缺什么?

发布时间:2026/7/22 14:08:11
MCP 选中工具之后,到安全执行之间还缺什么? 一张面向生产环境的职责地图MCP 与工具服务负责什么Agent Runtime 负责什么共享执行控制负责什么企业身份与审批系统负责什么以及为什么业务系统仍然必须保留最终授权。一个 Agent 已经通过 MCP 发现了工具生成了符合inputSchema的参数并成功发出一次tools/call。这时这项业务操作算完成了吗如果工具只是查询天气、读取本地文件答案可能接近“是”。但只要工具开始创建退款、修改库存、停用员工账号、批量发送通知或触发生产部署一次协议调用成功就只代表请求已经沿着一条技术通道到达某个工具服务。它还不能单独证明这次行动代表的是正确的人这个人此刻有权操作这条业务数据高风险参数已经得到有效审批网络重试不会造成重复扣款或重复退款超时之后到底执行了还是没有执行部分失败时应该重试、补偿还是人工介入事后留下的记录足以回答“谁以什么身份做了什么”最终业务状态仍然满足系统自己的约束。因此企业真正面对的不是“MCP 能不能调用接口”而是另一个更完整的问题从工具被选中到真实业务后果被安全地形成中间还需要哪些责任这些责任分别应该由谁承担这篇文章不把所有问题都塞给 MCP也不试图再创造一个万能中间层。它只做一件事把这条执行链上容易混在一起的责任拆开。一、MCP 调用成功和业务操作安全完成是两个事件MCP 已经解决了工具发现、结构化参数、调用协议、结果返回等重要问题。对于 HTTP 传输它还有独立的授权规范用来说明受保护的 MCP Server 如何作为 OAuth 资源服务器工作客户端如何获取访问令牌以及令牌为什么必须绑定正确的资源受众。官方安全实践也覆盖了最小权限、会话绑定、凭证保护、沙箱和逐次授权等问题。所以这里讨论的缺口并不是因为“MCP 没有安全设计”。真正的区别在于协议成功和业务完成回答的是两组不同的问题协议成功 一个格式正确的请求是否被送达给了一个允许当前客户端访问的 MCP Server 业务完成 正确的主体是否在正确的业务状态下对正确的对象执行了一次正确的行动 并且审批、幂等、失败恢复和责任证据都与这次行动保持一致协议可以承载行动但协议本身不知道订单ORD-9001现在是否还允许退款员工E-1024是否属于门店S-18这笔订单此前是否已经在另一个入口完成过退款退款金额是否超过当前剩余可退金额这个审批是否批准的正是即将执行的那组参数。这些事实更靠近业务领域而且会随时间变化。它们不能只靠工具描述、模型推理或一次 OAuth 鉴权来推断。二、先把执行链拆成五种责任生产链路最容易犯的错误是把所有组件统称为“Agent 平台”“MCP 网关”或“工具服务”然后默认这个盒子会自然承担全部安全责任。更可验证的做法是先区分五种语义责任层次主要责任不能被误认为工具协议与 MCP Server工具发现、Schema、协议调用、协议授权和工具执行接口每一条业务对象的最终授权者Agent Runtime / 编排器理解任务、选择工具、生成参数、维护工作流状态、呈现人机交互可信业务身份的来源或最终权限系统共享执行控制限定可触达能力、装配可信上下文、解释可移植治理意图、绑定审批快照、协调派发、请求去重、记录统一执行状态企业身份提供者、审批权威、事务协调器或全部业务规则的拥有者企业身份、策略与审批系统解析可信身份、执行组织策略、判断谁有资格批准某类行动真实业务操作本身业务系统强制租户隔离、对象级授权、当前状态校验、业务不变量、事务提交和最终执行决定只要上游说“已审批”就盲目信任的被动后端这五种责任不等于必须部署五个产品。同一个服务可以承担其中多项责任一个组织也可以把它们拆到多个系统。关键在于安全边界应该按照责任来判断而不是按照进程数量来判断。把两个责任放进同一个进程不会让它们自动变成同一件事把它们拆成多个服务也不会自动带来安全性。三、“权限”至少包含三种不同问题很多 Agent 权限管理的讨论之所以混乱是因为大家都在说“有没有权限”但实际说的是三种完全不同的决定。1. 当前客户端能不能访问这个 MCP Server这是协议授权问题。OAuth Scope、Token Audience、过期时间、受保护资源元数据等属于这一层。2. 当前 Agent 场景应该看见哪些能力一个售后 Agent 可能需要order.read和refund.request.create却永远不应该看见employee.delete或tenant.config.update。这是Reach能力触达范围。它在模型选工具、生成参数之前就缩小了最大可达攻击面。3. 当前主体此刻能不能对这个对象执行这项操作这是最终业务 Authority操作人属于哪个租户、门店或组织订单当前是否可退款金额是否在剩余可退范围内是否已经存在另一笔成功退款当前组织策略是否允许这项操作。只有业务系统或者拥有同等新鲜业务上下文的权威系统才能可靠回答这些问题。三者是互补关系MCP 协议授权 - 当前客户端能否访问这个 Server 能力 Reach - 当前 Agent 场景能否触达这个操作 业务 Authority - 当前主体此刻能否执行这一次具体行动一个有效的 MCP Token 不是订单退款授权一份工具白名单不能替代租户隔离业务系统保留最终授权也不意味着可以把所有危险工具都无差别暴露给模型。四、审批、幂等、重试、审计和回滚分别应该放在哪里这些问题都不是加一个字段或挂一个中间件就能完整解决的。它们是端到端属性有自然的主要责任方但必须穿过整条执行链才成立。1. Agent 工具调用审批Agent Runtime 往往最适合展示确认或审批界面共享执行层可以暂停派发并把审批决定绑定到一份规范化请求企业审批系统决定谁有资格批准业务系统在真正写入前仍然要再次执行最终授权。一份有意义的审批绑定至少应覆盖可信主体 能力标识 规范化参数 任务身份如果审批之后参数发生变化原审批不能静默授权新请求。因此“弹过确认框”不等于已经建立审批边界。审批证据必须和将要执行的内容绑定验证方还必须知道这份证据究竟由谁签发、谁有资格签发。2. Agent 重复执行与幂等Runtime 应在重试过程中保持稳定的请求身份共享执行层可以对重复提交去重并保存任务状态业务系统则必须在业务域内执行最终唯一性约束。以退款为例共享执行层可以阻止同一个执行请求被派发两次。但只有订单或支付系统才能保证同一笔业务退款不会从网页后台、定时任务和 Agent 三条不同路径被重复创建。所以“中间层做了幂等”不能替代数据库唯一约束、业务幂等键或领域状态检查。3. 重试、超时与部分失败写操作不能看到 HTTP 超时就盲目重试因为“没有收到响应”不代表“对方没有执行”。一个有状态任务至少应该区分accepted - awaiting_approval - queued - running - succeeded \- rejected \- failed调用方在超时后应该查询或恢复同一个任务身份而不是重新创造一笔新的业务请求。重试策略可以由执行协调层负责但重试是否安全最终仍依赖业务边界上的幂等约束。4. Agent 审计日志与可验证证据普通应用日志主要回答运维问题审计证据要回答责任问题谁发起了行动Agent 代表的是哪个可信主体哪项能力和哪些参数被评估哪条策略或哪次审批影响了执行谁在什么时间派发了什么业务系统最终接受还是拒绝了什么。如果同一个可能被攻陷的 Runtime既能声称“审批已经发生”又能书写唯一的审计记录那么这份记录本质上仍是自述。更高保证等级下可能还需要独立签名的审批证据、只追加存储、外部时间基准或者由业务边界重新验证证据链。共享执行层可以统一记录格式和任务关联但不能因为把一条记录命名为“审计日志”就让自己的声明自动获得独立可信性。5. 回滚、补偿与恢复回滚不是任意工具都天然具备的通用能力。有些动作可逆有些动作需要显式补偿有些动作根本无法撤销。真正的恢复语义属于业务操作本身或者属于理解业务流程的 Workflow / Saga 层。共享执行层可以保存执行状态、暴露失败并触发业务系统已经明确定义的补偿路径但它不能给几个互不相关的 API 标一个atomic: true就凭空制造事务原子性。五、一条最小的生产执行路径以“Agent 帮用户发起订单退款”为例一条可以被审查的路径大致如下1. 用户提出退款要求。 2. Agent Runtime 选择 refund.create并提出参数。 3. MCP Client 使用协议授权调用可信 Server。 4. 执行控制检查当前路由能否触达 refund.create。 5. 可信主体从模型参数之外的可信上下文中解析。 6. 请求 Schema 与治理条件被评估。 7. 如需审批任务暂停在精确参数快照上。 8. 同一任务携带可验证审批证据恢复执行。 9. 派发使用稳定的幂等身份。 10. 业务系统重新校验主体、租户、订单状态、金额和业务不变量。 11. 业务系统提交或拒绝这次操作。 12. 结果和证据链都关联到同一个任务身份。这里不存在一个“做完所有安全”的万能节点。模型提出行动协议承载行动Runtime 协调行动企业系统建立身份和策略信任业务系统授权并提交最终后果。六、每个 MCP 应用都需要独立控制面吗不需要。单用户本地工具、只读能力或者只有一个 Runtime 和少量低后果操作的应用完全可以把这些控制放在 MCP Server 或宿主应用内部。为了概念完整而额外部署新服务只会增加运维成本并不必然提高安全性。当以下情况逐渐出现时共享执行控制才更有价值多个 Agent 框架或 MCP Client 在调用同一批业务系统多个 MCP Server 正在重复实现审批、幂等和审计企业希望不同入口共享同一份能力白名单任务需要跨人工审批、本地执行器或进程重启暂停与恢复执行状态必须在 Runtime 退出后继续存在不同工具的治理证据需要统一比较业务凭证不应该散落到每一个 Agent 应用中。真正的判断标准不是“我们有没有使用 Agent”而是同一组跨工具执行保证是否已经在足够多的地方被重复实现以至于建立共享边界反而能减少不一致和事故半径即便答案是“需要共享控制层”它也应该保持克制协调和执行公共控制不把自己扩张为全部身份、全部策略、全部事务和全部业务真相的来源。七、架构必须明确写出的失败语义与其笼统地说“支持 Agent 治理”不如明确这些失败会发生什么失败情况保守处理可信主体缺失或无法验证不派发要求主体的操作工具元数据或治理声明不可信不根据它提升权限或放宽限制审批证据和精确请求不匹配拒绝执行或重新审批超时后执行状态未知查询同一任务不盲目创建新写请求可重试写操作没有幂等身份拒绝自动重试业务授权失败返回最终拒绝上游审批不能覆盖业务权限审计存储不可用按操作等级执行明确的 fail-open / fail-closed 策略不能假装证据已经落盘没有定义补偿动作报告不可逆或需要人工恢复不能宣称支持回滚这些语义才使不同实现之间可以被比较、被测试也使责任边界在事故发生时不至于消失。八、ACC 与 BailingHub 在这张图中的位置披露我维护两个探索这一问题的开源项目。Agent Capability ContractACC 尝试用可移植、操作级声明表达能力 Reach 与治理意图。它不执行工具不定义企业身份也不替代业务系统的最终授权。BailingHub百灵中枢 尝试实现一个可自托管的共享执行控制面在业务工具调用周围处理能力触达、可信主体、审批绑定、任务状态、派发和追踪。它是一个具体实现不是唯一答案业务系统仍然拥有最终 Authority。这张职责地图并不依赖任何一个项目。组织可以把同样的边界实现在 MCP Server、Agent 平台、API 网关、工作流引擎、共享控制面或者它们的组合中。真正重要的是系统能够不含糊地回答哪个组件控制工具 Reach可信主体来自哪里谁判断需要人工审批谁有资格批准审批授权的究竟是哪一份精确请求重试如何绑定稳定幂等身份谁记录证据谁能独立验证哪个系统执行最终对象级和业务状态授权执行部分完成、状态未知、被拒绝或不可逆时会发生什么MCP 让工具互操作变得现实。从“工具被选中”到“业务后果被安全形成”仍然是一项必须沿整条链路共同构造的端到端属性。参考资料MCP Tools specificationMCP Authorization specificationMCP Security Best PracticesMCP Tasks utilityTool Annotations as Risk Vocabulary: What Hints Can and Can’t Do