AI

权限不是字符串(中英切换)

This post is currently available in Chinese only. The original text follows.Open the Chinese page →

权限不是字符串。

你给 coding agent 开了 Read / Write / Exec。模型只要在工具参数里点名一个路径或一条命令,宿主就按用户权限动手。Harness 握着你的特权;模型只负责填字符串。间接提示注入钻的,正是这道混乱代理人缝隙:README、AGENTS.md、Skill、源码注释、工具输出里的一句「官方」说明,就能把子代理驶向你没要过的写入。

权限不是字符串

全局策略几乎挡不住

Authority Is Not a String(arXiv:2609.08371) 在 Pi coding agent 上实现 CapScope,跑修复工作流(编排器 + 子代理):5 个 Python 任务 × 5 个注入面 × 4 种授权条件 × 3 次重复 = 300 次。注入面:README.md、AGENTS.md、Skill 文件、源码注释、工具输出。

硬数字(Table 2,攻击执行越低越好 / 任务成功):

  • B0 环境权限:攻击 47/75,成功 72/75
  • B1 静态全局(denylist 风格):攻击 46/75,成功 70/75 —— 相对环境权限几乎没帮助;
  • B2 任务专用全局:攻击 33/75,成功 68/75
  • C CapScope:攻击 3/75,成功 68/75

基线在注入下仍 33–47/75 打中;CapScope 3/75。按表面(Table 3,各 15 次,CapScope vs B2):README 0/15 vs 7/15;AGENTS.md 3/15 vs 11/15;Skill 0/15 vs 7/15;源码注释 0/15 vs 4/15;工具输出 0/15 vs 4/15。剩下的三次不是「漏看字符串」,而是故意把权限授给该主体的 grant 情形。

CapScope:先铸天花板,再读仓库

设计不靠模型去「认出」恶意文本。预检只吃可信用户请求 + 文件树,铸出任务级权威天花板,能力存在模型上下文之外。Read/Write 按路径前缀;Exec 按解析后的 argv 向量;复合命令逐段检查。每个代理独立能力库——看到被投毒测试输出的 runner,写不了 patcher 才能写的源码。

今晚只改一处判定

别再把「工具名 + 路径字符串」当成授权完成。在 agent 读仓库之前,从可信输入铸出类型化 capability;按子任务衰减;在派发时检查。权限不是字符串——点名资源不等于有权动手。

Authority is not a string.

You open Read / Write / Exec for the coding agent. The model only has to name a path or a command in the tool args, and the host acts with the user's privileges. The harness holds ambient authority; the model fills in string names. Indirect prompt injection exploits that confused-deputy gap: one official-looking line in README, AGENTS.md, a Skill file, a source comment, or tool output can steer a sub-agent into a write you never asked for.

Authority is not a string

Global policies barely help

Authority Is Not a String (arXiv:2609.08371) implements CapScope on the Pi coding agent in a repair workflow (orchestrator + sub-agents): 5 Python tasks × 5 injection surfaces × 4 auth conditions × 3 trials = 300 runs. Surfaces: README.md, AGENTS.md, Skill file, source comment, tool output.

Hard numbers (Table 2 — attack executed, lower better / task success):

  • B0 ambient authority: attack 47/75, success 72/75;
  • B1 static global (denylist-style): attack 46/75, success 70/75 — almost no help vs ambient;
  • B2 task-specific global: attack 33/75, success 68/75;
  • C CapScope: attack 3/75, success 68/75.

Baselines still land the injected effect in 33–47/75; CapScope 3/75. By surface (Table 3, 15 each, CapScope vs B2): README 0/15 vs 7/15; AGENTS.md 3/15 vs 11/15; Skill 0/15 vs 7/15; source comment 0/15 vs 4/15; tool output 0/15 vs 4/15. The three residual CapScope hits are grant cases — authority deliberately given to that principal — not missed strings.

CapScope: mint the ceiling before untrusted text

The design does not ask the model to spot malicious text. Preflight mints a task-wide authority ceiling from trusted user request + file tree only; capabilities live outside model context. Read/Write use path-prefix scopes; Exec uses parsed argv-vector scopes; compound commands are checked segment by segment. Per-agent stores matter: the runner that sees poisoned test output cannot write the source the patcher could.

One judgment change tonight

Stop treating “tool name + path string” as authorization. Before the agent reads the repo, mint typed capabilities from trusted input; attenuate per sub-agent; check at dispatch. Authority is not a string — naming a resource is not permission to act.