dsh-grantwrite-patch:修复 Windows 沙箱 grantWrite 失败并静默重试

前言

在 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 不需要)。

工作原理

插件按工作区规模选择策略,三条路径按需叠加、互不冲突:

  1. 普通工作区:在内存中拦截错误并重试,不改动磁盘上的文件权限。
  2. 大工作区:当对象数量达到阈值(默认 20,000)时,对工作区 proactive 做一次完整 grant,避免每次 DSH 重启都重复支付写 grant 成本,大目录树等待时间更可控。
  3. 兜底:上述路径不可用时,运行一次 diagnose 脚本修复权限并重试;脚本不可用时,可回退到 icacls grant(见安全配置)。

大/小判定会用到 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:脚本不可用或失败时是否用 bare icacls;盘符根目录会被拒绝。

安全模型(安装前建议阅读)

插件运行在 dsh 宿主进程(非 restricted token),改权限正是沙箱 restricted token 做不到的事;不会提升 token 权限。

  • patch 路径:不碰系统 ACL,无持久副作用;保留 WRITE_RESTRICTED、capability-SID Allow ACE、world-SID 的 FILE_DELETE_CHILD Deny 等;仅 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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