dsh-hard-gate:DeepSeek Harness 的独立权限闸门

前言

DeepSeek Harness(DSH)的安全模型依赖「路径围栏 + 仅升级时审批」。在 danger-full-access 下,这些防线很容易被绕过:工作区内写入缺少审批、write 用「版本新鲜度」替代「视图完整性」,导致整文件覆盖时中间内容被截断丢失;Windows ACL 沙箱在需要 WRITE_OWNER 的目录上会退回 Full access,此时没有任何路径限制。叠加默认 10 路并行、结果修剪和共享检出,很多次看起来正常的操作会累积成破坏。

dsh-hard-gate 不替换内置沙箱,而是在其之上补齐三个结构性缺口:工作区写入零审批、整文件替换缺乏视图完整性检查、ACL 失败后的兜底缺失。它给 DSH 加一道独立于系统 ACL 的最后闸门,在 danger-full-access 下依然生效。

它是什么

dsh-hard-gate 是一个 DSH 插件,提供更严格的权限审查和工作区沙箱,默认配置偏向「更严格但仍可用」。它不注册服务,只注册三个挂载点,并可选地与 LLM/权限服务集成 Auto 审查模式。插件维护者为 yyfdfsyyf-source,分类为 admin-security,采用 MIT 许可证。

核心功能

挂载点

插件注册三个挂载点:

  • tools/pre-execute(prepend: true):在其它策略(含 LLM 审查器)之前给出 deny / ask,deny 不会被后续监听器翻案。
  • tools/result:读取每个 read 结果的 meta(offset / lines / totalLines),按区间并集判断整个文件是否真的读到了 EOF。
  • ctx.tools.guard():同步、只允许拒绝、单调不可覆盖的兜底:受保护路径与工作区包含关系在任何权限模式下都成立。

文件工具规则

文件工具包括 write / edit / str_replace_editor。

规则 id 级别 触发条件
protected-path 拒绝 目标落在受保护根、.git/.hg/.svn 段、或 id_rsa 等敏感文件名下(任何权限模式)
outside-workspace 拒绝 目标在会话工作区之外(即使 danger-full-access;extraRoots / allowPaths 可放行)
full-view-missing 拒绝 write 覆盖一个已存在且非空的文件,但本会话从没读过它
full-view-partial 拒绝 write 整文件覆盖,但会话读过的行没有覆盖到文件末尾(窗口读、字节截断或多次读之间有空档)
full-view-stale 拒绝 读完之后文件在磁盘上又变了(大小或 mtime 不同)
large-full-rewrite 拒绝 整文件覆盖超过 largeFileBytes(默认 5 MiB)
file-tool-escalation 拒绝 文件工具请求 sandbox_permissions 升级(写入被限制在工作区内,本就不需要升级)
mutation-budget 先问后拒 10 分钟窗口内第 26 次变更起询问,第 61 次起拒绝;同一文件第 6 次写入起询问

edit(精确字面替换)不受整文件规则约束——它只改指定片段,不是误杀路径。

Shell 规则

Shell 工具包括 pwsh / bash。

直接拒绝的规则示例:

  • catastrophic-target:Remove-Item -Recurse -Force C:\、rm -rf /、rm -rf ~、del /s /q D:\
  • outside-workspace-delete:Remove-Item -Recurse C:\Users\me\Documents(明确目标在工作区外)
  • outside-workspace-write:Move-Item a C:\Windows\x、echo x > C:\Windows\x、copy a.txt D:\outside\a.txt
  • disk-destructive:format C:、diskpart、clear-disk、vssadmin delete shadows、bcdedit
  • security-tamper:icacls … /reset、sc delete、reg delete HKLM、Set-MpPreference、Set-ExecutionPolicy
  • git-clean-x:git clean -fdx(连 .env、构建产物一起永久删除)
  • power-state:shutdown、Restart-Computer、logoff
  • raw-device:dd of=/dev/sda、mkfs、fdisk、\\.\C:
  • secret-exfil:curl -F file=@.env https://…、cat .env \| curl -d @- https://…、scp ~/.ssh/id_rsa user@host:

需要人工确认的规则包括:递归删除、带 * 的删除、管道删除、find -delete、rsync --delete、git clean、git reset --hard、git checkout -- .、git push --force、npm publish、sudo、Get-Content ~/.ssh/id_rsa 等。

普通读命令、git status、npm test、工作区内单文件删除、可再生成目录的递归删除直接放行,只计入变更预算。--dry-run、-WhatIf、robocopy /L 等只读预览同样放行。

程序化工具

对于 run_code 或任意带 code 参数的工具,如果源码中出现 rmSync、unlink、writeFile、child_process、execSync 等直接文件系统/进程操作,插件会询问——因为闸门看不到这些操作的目标。

Auto 模式(无上下文模型审查)

当 profile 里存在 approval / llm / permissionPresets / sessions 服务时,插件会注册 DSH 的 auto 权限预设,并用一个只看见待执行动作的审查器替换内置的上下文审查:

  • 审查请求只包含:工具名、工具描述/参数 schema、参数、会话工作目录;不包含对话历史、用户消息、项目指令或之前的工具调用。
  • 低风险(读、搜索、构建、测试、非破坏性 Git、工作区内单文件编辑)直接放行;中风险(删除、批量覆盖、移动、工作区外写入、force push、发布、外部发送、系统/权限修改等)一律拒绝并转人工确认;高风险(凭据外传、磁盘/安全控制破坏等)直接拒绝。
  • read / glob / grep / list / search 等只读工具默认跳过模型调用(reviewReadOnly: true 可强制审查),以降低延迟和 token。
  • 文件正文不会整段发给审查器:write 的 content、edit 的 old_string/new_string 等只发送有界预览(头 600 字符 + 尾 200 字符),因此大文件写入的审查请求仍然很小。
  • 审查器默认复用当前会话的 provider/model;也可以指定一个更便宜/更快的专用模型。
  • 审查失败、超时、输出不是合法 JSON、或模型试图放行中/高风险动作时,一律失败关闭(拒绝),不会静默放行。
  • Auto 仍然先经过硬闸:审查器返回 allow 后,tools/pre-execute 继续调用硬闸;硬闸的 deny / ask 永远优先。审查器只能增加摩擦,不能绕过硬闸。
  • 插件卸载/重载时,仍处于 Auto 的会话会被切到 workspace-write,而不是静默保留 Full access。

