跳到主要内容

当你的 CLI 开始说英语:可提示基础设施的最小权限原则

· 阅读需 13 分钟
Tian Pan
Software Engineer

我本季度交流过的一个平台团队发布了一个封装了 kubectl 并支持英语指令的 Slack 机器人。一名工程师输入了 “清理 staging 中未使用的分支”。这个机器人非常“热心地”删除了 12 个命名空间——其中一个的名字匹配到了子字符串 “branch”,但它恰好托管了移动团队已经使用了一周的长期集成环境。没有任何异常被抛出。机器人发起的每一次调用都是它合法持有的权限。复盘报告无法指出任何违背的访问规则,因为确实没有规则被打破。该机器人完全按照其 IAM 策略允许的操作执行。

Unix 哲学是一种隐藏在审美偏好下的隔离策略。具有窄接口的小型工具意味着任何单个命令的爆炸半径都受到它所接受的谓词和标志 (flags) 的限制。rm -rf 极其危险,因为这是大家的共识;kubectl delete namespace 要求操作者完整输入命名空间名称,而这种手动输入就是一道关卡。最小特权原则之所以容易执行,是因为权限是词法化的:命令的形式告诉了你行动的形式。

随后,封装层开始接受英语。现在,“命令的形式”变成了 LLM 认为它是什么,它就是什么。

封装层是新型的混淆代理 (confused deputy)

经典的混淆代理模式——一个特权程序被低特权调用者欺骗,从而误用其权限——本应成为历史遗迹。这种 Bug 通常出现在早期的能力系统和几十年前的 setuid 二进制文件中。但近期可提示化基础设施 (promptable infrastructure) 的激增,使其作为 Agent 系统中主要的授权失效模式再次复活。云安全联盟 (Cloud Security Alliance) 在 2026 年关于 Agent 混淆代理攻击的研究简报中精确地描述了这种动态:当 AI Agent 持有代表操作者执行操作的广泛凭据时,Agent 处理的每个输入渠道都成为了权限滥用的候选点。任何能够向 Jira 工单、检索到的文档、工具响应或 Slack 消息写入内容的攻击者,都可以注入指令,并以操作者的全部权限执行。

但请注意:Prompt 注入是极端案例。日常情况要隐蔽得多。“代理”被其自身用户出于善意地混淆了,因为用户要求“删除未使用的分支”,而代理自行决定了什么是“未使用”。

可提示化基础设施继承了自然语言最糟糕的属性:同义表述极其丰富。同一个意图可以用一千种方式表达,而同一个短语也可以被解释为一千种意图。传统的 CLI 是一个解析器;而可提示化 CLI 是一个解释器,它将一个未充分说明的规范解析为一个具体的计划,然后以用户的全部权限 执行该计划。现在,每一个将意图转化为命令的封装层都建立在一个权限膨胀机之上。

Unix 模型通过限制命令集的基数来提供隔离。而可提示化模型提供了一个命令集,其基数等同于语言的大小。爆炸半径不再受工具接受的谓词限制,而是受解析请求的任何模型的想象力限制。

RBAC 是为谓词设计的,而非意图

行业在过去十年构建的 IAM 栈——RBAC、sudo、能力令牌、OPA 策略、IAM 条件——都假设主体发起一个离散的动作请求,而策略引擎回答“是”或“否”。其语法是 (subject, verb, resource, condition) → allow | deny。它之所以奏效,是因为谓词是稳定的名词:s3:GetObjectpods/deletesecrets/list。你可以针对谓词编写策略,因为谓词具有固定含义。

自然语言则不具备这些属性。“帮我清理 staging 环境”不是一个谓词;它是一个未充分说明的意图,在运行时被编译成一系列策略引擎从未将其视为整体的谓词序列。RBAC 可以告诉你 Agent 是否允许调用 pods/delete。但它无法告诉你 删除这些特定的 Pod 是否属于 用户所要求的范围。策略引擎看到的是叶子;而授权问题存在于整棵树中。

2026 年 Agent 安全研究界提出的一个框架认为,这一差距值得拥有自己的名字:语义提权 (semantic privilege escalation)。Acuvity 的报告将其描述为 Agent 在其正式权限范围内运行,却超出了用户实际授予的权限范围的情况。arXiv 上关于 “Prompt 流完整性” (2503.15547) 的论文在架构层面提出了同样的观点:单次调用授权是必要的,但并不充分,因为真正起作用的是针对 计划 的策略,而非针对每个单独步骤的策略。2503.20279 论文中的攻击框架 SUDO 展示了对称的攻击案例:一个 “Detox2tox” 流水线将一个被拒绝的有害请求重新表述为一系列看似无害且已授权的动作,然后在执行时重新组合成伤害。在这些案例中,Agent 从未向策略引擎请求过它尚未拥有的权限。

这就是为什么“给部署机器人 LLM 访问权限”离“给部署机器人完整的管理员权限”仅有一个 PR 的距离。机器人并没有获得更多权限。只是这些权限前的自然语言界面变得足够大,以至于它们的任何子集现在都可以通过某种表述方式被触及。

意图绑定令牌:签署自然语言,锁定计划

适配这一问题的架构原语是 IAM 行业多年来一直关注、且目前正被推向实际部署的:意图绑定令牌 (intent-bound token)。这个想法很直接,在 macaroons、biscuits 以及 2010 年代初的各种能力令牌 (capability-token) 设计中都有先例。新的变数在于,绑定的对象是用户的自然语言(English),而不仅仅是一个作用域(scope)。

具体机制如下:

  1. 用户以自然语言提交意图:“扩展结账服务以应对假日流量。”
  2. 编排器将意图编译成具体的计划——一系列带有已解析参数的类型化工具调用。该计划是一个确定性产物:可以进行哈希处理、序列化和对比 (diff)。
  3. 系统铸造一个短寿命令牌,其负载绑定了三样东西:原始提示词、计划哈希以及一个作用域子句,该子句将令牌严格限制在计划中的调用及其解析后的参数内。
  4. 每个下游工具根据令牌重新验证调用。不在计划中的调用将失败并关闭 (fail closed),即使智能体的广泛凭证原本允许该操作。

重点不在于加密——而在于权限变成了“基于计划的”而非“基于角色的”。一个拥有完整 kubectl 访问权限的智能体,如果其意图绑定令牌仅授权 scale deployment/checkout --replicas=N,那么无论计划在提示词注入下如何演变,它都无法在执行过程中转向 delete namespace。在令牌的生命周期内,智能体的“基础”权限是无关紧要的;令牌已将权限缩小至解析后的计划。

这也是 IETF 和 NIST 在智能体认证方面的工作方向。draft-klrc-aiagent-auth 路径以及早期的 Microsoft Entra Agent ID 工作都将智能体身份视为区别于人类或服务身份的东西,其明确目标是实现针对每个任务的作用域限定。WorkOS 在产品层面的构想也是一致的:智能体需要的授权应锚定在 任务会话 (task session) 上,而非长效的智能体身份。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates