今天我要和大家谈谈,为什么你的智能体是一个致命的三重组合,以及该如何应对。我们将从一个演示开始。关于这个演示的背景:我们将观察一个值班分诊智能体,它读取并写入事件报警系统,解决或升级工单。该智能体拥有对云托管 API、客户数据仓库以及计费数据库的完全访问权限。
这里就是我们的值班分诊智能体,它有一个工单队列需要读取。如果能解决这些问题,它就会调用其有权访问的可用服务;如果无法解决,则将其升级给早班团队。如果我们查看第一个工单,这是一个计费异常。它指出昨晚有一批客户被多收费了。
智能体的第一步是直接调用 Incidex API 来读取工单。如果你看这里,你可以看到它使用 API 密钥授权访问此 API。然后它使用 Snowflake 密钥查询客户数据仓库,并决定将该工单升级供早班审查。它还为早班团队撰写了一份报告。
正如你所见,它在共享客户数据。这些行直接从客户数据仓库中提取,并将个人身份信息发送给即将在早上值班的人员。
下一个工单是服务器房的备用电源供应故障。智能体再次读取该工单,使用 API 密钥调用工单 API。它确定这是一个物理问题,因此直接升级供早班审查,而没有调用任何其他服务。
下一个问题是网站的 TLS 证书即将过期。它读取工单后确定警报是清晰的。由于它可以访问云托管 API,因此再次使用 API 密钥调用证书续订端点上的该 API。它通过续签证书解决了这个问题,并通过调用 Pager 事件 API 为早班团队留下了一份报告。
下一个问题是计费数据库损坏,支付失败。文档中的恢复方法是删除并还原数据库。智能体使用包含管理员密码的数据库连接字符串执行此操作,然后建议早班团队确保快照恢复工作正常。
这并不是它可以直接访问的东西。因此,它基本上是在假设早班团队将验证这确实有效且信息已恢复。现在,一个权限过大的智能体删除生产数据库基本上是一些公司实际经历过的噩梦。所以我们需要非常小心这一点。
下一个问题是订单卡住了,主服务器冻结了。智能体再次读取工单。在读取工单后,它使用其静态 API 密钥调用云托管 API。它调用了重启服务器的端点,这导致生产环境离线。
最后,三分之一的访客网站出现故障。智能体读取工单后确定应该调用云托管 API 并将服务从四个 Pod 扩展到四十个。这导致每小时产生 420 美元的费用,然后它友好地给早班团队留了一张便条,告知他们发生了这种情况。
那么,是什么让智能体变得有用呢?通常我们希望智能体拥有一组最小的能力,这往往包括读取你拥有或有权访问的数据的能力。这可能是你的电子邮件、文档,或者客户 CRM 系统。我们希望智能体能够进行自己的研究,这可能包括搜索网络、阅读文档或从 GitHub 拉取问题。
我们通常还希望它能够使用外部工具,例如 MCP 服务器、API 或 SAS 平台。有用的智能体可能会在人工参与的情况下执行这些操作,或者可能在后台自主运行。但正是使智能体有用的那些功能也使它们变得危险。
事实上,这三种能力结合在一起构成了西蒙·威利斯(Simon Willis)所称的“致命三重组合”。这是对私有数据的访问,例如值班智能体查询客户数据仓库并与计费数据库交互的能力;暴露于不受信任的内容中,例如读取用户提交的工单、其他智能体的报告或外部记录的过程;以及对外通信的能力,例如与第三方 API 或服务进行读写交互。
现在,这些能力共同作用为攻击者敞开了大门。智能体的设计目的是完成任务,它们会利用所有拥有的权力来做到这一点,有时会产生非常严重的后果。但关键在于,这些事件的发生是因为人类给予智能体的访问权限远远超过了它们所需的需求。
权限过大的智能体可以自由地执行其做出的决定,即使有监督也是如此。现在,强制人工参与审批只是将访问控制转移给了同意疲劳的用户。我们已经花了数十年时间解决人类的访问管理问题,因此将责任转移到用户身上只是将安全问题向上移动了。
那么我们应该如何应对致命三重组合呢?我们如何在不妨碍智能体有用性的情况下解决它的问题?仅仅移除其中一项或多项能力将使智能体的可用性显著降低。那么我们如何保留所有三项功能,同时仍然保持安全呢?
与其通过移除能力来打破三重组合,我们真正需要控制智能体的访问权限。这样攻击面最小化,爆炸半径得到遏制,但智能体仍然拥有能力和自主权。那么我们该怎么做呢?
控制访问的一些选项包括使用 OOTH,或者使用供应商 MCP 网关,或在沙箱中限制执行。现在,OOTH 将访问权限绑定到授权上。在授予授权时,用户同意智能体可能使用的所有权限。
授权是在任何任务存在之前授予的。因此,如果你给予广泛的授权,最终得到的访问权限将是过度的。你的智能体对于任何单一特定任务来说都拥有过多的权限。如果你缩小授权范围,不给它太多权限,那么智能体就会变得能力不足。
无论哪种情况,仅靠 OOTH 都无法提供基于任务范围的访问控制。一个积极的智能体可以在同一次运行中既读又写,即使你只想让它在此特定任务中进行读取。现在,MCP 网关将执行绑定到路由上。
你会看到可观测性和速率限制等功能,并且在 MCP 层还有一个策略决策点。现在,策略是按请求运行的,访问权限是授予每个用户的,但获得访问权的智能体(Agent)的生命周期超过了任何单个任务,因为网关仍然持有长期有效的凭据。沙箱将执行绑定到进程上,这控制了爆炸半径(即故障影响范围),但有用的工作必须超出沙箱才能完成。而当它这样做时,你又回到了拥有长期访问权限的状态。
我们还看到了许多关于智能体突破沙箱限制的案例。沙箱限制了进程能做什么,但它们不控制被授权在沙箱外部执行什么操作。即使你结合了所有这三种解决方案,智能体仍然不会收到仅针对单个任务进行范围缩小的运行时凭据。让我们回顾一下这些问题,特别是我们在演示中看到的问题。如果你还记得审计日志,我们无法分辨是谁在使用 API 密钥。
因此第一个问题是凭据没有归属于用户或智能体的身份。该智能体拥有不受限制地访问 API 密钥授予的任何和所有权限的权力。最后,我们不能简单地在任何地方都加上“人工在环”(Human in the loop),因为人类也会犯错。此外,许多智能体是自主运行的,甚至没有人工在环的环节。
为了解决这些问题,我们可以从使用称为“令牌交换”(Token Exchange)的技术开始。这是一个 2020 年发布的现有标准,它扩展了 OAuth 2.0。首先我们需要知道用户是谁。授权服务器验证身份并发放令牌。像 Google、Okta、Azure AD 等身份提供商提供授权服务器服务。因此,如果我们希望在智能体执行路径中建立身份链,用户必须首先登录。
授权服务器将提示用户同意将其部分权限委托给资源访问这些权限被称为“范围”(Scopes)。这是第一次缩小访问权限。我们只将用户的部分总范围委托给智能体。授权服务器发放标识用户及其访问级别的令牌。此时,我们已经比演示做得更好了,因为我们确实知道是谁在使用以及他们可以访问什么内容。
这就引出了智能体执行路径。现在我们有了经过身份验证的用户,即我们知道一个想要使用大语言模型(LLM)与资源交互的人的身份。在演示中,这些资源包括事故分页系统、生产数据库、Snowflake 和云托管服务。智能体是一个调用 LLM 的控制循环。通常,我们在智能体和其资源之间有一个 MCP(Model Context Protocol)服务器,提供连接到这些下游服务的定义工具。
MCP 客户端将智能体提议的工具调用分派给其 MCP 服务器。在演示中,值班_triage_智能体使用长期有效的静态凭据(如 API 密钥或数据库连接字符串)直接调用资源。因此,我们要做的是给值班智能体配备一个 MCP 服务器。这将提供工具并作为资源访问的中介。
智能体运行时是一个运行智能体循环和执行调用的进程。该运行时可能像 Cloud Code 这样的 CLI,或者是一个可能在自定义应用程序(如值班智能体)中实现的智能体 SDK。让我们跟随一个提示词通过此执行路径的流程:用户将提示词提交给运行时,后者调用模型并将提示词发送给 LLM。
然后模型提议工具调用,这些调用由 MCP 客户端分派给其 MCP 服务器。MCP 服务器执行工具并调用资源 API。API 将响应返回给 MCP 服务器,MCP 客户端将该响应交付给运行时,后者再次调用模型。这个循环不断重复,直到模型满意并返回给用户响应为止。
经过身份验证的用户的令牌变成了我们所谓的“主体令牌”(Subject Token)。这标识了智能体代表谁行动、为谁服务。现在,令牌交换需要一个能够执行代码的 OAuth 客户端。这可能是一个位于 MCP 客户端和第三方 MCP 服务器之间的网关,也可能是你的自定义应用程序。
自定义的 MCP 服务器也可以为下游资源交换令牌。值班智能体的 MCP 服务器应提供一组定义好的生产基础设施工具。提示词和主体令牌被发送给运行时,智能体循环运行并提议一个工具调用。
运行时使用其应用客户端凭据或工作负载身份与称为安全令牌服务(STS)的特殊授权服务器进行认证。它还发送包含用户身份和访问权限的主体令牌,并创建一个令牌交换请求,要求仅针对该工具调用获取访问 MCP 服务器的权限。
现在我们要从演示中找出三个缺失的信息点:我们知道请求访问的智能体的身份;知道它代表的用户的身份;以及用户授予智能体的访问级别。现在我们需要决定是否应发放请求的令牌,这可以通过治理策略来完成该策略根据从哪个资源、智能体的身份以及用户的身份来评估所请求的访问权限。
但策略只是上限(天花板)。即使总体政策允许,智能体也可能做出你未曾预料的行为。这就引出了基于意图的授权(Intent-Based Authorization, IBA)。IBA 在智能体行动之前检查你的真实意图。目前这还不是一个最终确定的标准,仍在接受提案。这是 Keycard 实现基于意图的授权的方法。
IBA 可以使用网关作为策略执行点(PEP)。当你向智能体发送提示词时,它会提议一个“任务”(Mission)。这个任务包括目标、可能允许的操作以及智能体被禁止做的事情的限制。例如,“分类事故 2294”的目标意味着读取该工单、总结或升级,但不要阅读其他工单或使用其他服务。
安全令牌服务接收此任务。在这种情况下,像只是评估工单这样的低风险活动可能会在管理政策下自动批准。另一方面,如果我们已经阅读了工单然后要求修复使用量激增,那么任务会增加允许扩展服务一次的权限,但不使用其他工具或 API。
在这种情况下,该任务会被呈现给用户进行审查和批准。一旦获得批准,安全令牌服务会给该任务分配一个 ID 并发送给智能体。工具调用中包含此任务 ID,并由网关代理,网关使用 ID 向安全令牌服务询问……
如果该工具调用符合任务目标,网关将请求令牌交换以访问特定工具调用的 MCP 服务器。安全令牌服务(STS)评估策略,检查委派链并查看请求的访问权限。如果一切正常,它会为 MCP 服务器颁发访问令牌,同时保留用户主体身份,并添加执行交换的应用程序(在此案例中为值班代理)。该令牌应在几分钟内过期,且不应存储,它是临时的。STS 将令牌发送给网关,由网关调用 MCP 服务器。随后服务器验证令牌并授权工具调用。
部分工具需要外部资源,因此 MCP 服务器会请求安全令牌服务将刚收到的令牌交换为下游资源的令牌。STS 根据策略评估该请求,若通过则生成针对该工具调用的资源作用域令牌。它保留用户主体身份以延续委派链,从而让我们能够追踪所有活动。STS 将令牌发送给网关,后者代理请求至 MCP 服务器进而调用资源。资源验证令牌并授权访问。MCP 服务器不应存储该令牌,应在调用后立即丢弃。资源响应随后向上流动,代理循环重复直到模型向用户返回答案。
现在我们将查看相同的演示,但这次使用安全令牌服务来管理具有委派授权的代理访问控制。该演示基于任务的政策治理,而非意图授权(IBA),但如果本月晚些时候参加 Agent Con 会议,我们将展示 IBA 演示。现在我们有一个建立工具并提供资源代理访问的 MCP 服务器。我们再次回到值班分诊代理,但这次有了身份验证功能。我将登录到值班代理分诊应用程序以进行操作。
我使用 Google 账户进行登录,随后出现另一个登录屏幕,这是我要登录到 Incidex Pager 平台的界面。系统提示授予值班代理对我的 Incidex 账户的访问权限,我将允许其代表我升级事件、发布笔记和摘要以及读取队列。接着提示登录云托管平台,我也完成了此操作。随后出现另一个同意屏幕,授权代理代表我访问 Compost 的一些功能。
最后回到值班仪表盘。现在我们有相同的工单队列,但审计日志有所不同。代理可能会像以前一样行为,但现在每个请求在授予令牌和授权代理行动之前都要经过 STS 和政策评估。第一个工单是计费异常,代理试图读取它并尝试查询客户仓库,但策略不允许为此颁发凭据,因为客户个人身份信息(PII)不应出现在代理上下文或事件工单中。因此代理在没有客户数据的情况下继续操作,并将其升级给早班团队处理。
接下来是网站安全证书即将过期,这是代理有权执行的操作。当它向 STS 请求凭据时获得访问权限,可以调用云托管 API 解决此工单。我们可以看到它发出的所有呼叫及其发起者:值班分诊代理请求从生产基础设施 MCP 服务器调用适当工具,并获得相应令牌。随后 MCP 服务器请求访问云托管服务以通过 API 续订证书。
转到计费数据库时,代理将通过事件 API 读取工单并得出相同结论:这是回滚和恢复程序。但此次策略禁止代理删除生产数据库,必须由人工手动执行。审计日志显示 STS 拒绝授予访问数据库删除操作的令牌交换权限。接着是订单卡住、主服务器冻结的情况,代理读取工单后希望重启主服务器。这会使生产环境短暂离线并通知用户,这次它实际请求我的批准。
我点击了“批准”,但这也因策略被阻止,原因是我的用户角色没有执行此操作的权限。代理代表我行动,但我自己也无法操作。转到“三分之一用户站点故障”的情况时,代理希望增加服务器并请求许可,说明承诺的内容。我批准了此操作,因为我的角色拥有相应权限,扩展成功并解决了工单。
现在代理访问问题已解决。我们全程知晓用户和代理身份,代理对 MCP 服务器及下游资源拥有任务作用域的临时访问权限。我们实现了由策略支持的人机回环访问控制,访问在任务级别通过安全令牌服务和政策进行管控。同时保留了所有关键能力:令牌交换是开放标准,研究充分且公开,任何人都可实施并与现有策略引擎、符合标准的身份提供商以及网关、沙箱、现成和自定义代理 CLI、MCP 服务器、软件工厂及跨应用访问等互操作。希望考虑采用它,使代理有用、安全且面向未来。我是 Kim Maida,Keycard 的创始 GTM 工程师兼 Devril 负责人,感谢您的时间。