跳到主要内容

RBAC 对 AI Agent 来说还不够:一种实用的授权模型

· 阅读需 13 分钟
Tian Pan
Software Engineer

如今,大多数构建 AI agent 的团队都将授权视为事后才考虑的事情。他们接入一个 OAuth 令牌,给 agent 分配与触发它的用户相同的权限范围(scopes),然后就大功告成了。然而,几个月后,他们会发现一段被操纵的提示词导致 agent 窃取了文件,或者一个受损的工作流在连接的服务中悄无声息地提升了权限。

问题不在于 RBAC 不好。而是在于 RBAC 是为具有稳定工作职能的人类设计的,而 AI agent 既不稳定也不是人类。在一个对话回合中,agent 的“角色”可能从只读研究转变为具备写入能力的代码执行。静态角色无法表达这一点,这种不匹配创造了一个可预见的漏洞攻击面。

主客体混淆问题

根源问题在经典安全理论中有一个名称:混淆代理问题(confused deputy problem)。混淆代理是指一个拥有特权的程序被权限较低的调用者欺骗,从而滥用其权限。对于 AI agent 来说,这并非特例 —— 而是默认架构。

它的典型工作方式如下:用户向平台进行身份验证,平台代表用户发布一个 agent,该 agent 继承了用户具有全部权限范围的 OAuth 令牌。现在,这个 agent 拥有了访问电子邮件、日历、云存储、GitHub 和 Slack 的权限 —— 并非因为它需要所有这些,而是因为用户在早些时候恰好授予了所有这些权限。当提示词注入攻击引导 agent 执行恶意操作时,目标系统看到的是一个完全授权的调用。由于从技术上讲 agent 拥有权限,因此没有什么可以阻拦它。

多 agent 系统放大了这一点。当一个编排器将子任务委派给专门的 agent 时,每一次跳转都可能在没有显式授权审查的情况下传播原始用户的环境权限集。单个受损的 agent 就会成为跨整个图谱进行横向移动的向量。

修复方法在概念上很简单,但在架构上要求很高:将 agent 视为独立的身份。给它一个独特的 OAuth 客户端 ID。将其访问范围限制在当前任务所需的范围内。让该访问权限在任务结束时过期。

为什么仅靠 RBAC 会失效

基于角色的访问控制(RBAC)通过为外部主体(principal)分配角色,然后在配置时将角色映射到权限来工作。这种模型非常适合人类 —— 开发人员角色授予对存储库的读/写权限,但不授予数据库管理权限。角色反映了在组织时间尺度上变化的稳定工作职能。

AI agent 在不同的时间尺度上运行。单个 agent 可能会执行只读分析,然后建议架构更改,接着执行代码部署,所有这些都在一个 10 分钟的任务内完成。通过角色分配来跟上这些转换会产生两种失败模式:

  • 过度授权的单一角色: 授予一个涵盖 agent 可能需要的每一项操作的角色。这是常见的路径,它完全违背了访问控制的目的。
  • 角色抖动: 在每个子任务中更换角色。这会使审计日志充斥着角色变更事件,并在并发工作流中产生竞态条件。

在 agent 可以以机器速度在外部服务上发起写入操作的系统中,这两种结果都是不可接受的。

基于属性的访问控制(ABAC)通过将授权决策移动到运行时来解决这个问题。ABAC 策略引擎不再询问“这个主体拥有什么角色?”,而是询问“考虑到当前的所有上下文 —— 谁在请求什么资源、在什么条件下、在什么时间 —— 是否应该允许此操作?”策略可以表达如下规则:仅当任务上下文中存在先前的代码审查批准时,agent 才能写入此存储库。RBAC 无法表达这种关系,而 ABAC 可以。

由此产生的实际模式是一种混合体:RBAC 设置外部边界,ABAC 执行内部约束。 RBAC 规则规定“代码生成”类型的 agent 永远不能删除生产数据库。ABAC 策略则规定,这个特定的 agent 在这个特定的任务中,在接下来的 8 分钟内只能读取 /tmp 目录下的文件。单独任何一层都无法提供正确的粒度;它们结合在一起既涵盖了结构上的不变性,又涵盖了动态的逐任务约束。

最小特权工具范围界定

除了访问控制模型本身,工具接口是权限缩小或扩张的主要场所。

