前言¶
在 Windows 上使用 DeepSeek Harness(dsh)的 workspace-write 沙箱时,每次执行受控命令前,沙箱会在工作区根目录的 DACL 里写入写权限授予(AclWriteGrant.add → grantWrite)。若路径链上某一目录缺少有效的 WRITE_DAC / WRITE_OWNER,SetNamedSecurityInfoW 会以 Win32 5(ERROR_ACCESS_DENIED)失败,表现为:
Error: SetNamedSecurityInfoW failed (Win32 5): grantWrite
此后该工作区上的每一条受控命令都会在 spawn 之前失败,与具体要跑的 shell 命令无关。手动改 ACL 或换目录可以绕开,但不符合日常开发节奏。下面介绍社区插件 dsh-grantwrite-patch(维护者 0-v-0,分类 admin-security):在命中上述错误时自动修复权限并重试命令,尽量让你无感继续工作。
这是什么¶
dsh-grantwrite-patch 是面向 dsh 的 Windows 沙箱 ACL 修复插件:拦截 grantWrite 场景下的 SetNamedSecurityInfoW Win32 5 失败,按策略修复后 invisible 重试原命令。仅 NTFS + Windows 生效,非 Windows 平台插件会自行禁用。依赖 dsh >= 0.1.7-rc.1;完整 diagnose 脚本修复路径需要 dsh >= 0.2.0-rc.2。只有 workspace-write 沙箱策略需要此插件(read-only、danger-full-access 不需要)。
工作原理¶
插件按工作区规模选择策略,三条路径按需叠加、互不冲突:
- 普通工作区:在内存中拦截错误并重试,不改动磁盘上的文件权限。
- 大工作区:当对象数量达到阈值(默认 20,000)时,对工作区 proactive 做一次完整 grant,避免每次 DSH 重启都重复支付写 grant 成本,大目录树等待时间更可控。
- 兜底:上述路径不可用时,运行一次 diagnose 脚本修复权限并重试;脚本不可用时,可回退到
icaclsgrant(见安全配置)。
大/小判定会用到 size probe;probe 超时(默认 10s)按大工作区处理;每个工作区的 probe/决策有缓存(默认 1 小时)。
安装与启用¶
通过 npm 安装到 profile(与给 profile 加依赖类似;bundle 出现在 dsh.profile.bundles 后,下次启动加载 cordis.patch.yml):
dsh plugin --profile web add dsh-grantwrite-patch
更新时再次执行同一命令即可,例如:
dsh plugin --profile web add dsh-grantwrite-patch@latest
也可手动把仓库内 cordis.patch.yml 的 - insert: 块合并进宿主 cordis.yml。
从源码安装需先 pnpm build(lib/ 未提交,FFI preload 来自安装包内的 lib/preload.cjs);步骤见 GitHub README,本文不展开 clone 流程。
配置¶
插件通过 cordis.patch.yml 注入,典型字段如下(默认值以 README 为准):
- insert:
id: grantwrite-patch
name: dsh-grantwrite-patch
config:
enable: true
mode: auto # auto | patch | repair
objectThreshold: 20000
probeTimeoutMs: 10000
probeCooldownMs: 3600000
repairTimeoutMs: 120000
maxRetries: 1
cooldownMs: 60000
appendDiagnostics: true
grantFallback: true
# scriptPath: <absolute path>
# outDir: <absolute path> # 默认 $DSH_HOME/grantwrite-patch
mode:auto自动选 patch / repair;也可强制patch或repair。maxRetries:可调 0–3;修复失败不会再次重试,避免循环。grantFallback:脚本不可用或失败时是否用 bareicacls;盘符根目录会被拒绝。
安全模型(安装前建议阅读)¶
插件运行在 dsh 宿主进程(非 restricted token),改权限正是沙箱 restricted token 做不到的事;不会提升 token 权限。
- patch 路径:不碰系统 ACL,无持久副作用;保留
WRITE_RESTRICTED、capability-SID Allow ACE、world-SID 的FILE_DELETE_CHILDDeny 等;仅 Low-integrity 标签层可能缺失(部分主机本就无法打标签时,子进程以 Medium 运行)。 - repair 路径:范围由 diagnose 脚本的
-AllowRoot限定,只改目标目录及其内部;拒绝 reparse point、受管应用树;不删 Deny ACE;变更前备份、读后校验,批次失败会回滚。 - grantFallback:
icacls <root> /grant "<user>:(OI)(CI)F";盘符根(如D:\)硬拒绝;不改继承策略、不删 Deny;可用icacls ... /remove:g回滚。脚本路径更安全,fallback 仅补缺口。
仅匹配 grantWrite 上下文中的 SetNamedSecurityInfoW 失败;其他 Win32 错误、命令退出码、EPERM 等原样透传。
典型用法¶
安装并启用后,无需为 grantWrite 单独写命令:在仍使用 workspace-write 且曾出现 Win32 5 的工作区里正常跑 dsh 受控命令即可。插件在失败时修复并重试(默认最多 1 次,可由 maxRetries 调整)。
若工作区文件极多、启动或 probe 偏慢,可调高 objectThreshold 或 probeTimeoutMs,或在大工作区场景下接受一次性 persistent repair 以降低后续每次 grant 的开销(见 README「Large workspaces」)。
适用场景与注意¶
适合:Windows + NTFS 上长期使用 dsh workspace-write,工作区 ACL 链不完整导致 grantWrite 全面阻断的开发者。
注意:
- 插件以当前 dsh 进程权限运行,repair / icacls 会改工作区 ACL;安装前应阅读 源码 与 MIT 许可证。
- FFI 核心改编自 masknull/dsh-acl-sandbox-patch。
- 社区插件目录 SkillHub 条目 与 GitHub 为独立信息源,与 DeepSeek / 幻方无官方从属关系;DSH 生态强调「一切皆插件」,按需选用即可。
结尾¶
dsh-grantwrite-patch 针对 Windows 沙箱在 grantWrite 阶段的 Win32 5 做拦截、按规模选 patch / repair / 脚本或 icacls 兜底,并在可控重试次数内恢复命令执行。若你在 workspace-write 下被 SetNamedSecurityInfoW failed (Win32 5): grantWrite 卡住,可先按上文 npm 命令安装,再对照 README 调整 objectThreshold 与安全相关开关。
- 目录页:https://www.skillhub.cn/plugins/0-v-0/dsh-grantwrite-patch
- 仓库:https://github.com/0-v-0/dsh-grantwrite-patch