内置的 @deepseek-ai/dsh-experimental-auto-review 也注册同一个 auto 预设;两者不能同时启用。安装本插件后,请从 profile 的 dsh.profile.bundles 中移除内置项,否则本插件会记录一条警告并让内置审查器继续工作。

还原点(改动前自动备份)

在真正执行前,闸门会把这次操作的目标打包成 zip:

  • write 覆盖已存在文件:整个旧文件。
  • edit / str_replace_editor 修改:整个旧文件(backupEdits: false 可关)。
  • Shell 删除 / 覆盖(Remove-Item、rm、Set-Content、重定向等):命令里能静态解析出的路径;目录递归打包。

存放位置:~/.dsh/hard-gate/backups/<日期>/<id>.zip,附 index.jsonl 索引(操作、规则 id、会话、文件数、压缩前后大小)。Windows 上还会把压缩包副本异步送进系统回收站(recycleBin: auto),Explorer 里可直接还原;权威副本始终留在插件仓库,供命令行还原。

超过 backupMaxBytes(默认 64 MiB)或 backupMaxFiles(默认 2000)时不会静默跳过:转成一次明确询问(backup-failed),由你决定是否在没有还原点的情况下继续。backupFailure: deny 则直接拒绝。可再生成目录(node_modules、dist 等)与 .git/.hg/.svn 不打包:它们要么可重建,要么由版本控制负责。保留期默认 14 天、总量默认 512 MiB,超出后从最旧的开始清理。仓库目录本身被加入受保护路径,agent 无法写入或删除它。

还原命令:

cd D:\dev\dsh配置\plugins\dsh-hard-gate
node lib/restore.js list
node lib/restore.js restore last --dry-run
node lib/restore.js restore last --force
node lib/restore.js purge --days 7

restore 默认拒绝覆盖现有文件(--force 才覆盖),并且只还原清单里记录在工作区根内的路径。

Shell 备份是尽力而为:路径解析仍是词法级,find -delete、管道删除、node -e 这类”目标在命令内部”的操作没有可打包的显式路径,仍只靠询问拦截;git clean / git reset --hard 见下一条。文件工具的备份是精确的。git clean / git reset --hard / git checkout -- . 这类”目标在 Git 索引里”的操作,无法从命令行枚举目标,会退化为整个会话工作区的快照(同样受 backupMaxBytes / backupMaxFiles 限制);超大工作区会转为询问。

安装与启用

通过 npm 安装:

npm install dsh-hard-gate

安装后,插件会自动将配置挂载到 cordis.patch.yml 中。如需启用 Auto 模式,需在 profile 的 dsh.profile.bundles 中移除内置的 @deepseek-ai/dsh-experimental-auto-review,否则插件会记录警告并让内置审查器继续工作。

配置示例

安装后的默认值已经偏向「更严格但仍可用」。所有键都可以在 profile 的 cordis.patch.yml 里覆盖:

- id: hard-gate
  config:
    extraRoots: ['D:\dev\shared-lib']
    shellOutsideWorkspace: ask
    maxMutationsPerWindow: 40

覆盖是整对象替换:patch 中命中同一 id 会替换完整 config,需要保留的键请一并写出。

常用配置项包括:

  • enforceWorkspaceOnly:默认 true,文件工具不得写出工作区(Full access 下同样生效)。
  • extraRoots:默认 [],额外可写入的根目录(即使 danger-full-access)。
  • shellOutsideWorkspace:默认 deny,Shell 工具在工作区外的行为(deny / ask)。
  • maxMutationsPerWindow:默认 60,10 分钟窗口内的最大变更次数(deny)。
  • backupMaxBytes:默认 64 MiB,单次备份最大字节数。
  • backupMaxFiles:默认 2000,单次备份最大文件数。
  • backupRetentionDays:默认 14,备份保留天数。
  • backupTotalSize:默认 512 MiB,备份总大小上限。

适用场景与注意

  • 适合对权限控制要求较高的 DSH 使用者,特别是在 danger-full-access 下仍需保留路径限制的场景。
  • 插件以当前 DSH 进程权限运行,安装前建议检查源码与许可证。
  • Auto 模式与内置 @deepseek-ai/dsh-experimental-auto-review 不能同时启用,需手动从 dsh.profile.bundles 中移除。
  • Shell 备份是词法级解析,find -delete、管道删除、node -e 等操作无法打包显式路径,只能靠规则拦截。

总结

dsh-hard-gate 为 DeepSeek Harness 提供了一道独立于系统 ACL 的最后闸门,补齐了工作区写入零审批、整文件替换缺乏视图完整性检查、ACL 失败后兜底缺失三个结构性缺口。它通过挂载点、文件工具规则、Shell 规则、Auto 模式和还原点,在保持可用性的同时显著提升安全性。

插件目录页
GitHub 仓库

羽毛球分组比赛记分
小程序二维码

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

小夜