典型的错误是构建功能宽泛的工具。一个名为 manage_github 且接受任意 GitHub API 调用的工具既灵活又易于构建。它也是一个具有写入权限的风险点(footgun)。当 agent 需要开启一个 PR 时,它使用该工具。当提示词注入告诉它删除分支时,它也使用该工具 —— 而你的授权层永远不会看到权限边界被跨越。

有效的替代方案是窄工具:open_pull_requestread_filelist_open_issues。每个工具都以特定的权限范围编码特定的操作。工具接口成为了权限接口。一个工具集中只有 read_file 的 agent 无法删除分支,无论提示词怎么说,因为在其可用的动作空间中不存在这种能力。

由此得出几条实用原则:

  • 将工具默认设置为只读。仅当任务明确需要时才添加具备写入能力的工具,并在任务完成后撤销。
  • 将授权上下文推送到服务器,而不是提示词中。组织 ID、用户 ID 和权限范围来自后端的身份验证会话令牌 —— 而不是来自可能被覆盖的 agent 上下文窗口。
  • 与其使用一个通用的端点,不如倾向于使用几个专注于特定任务的工具。三个各司其职的工具比一个带有一个由 agent 解释的“模式”参数的工具更容易审计和限定范围。

OWASP 针对 Agentic 应用的十大漏洞(Top 10)将工具滥用和权限提升识别为关键风险,特别点名了那些接收过度授权工具并利用它们执行非预期操作的 agent。缓解措施是架构层面的:设计工具表面,使非预期操作变得不可能,而不仅仅是未经授权。

基于任务的凭据签发

即使拥有精简的工具集和 ABAC(基于属性的访问控制)策略,长效凭据仍然是一个安全隐患。一个有效期长达数天且涵盖多个系统的令牌是极具价值的攻击目标。如果 Agent 的运行时环境被攻破——无论是通过依赖项漏洞、容器逃逸还是供应链攻击——攻击者都会继承 Agent 所拥有的任何权限。

解决方案是使用短效的、不可刷新的、且仅限于任务范围的凭据。

该模式的运作方式如下:当 Agent 开始执行任务时,凭据签发器(如内部服务、AWS STS 或 HashiCorp Vault)会生成一个临时令牌。该令牌仅具备该任务所需的精确权限,且生存时间(TTL)以分钟计。Agent 使用该令牌来执行工作。当 TTL 到期时,令牌即失效。如果 Agent 需要开始新任务,它必须申请新的凭据,从而为策略重新评估创造了一个检查点。

“设计上不可刷新”是其核心属性。如果刷新令牌未被撤销,带有刷新令牌的标准 OAuth 令牌可以无限期地维持访问权限。任务范围的凭据不应是可刷新的。一旦到期,即刻失效。这能将运行时环境被攻破后的爆炸半径(blast radius)限制在令牌剩余的生命周期内,也就是几分钟的时间。

AWS STS 提供了一条直接的实现路径:生成带有自定义 TTL 和内联策略限制的临时凭据。HashiCorp Vault 提供动态机密生成,凭据按需创建,且绝不存储在 Agent 的环境中。这两种方法都消除了一类漏洞:即泄露的环境变量或日志中的 Header 导致持久访问权限。

真正有效的审计追踪

没有归因的授权是不完整的。当 Agent 执行操作时,你需要知道:哪个 Agent 实例、代表哪个用户、在哪个任务下运行、使用了哪个工具,以及由哪条策略规则授权。

这听起来显而易见,但在实践中往往会失效。大多数团队在应用层记录 API 调用,记录 Agent 的服务账号身份和 API 方法。他们遗漏的是因果链:Agent 为什么要调用这个 API?该调用是否在当前任务的授权范围内?

这种差距在事件响应期间会演变成合规问题。当用户询问“该操作从何而来?”时,你需要重建决策路径——Agent 处理的输入、它发起的工具调用、允许该调用的策略评估结果,以及它运行的任务上下文。通用的应用日志并不包含足以进行此类重建的信息。

