Skip to content
dsh.fish
Bundle

dsh-approval-flow-poc

A fail-closed, auditable approval policy plugin for DeepSeek Harness

Source
lasoloryan
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-approval-flow-poc

> **非官方社区实验。** 本项目与 DeepSeek AI 无隶属或背书关系,不是生产安全承诺。

一个面向 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的最小企业审批策略插件:在官方 `tools/pre-execute` 扩展点上,把工具调用分成 `allow`、`deny`、`requireApproval` 三类,并生成脱敏 JSONL 审计记录。需要人工确认时,插件返回 DSH 原生 `ask` 决策,由 DSH 内置审批服务和 Web UI 完成一次性授权;本项目不修改官方核心。

## 验证基线

| 项目 | 验证值 |
|---|---|
| DSH npm | `@deepseek-ai/dsh@0.1.0-rc.6` |
| DSH 源码 | `47f943859bef60e4160492346772ded9b24f765a` |
| Node.js | `v24.19.0` |
| 验证日期 | `2026-08-15` |
| 项目版本 | `0.1.0-beta.1` |

DSH 当前仍处于 developer preview,官方明确提示会有不兼容改动;升级 DSH 后请重新执行本文的配置检查和测试。

## 功能边界

- 基于工具名和脱敏参数摘要评估 `low`、`medium`、`high`、`critical` 风险。
- `critical` 默认拒绝;其他风险按 `developer`、`production`、`strict` 预设处理。
- `allow` 会继续委托后续策略,不会绕过 DSH 自带安全控制。
- `requireApproval` 使用 DSH 原生审批通道;无可用审批通道时由 DSH 自动拒绝。
- 审计日志只记录脱敏摘要、策略决定和最终错误状态,不记录原始参数。
- 提供可注入的 `ApprovalTransport` 接口,以及用于无界面调试的本地 TTY transport。

这个 PoC **不提供** SSO、RBAC、多级会签、远程 Webhook、不可篡改日志或合规认证。

## 安装

从 GitHub 安装到 Web profile:

```bash
npx @deepseek-ai/dsh plugin --profile web add github:lasoloryan/dsh-approval-flow-poc
npx @deepseek-ai/dsh --profile web --dump-config
npx @deepseek-ai/dsh web
```

在配置输出中应看到:

```yaml
- id: approval-flow-policy
  name: dsh-approval-flow-poc
```

从本地 checkout 验证:

```bash
npm install
npm run check
npx @deepseek-ai/dsh plugin --profile web add .
npx @deepseek-ai/dsh web
```

如果 pnpm 阻止 Git 依赖的 `prepare` 脚本,请按 pnpm 输出的精确提示在对应 profile 的 `pnpm-workspace.yaml` 中允许该包构建,然后重新执行安装;不要关闭全部构建保护。

## 三套策略

| 预设 | low | medium | high | critical | 适用场景 |
|---|---|---|---|---|---|
| `developer` | 委托/允许 | 委托/允许 | 人工审批 | 拒绝 | 本地开发 |
| `production` | 委托/允许 | 人工审批 | 人工审批 | 拒绝 | 预生产或受控运行 |
| `strict` | 委托/允许 | 人工审批 | 拒绝 | 拒绝 | 高敏感演示 |

`allow` 实际上调用 `next()`,所以后续 DSH 策略仍可拒绝该调用。

切换预设时,在 profile 的 `cordis.patch.yml` 覆盖完整配置:

```yaml
- id: approval-flow-policy
  config:
    preset: production
    auditPath: .dsh-approval-flow/audit.jsonl
    approvalTimeoutMs: 45000
    localPrompt: false
    include: []
    exclude: []
```

注意:DSH patch 对同一 row 的 `config` 是整体替换,不是深度合并,因此覆盖时应写全字段。

## 公共接口

```ts
export interface ApprovalRequest {
  requestId: string
  callId: string
  toolName: string
  summary: string
  risk: 'low' | 'medium' | 'high' | 'critical'
  createdAt: string
  expiresAt: string
}

export interface ApprovalDecision {
  requestId: string
  decision: 'allow' | 'deny'
  reason: string
  decidedAt: string
}

export interface ApprovalTransport {
  requestApproval(request: ApprovalRequest, signal?: AbortSignal): Promise<ApprovalDecision>
}
```

当前 DSH 适配器把 `requireApproval` 映射为官方 `{ kind: 'ask' }`。`ApprovalTransport` 为后续 Webhook/飞书/企微适配保留稳定的最小 seam;本版本只提供本地 TTY 实现。

## 审计示例

```json
{"schemaVersion":1,"event":"policy-decision","timestamp":"2026-08-15T00:00:00.000Z","request":{"requestId":"…","callId":"…","toolName":"bash","summary":"{\"cmd\":\"deploy\",\"token\":\"[REDACTED]\"}","risk":"high","createdAt":"…","expiresAt":"…"},"decision":"requireApproval","reason":"high-risk action requires one-time approval"}
```

日志默认写到当前项目的 `.dsh-approval-flow/audit.jsonl`。它是调试和取证线索,不是防篡改账本;生产环境应接入受保护的集中日志系统。

## 测试

```bash
npm run check
```

当前测试覆盖:风险分类、允许/拒绝/需要审批、敏感字段脱敏、本地批准/拒绝、审批超时默认拒绝和 JSONL 审计。

## 配套内容

- [《DSH 插件开发周末速通——企业审批实战》](docs/BLUEPAPER.md)
- [知乎发布稿:《如何评价 DeepSeek Harness?》](docs/ZHIHU.md)
- [B 站视频脚本:《两天做出第一个 DSH 企业审批插件》](video/SCRIPT.md)
- [需求登记页](https://dsh-approval-flow-lasoloryan.lasoloryan.chatgpt.site/?source=github)

## 反馈

请在 [GitHub Issues](https://github.com/lasoloryan/dsh-approval-flow-poc/issues) 提交可复现问题。工具包、训练营和企业诊断仅做需求验证,不在本 Beta 中收费交付。

## License

MIT

Install

dsh plugin --profile web add github:lasoloryan/dsh-approval-flow-poc

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source