前言¶
在 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