[RFC] 增加评测隔离模式:当前 workspace 缺少读取隔离能力 #492
xsyshuishui
started this conversation in
General
Replies: 2 comments
|
试试用微软的MXC容器,基于uwp的AppContainer,可以做到文件系统隔离,不过跑node时不太稳定。 |
0 replies
|
收到,感谢建议,我们会改进沙箱功能,让沙箱能够更细粒度的被配置,以及可以用沙箱包住整个dsh进程的行为而不仅仅是只对于特定工具生效。 |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
TL;DR
read-only/workspace-write/danger-full-access)限制的是文件修改范围,读取仍然可以访问 workspace 以外的内容。选择一个空的 workspace,并不能保证 Agent 只看到这个目录里的东西。我们遇到的情况
我们最近在用 DSH 作为评测基底,运行 GPU kernel 优化任务。每个任务里,Agent 会围绕一个算子反复修改实现、运行测试、比较性能结果。
一次测试中,我们特意选了一个空目录作为 workspace,想要一个干净的环境。但在看轨迹时发现,Agent 读到了同一台机器上另一个目录里、上一轮任务留下的内容。这些内容并不属于当前 workspace。
我们随后查了文档和源码,发现这不是实现上的疏漏,而是当前沙箱设计明确允许的行为:现有权限模型限制的是写入范围,读取保持开放。
排查中我们还发现,即使 Agent 没有主动调用文件工具,第一轮的上下文也可能包含 workspace 以外的信息:
discoverInstructionFiles会先探测$DSH_HOME/AGENTS.md,再沿祖先目录逐层收集AGENTS.md和CLAUDE.md(packages/context/agent-instructions/src/files.ts L267-L307)。这也是为什么只选一个空目录当 workspace,并不能保证任务环境是干净的。所以这篇不是要报告一个缺陷,而是提一个能力上的建议:评测场景需要一个额外的隔离模式。
一、现状
DSH 当前三档权限(
read-only/workspace-write/danger-full-access)限制的都是写入行为,读取保持开放。相关证据(基于 commit
47f9438):CLI 文档写明:
apps/cli/reference/README.zh.md L68-L70
fs-sandbox的模块注释写明:packages/fs/fs-sandbox/src/index.ts L1-L28
这一行为也已经被回归测试固定下来。在同一个
workspace-write的测试块里,跨 workspace 的写入会被拒绝,而读取父目录会成功:packages/examples/agent-spine-demo/tests/multi-project-sandbox.e2e.ts L210-L244
我特意把这条测试列出来,是因为它说明放开读取是当前的设计约定,不是遗漏。所以下面提的是增加一个新的档位,而不是改变现有档位的行为。
补充一点:这也不是配置能解决的问题。权限预设表本身是可以覆盖的——界面上那三档就定义在部署配置里(packages/bundle/base/cordis.patch.yml L193-L205)。但一个预设只是把两个开关捆在一起:
sandbox的取值只有read-only/workspace-write/danger-full-access,approval的取值只有ask/never,两者都不接受路径参数。环境变量DSH_PERMISSION_MODE也只是在这三档里选。也就是说,现在的配置里没有可以写出「这些目录不许读」的地方,自定义预设也只能在这几种组合里挑。二、为什么评测场景需要额外的隔离能力
1. 评测结果会受到机器上其他文件的影响
BENCHMARK.md 里关于隔离目前只有一句:
但当前的 workspace 之间并不存在读取隔离。
如果不同题目的目录放在同一个文件系统里,或者参考答案、用来评分的测试和其他产物放在一起,Agent 可以通过
../、绝对路径、grep、find等方式访问到。已经跑完的其他任务留下的会话记录,也在同样的可见范围内。也就是说,评测结果是否可信,取决于这台机器上其他目录里放了什么,而不是只由当前任务目录决定。
我们把 DSH 用作 kernel 优化评测基底时,这是一个实际的约束:目前只能把整个 DSH 放进每道题独立的一次性容器里,才能保证环境干净。这个要求本身合理,但值得写进文档和能力设计里,而不是让每个做评测的用户自己发现一遍。
2.
$DSH_HOME不在当前的读取隔离范围内会话记录默认就放在
$DSH_HOME下。在默认配置下,只要 Agent 能用文件工具和 bash,同一台机器上其他会话的记录、系统提示词和配置就都不在读取边界之内。在共用的机器上,这涉及隐私;在评测场景下,这会影响实验结果。
credentials-local的 README 已经描述过类似情况:packages/credentials/credentials-local/README.md L52-L70
我们的建议是:DSH 自己的主目录可以考虑单独对待,即使整体的读取策略保持开放。
3. 现在的命名容易让人以为 workspace 限制得更严
Read Only/Workspace Write/Full access这组名字,容易让新用户以为 workspace 在读取上也有约束。这不是主要问题,但在文档或界面上写明当前行为就能减少误解。三、最小复现
在 Web 里新建会话,workspace 选空目录
task-01,权限保持默认,然后让 Agent 看看上一级目录里有什么。Agent 可以读到../answers/solution.txt。切换到read-only结果一样,因为这一档限制的是写入。这个例子只是从用户角度复现一次;这个行为本身已经由仓库自己的端到端测试覆盖。
四、建议
P0 — 在轨迹里标记读到 workspace 以外的操作
不改变当前行为,只增加可见性:当读取的路径不在当前 workspace 里时,在轨迹中加一个「出界读」标记。
这样不改动权限模型,不用修改沙箱实现,也不影响现有的测试约定。
对做评测的人来说,先能看出一次任务有没有读过外部内容,这一步很重要。有了标记就能快速判断某次运行是否受到外部信息影响,不用逐条翻工具输出。
P1 — 增加一个可选的评测隔离模式(设计提案)
目标是缩小 Agent 能看到的文件范围,而不是替代容器。具体怎么实现可以再讨论,更严格的文件系统隔离、容器镜像、microVM 都是可选项,这里不限定做法。
我也看过
a90ccc44(2026-07-30,撤回readDenyPaths)。撤回的理由是成立的:bwrap需要在自己已经设为只读的目录树里创建绑定挂载点,所以在还没有这个父目录的全新安装上,整个隔离都会失败;Landlock无法从自己对/的读取授权里去掉单个路径,只能报partial。那个 commit 的结论是:所以这里不是建议把那条路再走一遍。之前的做法是在已经全部开放的读取上做减法,受限于这两个后端的能力;而评测隔离模式要的是一开始就给出一个更小的环境。但也得承认:真实的 Agent 环境要跑起来,需要运行时、编译工具链、CUDA 这些依赖,能看到的范围会逐渐接近一个完整的执行环境。所以这更像是评测环境本身的设计问题,而不是给沙箱加一个参数就能解决的。
这一档只在评测和处理不可信内容时开启,默认用法不需要改变,现有
workspace-write的测试也不用调整。P2 — 处理
$DSH_HOME的默认可见性在 P1 下这个问题自然就包含进去了。在现有档位里,可以先从小范围做起,比如在
fs-sandbox里增加读取方向的判断。这一层是在进程内做的路径检查——它已经在为写入和编辑做同样的检查——并不依赖bwrap或Landlock,所以上面提到的那两个内核层面的问题在这里不会出现。更轻的做法是把会话记录和敏感产物分开存放、收紧文件权限,并提供一个明确的导出接口。
bash 这条路径能力不同,拦不住,应该作为已知限制写进文档,而不是当作已经解决。
P3 — 补充
BENCHMARK.md的说明建议在
BENCHMARK.md里写明:严格的评测需要把整个 DSH 放进每道题独立的一次性容器或 microVM,并且当前三档权限都不提供答案层面的隔离。这一项成本最低,也最能让做评测的用户少走弯路。五、与 #159 的关系
#159 里,模型直接调用的读取操作读到了 workspace 以外的文件(
isError: false),这可以作为旁证,但那篇讨论的主题是workspace-write的写入边界存在先检查、后执行之间的竞态。两者关注的不是同一件事:#159 说的是写入限制的实现缺口,这篇说的是读取隔离的范围本身。所以单独发一帖,避免把两个问题混在一起。#250 和 #268 的正文里也各自引用过同一条读取行为。
感谢阅读。希望这篇讨论能帮忙把 DSH 在评测场景下的使用边界说清楚。当前设计对于日常写代码的场景是有价值的;这里想讨论的是,当 DSH 被用来跑评测、或者处理不可信内容时,是否需要增加一层额外的隔离。
All reactions