🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

操作安全门禁 bbaz123/dsh-operation-security

DeepSeek Harness
bbaz1239 天前有提交已提供中文文档扫描:含敏感能力

为工具调用分级把关,拦截高风险插件安装

29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add bbaz123/dsh-operation-security
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · security
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 9 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 30 处,展示前 19 条)
  • 写入本地文件
    vendor/opsec/index.js:112
    mkdirSync(directory, { recursive: true });
  • 写入本地文件
    vendor/opsec/index.js:120
    appendFileSync(this.file, `${formatAuditLine(record)}\n`, "utf8");
  • 写入本地文件
    vendor/opsec/index.js:1313
    mkdirSync(directory, { recursive: true });
  • 读取本地文件
    vendor/opsec/index.js:1328
    const raw = JSON.parse(readFileSync(this.file, "utf8").replace(/^ FEFF/, ""));
  • 写入本地文件
    vendor/opsec/index.js:1361
    writeFileSync(temporary, JSON.stringify(document, null, 2), "utf8");
  • 写入本地文件
    vendor/opsec/index.js:1362
    renameSync(temporary, this.file);
  • 读取本地文件
    vendor/opsec/index.js:1476
    entries = readdirSync(path);
  • 读取本地文件
    vendor/opsec/index.js:1486
    isDirectory = statSync(child).isDirectory();
  • 读取本地文件
    vendor/opsec/index.js:1494
    if (!statSync(child).isFile()) continue;
  • 读取本地文件
    vendor/opsec/index.js:1499
    if (statSync(child).size > options.maxFileBytes) continue;
  • 读取本地文件
    vendor/opsec/index.js:1502
    content: readFileSync(child, "utf8")
  • 写入本地文件
    vendor/opsec/index.js:2065
    mkdirSync(path, { recursive: true });
  • 读取本地文件
    lib/gate/ack.js:45
    const readFile = options.readFile ?? ((file) => readFileSync(file, 'utf8'))
  • 写入本地文件
    lib/gate/ack.js:68
    mkdirSync(directory, { recursive: true })
  • 写入本地文件
    lib/gate/ack.js:71
    writeFileSync(temporary, `${JSON.stringify(acks, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/gate/ack.js:72
    renameSync(temporary, path)
  • 读取本地文件
    lib/gate/ack.js:112
    if (!existsSync(path)) return false
  • 删除本地文件
    lib/gate/ack.js:120
    unlinkSync(path)
  • 读取本地文件
    lib/gate/spec.js:53
    const readFile = options.readFile ?? ((path) => readFileSync(path, 'utf8'))
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 操作安全插件:工具 pre-execute 分类、单调 guard、插件生命周期 DPIP 门禁与审计留痕。

README

由 DeepSeek 最新模型翻译生成
dsh-operation-security 桌面版(Desktop / app.asar 0.2.1-rc.2)的操作安全层移植。npm-global CLI 安装树里有两样东西桌面版看不到,这个插件把它们带过来,并补上桌面版唯一可行的插件生命周期门禁位置。 它做的三件事 | 能力 | 来源 | 在桌面版怎么工作 | | 工具调用分级与策略执行 | @deepseek-ai/dsh-operation-security@0.2.0-rc.2 的构建产物(vendor/opsec/,逐字移植) | 注册 tools/pre-execute + 单调 ctx.tools.guard():READ / DOWNLOAD / EXECUTE / PLUGIN_* / EXPORT / PUBLISH;EXPORT/PUBLISH 额外做凭据扫描;拒绝不可被后续监听器翻回允许 | | 插件生命周期 DPIP 门禁 | CLI 里被插入 lib/plugin-.js 的 gatePluginInvocation | 包装 pluginManager.installBundle(以及启用路径的硬停检查)。
展开完整文档(README 剩余 1 节)
dsh-operation-security

桌面版(Desktop / app.asar 0.2.1-rc.2)的操作安全层移植。npm-global CLI 安装树里有两样东西桌面版看不到,这个插件把它们带过来,并补上桌面版唯一可行的插件生命周期门禁位置。

它做的三件事

| 能力 | 来源 | 在桌面版怎么工作 |
| 工具调用分级与策略执行 | @deepseek-ai/dsh-operation-security@0.2.0-rc.2 的构建产物(vendor/opsec/,逐字移植) | 注册 tools/pre-execute + 单调 ctx.tools.guard():READ / DOWNLOAD / EXECUTE / PLUGIN_* / EXPORT / PUBLISH;EXPORT/PUBLISH 额外做凭据扫描;拒绝不可被后续监听器翻回允许 |
| 插件生命周期 DPIP 门禁 | CLI 里被插入 lib/plugin-.js 的 gatePluginInvocation | 包装 pluginManager.installBundle(以及启用路径的硬停检查)。CLI 的 dsh plugin 在桌面版无法接管:desktop profile 由 Electron 独占,且 GUI / Agent / 自安装页的写入都走 pluginManager 的 Gateway 方法,不经过工具流水线 |
| 审计 / 状态 / 恢复边界 | 同上包 | 写入 $DSH_HOME/operation-security/,与 CLI 门禁同一份 audit.jsonl 与 plugin-state.json |

门禁语义(与 CLI 一致)

装/升级(installBundle) ├─ 该插件记录为 BLOCKED / QUARANTINED / ROLLBACK_REQUIRED → 拒绝(确认也不能放行) ├─ 记录为 ACTIVE → 放行(coverage = active) ├─ 有有效确认(ack 文件,或 DSH_DPIP_ACK=1) → 放行(consumed = 一次) └─ 其余 → 拒绝,并给出可执行指令

启用(setBundleEnabled / setPluginEnabled,仅 enabled = true) └─ 只有硬停状态会被拒绝;未完成的协议记录不拦(CLI 也不拦启用)

拒绝会抛出一个 code = 'DSH_DPIP_REFUSED' 的错误,消息里带三样东西:缺什么(协议五步)、怎么确认(脚本绝对路径与命令)、硬停无法用确认绕过。

给未经审查的第三方插件开一次确认

node "<工作区>/dsh-operation-security/scripts/ack.mjs" @scope/name --note "看过 changelog,无 postinstall"

- 确认写入 $DSH_HOME/operation-security/dpip-ack.json,默认 24 小时有效;名称会按门禁的规则归一化(pkg@1.2.3 与 pkg 是同一个键);
- --ttl 0 表示「不设记录级上限」,实际仍受 gate.ackTtlHours 这个上限约束;只有把上限配成 0 才真的不过期;
- 一次成功安装后自动作废;
- 只有操作员(你)能写:Agent 和插件自己都不会调用这个脚本。

协议状态可以直接改(脚本不做协议迁移合法性校验,它是操作员入口而不是验证器):

node scripts/state.mjs list
node scripts/state.mjs set @scope/name ACTIVE # 视为协议已完成
node scripts/state.mjs set @scope/name BLOCKED # 硬停,确认也无效
node scripts/state.mjs remove @scope/name

配置

行配置在 cordis.patch.yml 里,全部字段见该文件注释。两个总开关:

- enabled: false → 两层都关闭,profile 回到装插件之前的状态;
- gate.enabled: false → 只保留工具层策略,不拦插件生命周期写入。

其余是上游 schema 的同名字段(requireApprovalForExecute / requireApprovalForOutput / scanRoots / scanMaxFiles / scanMaxFileBytes / enforcedOperations)。

外发扫描根:EXPORT/PUBLISH 的扫描根按「调用声明的 workdir(向上找 .git)→ 会话的沙箱工作区 → scanRoots」顺序解析。桌面宿主的进程 cwd 是 profile 目录,所以默认会跟随会话工作区;一旦显式配置了 scanRoots,就以你的配置为准。

目录

lib/index.js 插件入口:装工具层,再装服务门禁 lib/config.js 无 schemastery 的字段校验与默认值 lib/paths.js $DSH_HOME / profile 目录解析(只用 node 内建) lib/scan-roots.js 按调用解析外发扫描根(会话工作区) lib/gate/spec.js 安装 spec → 包名(状态键) lib/gate/decision.js 纯决策:ACTIVE / 确认 / 硬停 / 拒绝文案 lib/gate/ack.js dpip-ack.json 的原子读写 lib/gate/audit.js 审计记录(复用上游 buildAuditRecord) lib/gate/manager.js 在 pluginManager 原始实例上定义/回收方法 vendor/opsec/ 逐字移植的上游构建(改动见 docs/PATCH-NOTES.md) scripts/ack.mjs 操作员确认 scripts/state.mjs 协议状态查看/设置

验收

cd dsh-operation-security
node --test "test/.test.mjs"
node --check lib/index.js && node --check vendor/opsec/index.js

安装后做一次真实验收:对一个没有协议记录的包调用插件安装,应得到 DSH_DPIP_REFUSED,并新增一条 finalStatus: BLOCKED 的审计行。

已知边界

1. 只管运行中的宿主。 桌面版命令行(runtime/cli/bin/dsh.cmd)对非 desktop 配置档的 dsh plugin 仍然没有门禁——那需要改 app.asar 里的命令行代码,升级即失效,本插件不做。
2. 桌面配置档不能被命令行管理,所以先有插件、后有门禁:本插件的安装这次是门禁生效前的最后一次无约束安装。
3. enable 路径按 best effort 解析包名(listPlugins() 查不到时跳过额外检查),与命令行一致——命令行完全不检查启用。
4. plugin_manager 工具本身没有加进 detector:它的写入已经由服务门禁覆盖,再加一层会在门禁拒绝之前先弹一次审批。
5. 恢复边界只覆盖配置档的 package.json / pnpm-lock.yaml / pnpm-workspace.yaml / cordis.patch.yml,不含进程、服务与插件写到配置档之外的文件(审计记录里写明了这条 limits)。
6. 状态键是「按 spec 归一化出来的名字」:仓库名与本地目录能还原成包名,但 git / tarball URL 只能用 URL 本身作键。也就是说,一个已记录 BLOCKED 的包若改从 tarball 地址安装,不会复用按包名记的硬停,需要执行者显式确认(确认后仍会留下审计)。这是命令行门禁「按原始参数取值」的继承限制。
7. 安装失败时审计沿用上游语义:finalStatus: FAILED,但 securityResult 仍是 PASS(上游用它表示「没有安全门禁失败」)。判断成败看 finalStatus。
8. 每次放行安装都会在 recovery/ 留一份配置档四文件副本,没有自动清理;需要时手工删旧目录。
9. 相对 auditDir 按宿主进程 cwd 解析(当前是配置档目录),建议只写绝对路径或留空。
10. 外发扫描口径较严:工作区里只要有文件名命中凭据规则(例如任何 .npmrc),EXPORT/PUBLISH 都会判 CRITICAL。要缩小范围,给调用传 workdir,或在行配置里显式设 scanRoots。
预览分享卡片长什么样 ↓bbaz123/dsh-operation-security
分享 · DeepSeek Harness Hub
bbaz123/dsh-operation-security

为工具调用分级把关,拦截高风险插件安装

回到顶部