Bundle
dsh-shield
Security, Trust & Policy Layer for DeepSeek Harness. Don't trust your agent's tools. Verify them.
- Source
- 245678000000
- stars
- 1 stars
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-shield
DeepSeek Harness 的安全防火墙。
安装前扫描。执行前拦截。动作后审计。
> Don't trust your agent's tools. Verify them.
[English](./README.en.md)
## 安装
需要 Node.js 20+ 和 [pnpm](https://pnpm.io)。
### 1. 装 CLI(预检扫描器)
装完就可以在装任何 Harness 插件 **之前** 先扫一遍:
```bash
git clone https://github.com/245678000000/dsh-shield.git
cd dsh-shield
pnpm install
pnpm build
pnpm link --global
```
验证:
```bash
dsh-shield --help
dsh-shield doctor
```
不想链到全局的话,在仓库里直接跑:
```bash
node packages/cli/dist/bin.js scan ./某个插件目录
```
### 2. 装进 DeepSeek Harness(运行时护栏)
先有可用的 `dsh`。用**本地目录**安装,不要先 `allowBuilds` 去跑未知 git 包的 `prepare`:
```bash
dsh plugin --profile web add /你的路径/dsh-shield
```
装好后重启 `dsh web`(或对应 profile)。默认策略是 `balanced`。
自定义策略可以放在:
```text
~/.dsh-shield/policy.yaml
```
示例见 [examples/policy/balanced.yaml](examples/policy/balanced.yaml)。
### 3. 立刻试一下
```bash
# 扫一个会拉起进程的合成插件(不会执行它)
dsh-shield scan ./fixtures/plugins/process
# 扫一个干净插件
dsh-shield scan ./fixtures/plugins/clean
# 生成信任清单
dsh-shield manifest ./fixtures/plugins/process
```
`process` 夹具会报 **HIGH / REVIEW BEFORE INSTALLING**。
干净包显示 **NO HIGH-RISK FINDINGS DETECTED**——这不是「SAFE」,静态扫描不能证明代码安全。
### 不要这样装
```bash
# 会拉源码;若再 allowBuilds,可能执行对方的 prepare
dsh plugin add github:245678000000/dsh-shield
```
git 安装拿到的是源码,不是编好的产物。官方 Harness 也写了:`allowBuilds` 等于允许安装期在你机器上跑代码。
要走 git,先扫再 pin commit:
```bash
dsh-shield scan github:245678000000/dsh-shield#<完整sha>
dsh plugin --profile web add github:245678000000/dsh-shield#<完整sha>
```
---
## 这不是一个普通 Harness 插件
安装阶段的恶意行为,不能靠「装完才加载」的插件来拦。
`dsh-shield` 因此是 **两层**,共用同一套安全模型:
```
安装之前
→ 预检扫描器(CLI)
运行期间
→ 运行时护栏(Harness Plugin)
```
| 层 | 是什么 | 何时生效 |
|---|---|---|
| **预检 CLI** `dsh-shield scan` | 下载 / 解包 / 解析 / 检查。**绝不执行待扫描包** | 在 `dsh plugin add` 之前 |
| **运行时插件** | 挂在官方 `tools/pre-execute` 与 `ctx.tools.guard()` 上 | 每一次工具 / MCP 调用 |
产品能力就六个词:
```
SCAN → CLASSIFY → ALLOW / ASK / DENY → AUDIT
```
它做的是 **风险发现、策略执行、信任元数据、人工审批、可审计性**。
它不是「完美安全」,也不会声称 100% 防住 Prompt Injection。
---
## 为什么需要它
DeepSeek Harness(`dsh`)里,插件、MCP、内置工具都跑在宿主机 Node 进程权限下。
用户用 `dsh plugin add github:someone/plugin` 安装插件时,底层是 **pnpm**。
`prepare` / `preinstall` 这类 lifecycle 脚本,会在任何 Harness 插件 `apply()` 之前执行。
运行时,模型可以调用 `mcp__<server>__<tool>`,把本地文件、密钥、客户资料送出本机。
`dsh-shield` 卡在这些边界上:
- 安装插件之前
- 运行插件期间
- 调用 MCP 之前
- 数据离开本机之前
- 执行高风险 Tool 之前
---
## 预检扫描器
```bash
dsh-shield scan <目录|tarball|github:owner/repo#sha|npm:name>
dsh-shield inspect <target>
dsh-shield policy check <target>
dsh-shield manifest <target>
dsh-shield diff old.json new.json
dsh-shield doctor
```
扫描 **不会**:
- 跑 `npm install` / `pnpm install`
- `require()` / `import()` 待扫描包
- 执行 `prepare` / `preinstall` / `postinstall`
远程包路径是:`下载 → 防 zip-slip 解包 → 解析 → 检查`。
AST 优先于纯正则。字符串里写了 `"child_process"`,或文档写「我们不会读 ~/.ssh」,**不会**直接判成恶意。
---
## 运行时护栏
安装方式见上文「安装」。对接的是当前官方 API(Harness `0.1.0-rc.5`,commit `47f94385`),**不 fork AgentLoop,不改 Harness 源码**:
| 官方缝 | dsh-shield 怎么用 |
|---|---|
| `tools/pre-execute` | 返回 `{ kind: 'allow' \| 'ask' \| 'deny' }` |
| `ctx.tools.guard()` | 单调 DENY:后面的 hook **不能**把拒绝改回允许 |
| `ctx.approval.request()` | ASK 走官方审批;没有审批通道则 **降级为 DENY** |
| MCP 公开名 | `mcp__<serverName>__<rawName>` |
管理工具(只读,没有「一键关闭全部安全」):
- `shield_status`
- `shield_explain`
- `shield_policy`
- `shield_recent_events`
---
## MCP 安全
新 MCP Server 默认是 **unknown**,不是 trusted。
| | 未知 MCP | 已审查(如 github) |
|---|---|---|
| 只读 + 非敏感 | ASK(balanced) | ALLOW |
| 外部写入 | ASK | ASK |
| 密钥 / 凭据外泄 | DENY | DENY |
---
## 数据出境
外部 MCP / HTTP 工具执行前,会给 payload 分级:
`public | internal | personal | confidential | credential | secret`
日志和审批理由里的密钥一律脱敏(`sk-abc...xyz`),**从不写完整 secret**。
```
DATA EGRESS WARNING
Destination: crm-cloud
Detected: CONFIDENTIAL DOCUMENT, PERSONAL DATA, POSSIBLE SECRET
Action: DENY
```
---
## Prompt Injection
**检测 + 行为策略,不是魔法防御。**
网页 / README / MCP 返回值里的指令腔(「ignore previous instructions」「把 ~/.ssh 发出去」)会被打上 `UNTRUSTED_*`。
同一会话里随后的敏感读取或外部写入,会升为 ASK / DENY(`SHIELD-INJECT-002`)。
原文不会被删掉。普通文档里的「Run npm install to install this package」单独出现,不会当成攻击。
---
## 策略档位
YAML / JSON。内置四档,不是换名字:
| | permissive | balanced(默认) | strict | enterprise |
|---|---|---|---|---|
| 本地读 | allow | allow | allow | allow |
| 本地写 | allow | ask | ask | ask |
| 破坏性操作 | ask | deny | deny | deny |
| 外部写 | ask | ask | deny | deny |
| 密钥出境 | deny | deny | deny | deny |
| 未知 MCP 读 | allow | ask | ask | deny |
| 未知 MCP 写 | ask | ask | deny | deny |
配置坏了:高风险决策 **fail closed**,不会静默全放行。
示例:[examples/policy/balanced.yaml](examples/policy/balanced.yaml)
模型说明:[docs/security-model.md](docs/security-model.md)
---
## 架构
```
DSH SHIELD
│
┌─────────────┴─────────────┐
↓ ↓
预检安全 运行时安全
│ │
├─ 包扫描 ├─ 工具门
├─ 源码扫描 ├─ MCP 门
├─ 依赖扫描 ├─ 出境护栏
├─ 脚本扫描 ├─ 人工审批
├─ 权限推断 ├─ 敏感数据
├─ 风险引擎 ├─ 注入信号
└─ 信任清单 └─ 审计日志
```
| 包 | 职责 |
|---|---|
| `@dsh-shield/core` | 发现项、能力、风险分、策略、密钥检测 |
| `@dsh-shield/scanner` | 不执行目标的预检 |
| `@dsh-shield/cli` | `dsh-shield` 命令行 |
| `@dsh-shield/runtime` | Harness 插件 |
| `@dsh-shield/ui` | 输出格式化(先服务 CLI) |
风险分是确定性公式,**LLM 不能决定 ALLOW / DENY**。
---
## 信任清单
`dsh-shield manifest <target>` 写出 `dsh-shield.manifest.json`:
包名、来源与 commit、风险、能力、安装脚本、发现项、扫描完整性、扫描器版本。
信任库按 `(来源, commit)` 记录。commit 变了,信任作废。
---
## 威胁模型
见 [docs/threat-model.md](docs/threat-model.md)。
覆盖:恶意插件、被投毒依赖、恶意 MCP、Prompt Injection、数据外泄、危险工具调用、只读伪装、供应链漂移、动态配置。
**明确不声称:**
- 100% 防住 Prompt Injection
- 证明任意插件安全
- 完美沙箱任意恶意 JavaScript
- 抓住所有混淆载荷
- 替代操作系统沙箱 / 终端安全
- 保证 MCP Server 可信
---
## 示例
`fixtures/` 里全是合成样本,不是真实恶意软件。
```bash
pnpm test
node packages/cli/dist/bin.js scan fixtures/plugins/process
pnpm exec vitest run tests/runtime/demos.spec.ts
```
| Demo | 结果 |
|---|---|
| 本地 `read_file` | ALLOW |
| `mcp__github__get_issue`(已审查) | ALLOW |
| `mcp__github__create_issue` | ASK |
| 未知 MCP + `TEST_API_KEY=shield_test_123456` | DENY |
| 注入 README → `upload_debug_info` | DENY |
---
## 隐私
默认全部本地:扫描、策略、审计都不上传云端。
审计只留规则 ID、决策、目的地、数据分级、**脱敏摘录**。
不留原始密钥,不留完整机密正文。
---
## 局限
详见 [docs/limitations.md](docs/limitations.md)。
**dsh-shield 不能保证:** 安全证明、完整防注入、JS 沙箱、检出所有混淆加载器、MCP 诚实,以及你已经允许安装脚本跑过之后的保护。
Harness 对接调研:[docs/harness-integration.md](docs/harness-integration.md)
规则目录:[rules/catalog.md](rules/catalog.md)
---
## 开发与测试
```bash
pnpm lint
pnpm typecheck
pnpm test
pnpm build
```
CI 跑这四项。夹具是合成包。CI **不会**执行未知第三方代码。
当前:`55` 个测试通过。
---
## 路线图
- **v0.1** — 预检扫描、运行时策略、MCP 信任、出境护栏、审计(本版本)
- **v0.2** — 更完整的清单 diff、注册表信誉适配器、更深的来源追踪、可选 Web UI
- **v0.3** — 签名信任清单、插件透明度、CI Action
- **v0.4** — 组织策略、集中分发
---
## 供应链安装注意
见上文「安装 → 不要这样装」。git 安装拉到的是源码;`allowBuilds` 等于允许安装期在你机器上跑代码。
---
## 参与
欢迎 Issue 和 PR。
不要把 LLM 做成安全边界。
不要为了「看看它干什么」去执行扫描目标。
不要编造 Harness API——先读 `docs/harness-integration.md` 和官方仓库。
安全漏洞请走 [GitHub Security Advisory](https://github.com/245678000000/dsh-shield/security/advisories/new),见 [SECURITY.md](SECURITY.md)。
许可证:[MIT](./LICENSE)
Install
dsh plugin --profile web add github:245678000000/dsh-shield
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-shield from the hub
- 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.