Skip to content
dsh.fish
Bundle

dsh-risk-gate

dsh-risk-gate

Source
leetom314
License
MIT
Updated
Updated 2 days ago

Readme

# dsh-risk-gate

Semantic risk grading + progressive authorization for DeepSeek Harness.
按操作**语义**自动分级,不要求用户写规则——把 Hermes Agent 的可逆性决策链移植成 dsh 插件。

## What it does

Hooks `tools/pre-execute` and classifies every tool call by **operation semantics**:

| Level | Meaning | Action |
|---|---|---|
| `safe` | reversible / read-only (read, search, web, benign bash) | pass through (`next()`) |
| `risky` | irreversible but low-risk (write, edit, install, git commit) | `ask` via approval seam |
| `redline` | one of four red lines: remote-state change / outbound message / delete / paid quota | `ask` with explicit redline type; fail-closed `deny` when no answerer |

Classification is **local and deterministic** — no network, no LLM call. Unknown tools default to `risky` (fail-closed).

### Progressive authorization (渐进授权)

Same operation signature approved-and-succeeded N times → auto-allowed afterward; a single failure/rejection zeroes the signature back to `ask`.

- Signature = tool name + normalized arguments (large text payloads truncated)
- Redline ops never auto-allow by default (`alwaysAskRedline: true`)
- State is per-process (in-memory); HMR dispose clears it

## Install

```bash
# from GitHub (requires dsh CLI; git-based install)
dsh plugin --profile web add "github:leetom314/dsh-risk-gate#main"

# or clone and verify locally first
git clone https://github.com/leetom314/dsh-risk-gate.git
cd dsh-risk-gate && ./setup.sh && npm test && ./verify.sh
```

## Config

```yaml
- id: dsh-risk-gate
  name: dsh-risk-gate
  config:
    autoAllowThreshold: 3      # 0 = disable progressive auth, always ask
    alwaysAskRedline: true     # redline ops never auto-allow
    verbose: false
    overrides:                 # optional per-tool override
      some_tool: deny          # 'safe' | 'deny'
```

## Test

```bash
npm test        # node --test (classifier + host-level progressive auth)
```

E2E (real model + headless profile, isolated DSH_HOME):

```bash
./setup.sh
DEEPSEEK_API_KEY=... ./verify.sh
# expect: read-only pass / rm single-file blocked / rm -rf redline blocked /
#         quoted echo string not blocked / git push + scp + ssh remote blocked
```

`verify.sh` 动态生成临时 overlay(`$HERE/index.js` 路径),不需要仓库内 overlay 文件——`overlay*.yml` 已 gitignore(含本机绝对路径,不随版本库分发)。

## How the semantics map (red lines)

Shell-command inspection (bash/pwsh only, conservative regex):

- **DELETE** — `rm -rf`, `shred`, `mkfs`, `dd ... of=/dev/...`
- **REMOTE** — `git push` (incl. `git -C dir push` variants), `git reset --hard`, `rsync user@host:`, `ssh user@host`, `curl/wget -X POST/PUT/DELETE`, data uploads
- **PAY** — cloud provisioning (`aws ec2 run-instances`, `gcloud compute`, ...)
- **MESSAGE** — outbound message tools (`send_message`, `im_send`, ...)

Tool-name mapping: `read/glob/grep/web_*/skill/job_*` safe · `write/edit/str_replace_editor/todo_write/create_goal` risky.

## Limitations

- Shell inspection is regex-based (no full shell parsing): designed to be conservative (false positives over misses), but a determined prompt can still smuggle commands through obfuscation. It is a **safety gate, not a sandbox** — pair with `dsh-permission-rules` / sandbox executors for defense in depth.
- Learning state is in-memory only (no persistence across restarts yet).
- Approval UI is channel-provided; headless with no answerer fails closed (deny).

Install

dsh plugin --profile web add github:leetom314/dsh-risk-gate

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source