dsh-risk-gate
No description
- Stars
- 0
- Language
- JavaScript
- Created
- Sep 8, 2026
- Updated
- Sep 8, 2026
Introduction
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
# 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
- 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
npm test # node --test (classifier + host-level progressive auth)
E2E (real model + headless profile, isolated DSH_HOME):
./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 pushvariants),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).