思想领袖
你的 MCP 服务器很安全,但其背后的账本却并非如此。

最近,Gil Feig 在 Unite.AI 发表的一篇文章中,列出了构建安全 MCP 服务器的六项最佳实践。这些建议切实可行,任何要部署 MCP 服务器的人都应该遵循。他建议为每个集成“设置专属的细粒度角色,并严格限定为所需权限”,这完全正确。不过,这也以另一端的系统支持细粒度角色为前提。这揭示了一个鲜少被明说的更广泛假设:服务器背后的系统也能达到同等的安全标准。
在商业软件领域,这往往做不到。我负责一个工程团队,团队维护着一个集成层,可连接 32 个会计和 ERP 系统,并可在其上部署 MCP 服务器。我们经常看到这样的情况:代理在我们这边经过了良好的身份验证、权限范围限定和日志记录,却向那些根本无从得知代理曾参与其中的系统写入数据。
本文关注的是问题的另一半:上游系统实际上提供了什么、你可以通过集成层控制什么,以及这种控制的边界在哪里。
MCP 规范的职责边界
这份MCP 授权规范对自身边界的界定很明确。MCP 服务器对其客户端而言是 OAuth 资源服务器。调用上游 API 时,它会作为独立的 OAuth 客户端运行,并使用由上游系统签发的独立令牌。明确禁止转发客户端的令牌。
这是正确的设计。但这也意味着,上游调用的所有事项——包括谁有权执行哪些操作,以及这些操作如何被记录——完全取决于上游系统。上游系统不提供的能力,规范无法补上。
这同样适用于OWASP 关于过度代理行为的指导原则。它建议将代理的扩展在其他系统中持有的权限限制在最低必要范围内,并在其所代表用户的上下文中执行操作。这两点建议都很好。但二者都假定另一个系统能够表达最低权限要求和用户上下文。
上游系统实际提供了什么
以下是从集成方的角度来看,我们所连接的 32 个会计和 ERP 系统的情况。
三分之一的系统完全不支持 OAuth
32 个系统中有 21 个使用 OAuth。其余 11 个依赖静态凭据:API 密钥、用户名和密码,或一对令牌。其中一些密钥永不过期。有一个广泛使用的系统在其文档中说明,只要用户账号存在,其 API 令牌就会无限期有效。
令牌有效期长,撤销能力弱
OAuth 带来的帮助没有你期望的那么大。有一家服务提供商颁发的刷新令牌有效期约为 20 年。这种凭据的设计寿命甚至超过使用它的代理、构建该代理所用的框架,而且很可能还超过点击“允许”的那个人。在另一个系统中,连访问令牌都不会过期。
凭据一旦发放,接下来就要看谁能将其停用。相关标准OAuth 令牌撤销(RFC 7009)自 2013 年起就已存在。然而,大约十分之四的系统没有提供任何技术手段让集成方撤销凭据。所有使用 API 密钥的系统都属于这一类。唯一剩下的办法,就是要求客户手动删除访问权限。
权限范围粗略,无法识别代理身份
大多数静态密钥直接继承创建者用户的全部权限;只有少数系统允许将密钥权限限制到特定端点。许多 OAuth 系统支持权限范围,但通常划分得比较粗略,例如“会计:读写”。在我们考察的 32 个系统中,没有一个能通过 API 在同一笔交易中同时记录代理及其代表的用户。外部代理显示为连接它们的用户,或一个通用系统用户。值得注意的是,如果供应商在自己的产品中内置了代理,例如Microsoft 在 Business Central 中所做的那样,就会为代理分配专属用户账号。这与我在下文推荐的做法相同,只不过目前仅供供应商自己的代理使用。
集成层可以强制执行哪些措施
这并不意味着只能放弃努力。在代理与会计系统之间,你几乎可以掌控所有环节:
- 为每个代理配置用于访问你自己的集成层的凭据
- 设置自己的权限范围,例如仅允许读取发票
- 记录每次代理调用的审计日志,并注明代理代表的用户
- 使用幂等键,避免重试的代理重复登记同一张发票
- 为每个代理设置速率限制
- 在执行任何写入操作前设置审批步骤
这些措施都不取决于目标系统支持什么。如今,在集成层构建功能完备的访问控制层完全可行;如果你让代理接触任何财务数据,就应该构建这样一层。
控制的边界
但你无法将这一层的保护扩展到目标系统边界之外。到了那里,三件事就会出问题。
归因
在会计系统中,代理的写入操作会显示为授权连接的人,或者显示为某个技术用户。审计该系统的人看到的,是由该用户提交的记录。他们无法判断操作是由人还是代理执行的。对账簿而言,一个凌晨 3 点登记 400 张发票的代理,看起来和一位非常勤勉的财务经理毫无区别。要还原实际情况,就得查集成商的日志;这与权威记录系统所依赖的信任链并不相同。对于取证或审计来说,这是一个不利局面。
大多数组织在这方面也并没有走在前面。在一项Cloud Security Alliance 调查中,只有 28% 的受访者表示,他们能够在所有环境中可靠地追溯代理操作,并将其归因于某个人或某个系统;另有 44% 的受访者已经在使用或计划为代理使用静态 API 密钥。
最小权限
你可以强制规定代理只能读取发票。但如果目标系统不支持权限范围,位于你这一层之后的凭据仍然拥有完全访问权限。任何拿到这些凭据的人都能彻底绕过你这一层,以及你通过这一层设置的所有规则。
撤销
你可以立即切断自己的代理。但如果目标系统本身的凭据遭到泄露,这也无济于事。而对于十分之四没有撤销接口的系统,唯一的紧急停用办法就是给客户发邮件。
务实之选:为代理创建专用用户
今天最实用的做法并不引人注目:在目标系统中为代理创建一个专用用户,并且只通过该用户连接代理。
只要系统允许创建用户,这种做法就行得通,还能实现集成层无法做到的三件事:
- 在权威记录系统中追溯操作来源。记录会显示为“应付账款代理”所提交,而不是显示为六个月前点击“连接”的财务经理所提交。
- 即使没有相应的 API,也能撤销访问。客户可以在界面中停用该用户,因此即使系统没有撤销接口,这种方法也有效。
- 实现部分最小权限控制。只要系统具备某种角色模型,通常就可以将代理用户的权限限制在其实际需要的模块内。
这样做确实有成本。有人必须在开户时手动创建该用户,而这恰恰会在最不合适的时候增加操作阻力。大约一半的系统会对每个额外用户收费,费用从小型企业工具每月几欧元到完整 ERP 系统每月一百多欧元不等。还有几家会根据套餐限制用户数量,因此多增加一个用户,就可能意味着整个公司都要升级到更贵的套餐。此外,无人负责的服务用户本身也会带来风险,成为 Unite.AI 此前报道过的非人类身份泛滥问题的一部分。和其他账户一样,它也需要指定负责人并设定审查日期。
这也无法为那些不支持权限范围的系统补上这一功能。但它能让操作归因和访问撤销重新回到审计人员真正会查看的系统中。
结构性解决方案:委托身份
从理论上说,正确的解决方案早已存在。OAuth 2.0 令牌交换(RFC 8693)区分了模拟身份与委托。在委托模式下,代理保留自己的身份,令牌则通过“act”声明记录它是代表某个人行事。
应用到会计系统中,这意味着:
- 账簿会记录该代理代表某个人提交了记录
- 权限范围按委托逐次授予,而不是按用户授予
- 无需触及个人账户,就可以撤销单次委托
据我所知,这 32 个系统中没有一个支持类似机制。因此,目前它仍只是一个发展方向,还不是可用选项。这意味着,应当向会计和 ERP 软件提供商提出这一要求,而不是把它当成集成商的任务:代理已经在向你们的账簿写入数据,你们的 API 应当能够明确记录这一点。
代理接触账簿前该做什么
如果你要将代理接入会计或 ERP 系统,可以先按以下简短清单逐项检查:
- 梳理每个目标系统的凭据模型。它使用 OAuth 还是静态密钥?凭据的有效期有多长?是否设有权限范围?能否撤销?
- 无论如何,都要构建自己的访问控制层。无论目标系统提供什么功能,代理身份、权限范围、幂等性和审批机制都应由你在自己的系统一侧落实。
- 只要系统允许,就为代理使用专用用户。接受开户所需的工作量和许可费用,把它们视为实现操作可追溯性的代价。
- 确保你自己的审计轨迹具备防篡改能力。对于许多系统而言,这将是唯一能够证明代理曾参与其中的记录。
- 记录剩余风险。如果某个系统没有权限范围和撤销机制,就应向客户说明这一点,并将其记录在自己的风险登记册中。
边界才是关键
保护好你的 MCP 服务器是必要的,但这还不够。能够写入账本的智能体是否安全,取决于你的层与权威记录系统之间的边界;而如今,这条边界由系统决定,而非由你决定。
好消息是,这一缺口界定得很清楚。相关标准已经存在。缺少的是对这些标准的支持,而这种支持必须来自保存账簿的系统。