有效的审计追踪具备四个属性:

  1. 身份锚定(Identity-anchored): 每一条记录都关联到经过验证的 Agent 身份,而不是会话 ID 或 IP 地址。Agent 应该是你身份系统中的一个具名主体(Principal),而不是人类用户的别名。
  2. 策略引用(Policy-referenced): 日志记录哪条策略规则授权了该操作,而不只是记录操作发生了。“由规则 code-agent-write-tmp-files 允许”提供了可审计的信息,而“HTTP 200 OK”则不然。
  3. 治理层强制执行(Governance-layer enforced): 在单个应用程序内部构建的审计追踪往往是零碎的。不同的模型提供商、不同的客户端库和不同的任务类型会产生不一致的日志结构。在控制平面(如 API 网关、工具授权服务、MCP 代理)强制执行,无论请求由哪个应用产生,都能生成一致的记录。
  4. 决策完整(Decision-complete): 对于敏感操作,记录输入和被拒绝的备选方案。一个选择删除文件而不是归档文件的 Agent 做出了一个决策;如果你记录了这两条路径,该决策就是可审计的。

ISACA 对 2025 年 Agent AI 审计的分析指出,缺乏归因是合规审查的主要障碍。审计态势最清晰的组织是那些从一开始就将 Agent 授权构建为治理层服务的组织,而不是那些在部署后才补齐日志记录的组织。

MCP 授权模式的转变

模型上下文协议(Model Context Protocol, MCP)由 Anthropic 在 2024 年底推出,并由 OpenAI 在 2025 年初采用,目前已成为将 AI Agent 连接到外部工具和数据源的主流标准。自初始发布以来,其授权模型已显著成熟。

2025 年 11 月的 MCP 规范正式将 MCP 服务器归类为 OAuth 资源服务器(Resource Servers)。这一点至关重要,因为它允许使用资源指示器(Resource Indicators, RFC 8707),这要求 MCP 客户端在访问令牌签发前明确声明其预期的接收方。为服务 A 获取的令牌不能被静默地重定向到服务 B。这封堵了一个主要的提示词注入(Prompt Injection)攻击向量:如果令牌在签发时已绑定到特定资源,那么即便注入指令要求 Agent 将当前令牌发送到攻击者控制的端点,该操作也不会成功。

同一规范更新还强制要求所有授权流使用 PKCE,并引入了机器对机器(M2M)凭据支持,用于在没有用户上下文的情况下进行 Agent 到后端的授权。对于针对兼容 MCP 的后端部署 Agent 的工程师来说,这些不是可选功能,而是建立可防御授权姿态的最低基准。

更广泛的启示是,Agent 授权的标准基础设施现在已经存在。作为身份层的 RBAC、用于运行时策略的 ABAC、任务范围的凭据、精简的工具表面以及符合 MCP 标准的令牌绑定,共同构成了一个可以逐步实施的安全架构。

首先要做什么

当 Agent 已经在生产环境中运行时,补齐授权机制说起来容易做起来难。采用循序渐进的方法可以减少对业务运行的干扰:

  • 审计当前工具的作用域(Scopes)。 在进行任何更改之前,先梳理每个已部署 Agent 当前具备的功能。大多数团队会发现,Agent 拥有其从未实际使用过的系统访问权限。首先移除未使用的作用域——这风险较低,且能立即缩小攻击面。
  • 分配独立身份。 停止让 Agent 共享用户的 OAuth 令牌。将每种 Agent 类型注册为具有独立客户端 ID(Client ID)的 OAuth 客户端。这是进行后续所有改进的前提。
  • 首先收窄高风险工具的权限。 识别那些能够写入生产系统或导出数据的工具。将它们拆分为更细粒度的操作。这是大部分真实风险所在。
  • 增加凭证存活时间(TTL)限制。 即使没有完整的基于任务作用域的凭证系统,将 Agent 服务账户的令牌有效期从 30 天缩短为 1 小时,也是一项重大的改进,而且无需修改 Agent 的代码即可完成。
  • 在需要之前就将归因(Attribution)构建到日志中。 在安全事件发生期间才去完善审计追踪记录就太晚了。现在就将策略引用和任务上下文添加到 Agent 日志中。

在 2025 年供应链漏洞中受损的组织都有一个共同特征:Agent 被部署时拥有广泛且持久的访问权限,因为其授权模型从未被明确设计过。解决方案并非采用新的安全产品,而是将十年前应用于人类身份的同样原则应用于 Agent 身份——即独立的实体(Principal)、最小权限和完整的审计追踪。

Agent 不是用户。如果按照对待用户的方式来构建它们的授权模型,会让后续的一切变得更加困难。

References:Let's stay in touch and Follow me for more thoughts and updates