helmd
ADWMC/helm-d单包逆向与渗透测试安全分析插件:首轮工具收敛、领域路由与 33 个工具,覆盖 APK、Web、原生二进制、协议、恶意样本与 LLM 场景的逆向分析、加壳脱壳与 License 破解绕过;内置 H-CoT 评估引擎(语义路由、/hcot 命令)、账本驱动的 Web 工作台与工具货架、磁盘案件工作区(证据链自动存证、E 编号结论校验、上下文压缩后恢复)、GitHub 工具检索与 361 篇按需参考文档。
P0–P4 确定性优先权限门控,含 Permissive 档位、学习沉淀与审批历史 UI;凭据/受保护路径硬拒绝,内部只读工具自动放行。
Compatibility note: v2.0.0 shipsja/kodictionaries, but official DSH exposes
onlyzh/enthroughLocaleRuntime(LOCALE_IDS = ["zh", "en"]). On stock DSH,
selectingja/kofails withlocale "" is not registered. Use a DSH fork that
updatesLOCALE_IDS(locale-settings.ts) andLOCALESlabels (client/index.ts), then
rebuild.
▼ DSH version compatibility
Two DSH lines are served from two long-lived branches, each with its own version
series, engines.dsh, and npm dist-tag (release layout):| DSH version | Branch | Version | npm tag |
| --- | --- | --- | --- |
| 0.1.0-rc.7 ~ 0.1.1-rc.x |legacy|1.x|@legacy|
| 0.1.2-alpha.1+ (incl. 0.1.5-rc.2) |main|2.x|@latest/@dsh-0.1.2(@2.xis a range) |
The series number tracks the DSH line (1.x= DSH ≤ 0.1.1,2.x= DSH 0.1.2+),
and the majors fence each other: a^1.xinstall never resolves a2.xrelease and
vice versa. engines.dsh states the same split but DSH never reads it — the rangesand dist-tags are what hold an old DSH on 1.x.@deepseek-ai/dsh-client-runtimewas removed at0.1.2-alpha.1— it did not
merely move. Thelegacyline still reachesctx.slotsthrough it;maingets
the same declaration from @deepseek-ai/dsh-client-ui-renderer/client. Twoversion-sensitive seams are handled by capability probes rather than version
checks: (1) settings registration uses register, which exists on both lines(installSectionis an addition, not a replacement); (2)effectivePolicyis a
private method of the user-approval service on both, so it is read behind a
typeof probe and degrades to “policy unknown” when absent or throwing.Version 2.6.0 — see the Changelog.
A single, self-sufficient, deterministic-first, fail-closed permission gate for DeepSeek Harness.
dsh-perm-gate decides every tool call through a fixed priority chain:
Stage · Decision · What it is P0 · deny · deterministic hard-deny: credential material, protected-path mutation, dangerous shell P1 · allow · a precise, bounded session grant P2 · deny/allow/ask · static rule chain: blacklist first, then allow, then ask P3 · allow/deny/ask · optional LLM semantic classifier (default off) P4 · ask · official approval seam
Strictly fail-closed: a P0 decision is never overridden by a grant, a rule, the classifier, or a human.
0.1.0-rc.2 0.1.0-rc.3 0.1.0-rc.6 0.1.0-rc.7 0.1.0-rc.8 0.1.1-rc.1 0.1.1-rc.2 0.1.2-rc.1 0.1.5-rc.1 0.1.5-rc.2 0.1.5-rc.3 0.1.7-rc.1 0.1.7-rc.2 0.2.0-rc.1 0.2.0-rc.2 0.2.1-rc.1 0.2.1-rc.2 0.2.1-rc.3 (18 rc releases across lines 0.1.0 / 0.1.1 / 0.1.2 / 0.1.5 / 0.1.7 / 0.2.0 / 0.2.1)0.2.0-rc.2 — evidence in .compat-results/The DSH safety ecosystem splits this across several plugins (dsh-permission-rules, dsh-auto-mode, dsh-auto-review, dsh-movein-permissions). dsh-perm-gate merges the gate + approval + (optional) classifier into one package, with one audit trail and no cross-plugin version coupling.
with recursive descent into sh -c/bash -c, pipeline detection, redirect-target checking, and recursive/force (rm -rf) recognition.
(tool, canonical fingerprint) grants with TTL + maxUses;re-running with a different target never reuses authority. Sub-agents inherit but cannot mint.
malformed rules, and source-hash compile caching.
{ignorable:true} event with its callId; themodel-visible reason matches the recorded outcome.
permissive, plus permissive-full) — an independent approval mode(separate from read-only, full-access and whitelist tiers) that is neither "auto-approve" nor blanket trust. Front-end exposes a single switch (permissive); the four backend strategies are combinable and driven by plugin settings — still fail-closed against P0. The permission picker and the settings row both show it under the product label 自动审查, with no icon. The permissive-full variant keeps the identical approval behaviour but drops the built-in file sandbox, which otherwise denies the named pipes git clone / Cygwin / ConPTY need.
trustEscalation) — a sandbox escalation is asked from*inside* the shell / pwsh / edit tool body, after tools/pre-execute, so the gate never saw it and a call it auto-allowed still prompted you to approve the widening. With this strategy on, the exact call the gate cleared (matched by callId) is answered here instead.
ask assafe / risky:; hard categories (deletion, credential, remote, system, bulk) always ask, neutral enters verdict learning, and every failure stays fail-closed.
count up; after the threshold, the *exact same operation* (fingerprint-matched) auto-allows.
browser half as a notice strip above the conversation input plus an approval-records tab (newest first) in the conversation view.
A preset deny-keyword blacklist (inherited from dsh-approval-gate's DEFAULT_DENY_KEYWORDS: rm -rf, push --force, drop table, mkfs, git reset --hard, docker system prune, …) vetoes any call whose text contains a keyword — case-insensitive substring, applied before whitelist, grants and LLM. It is editable as a list in the settings card (preset entries are tagged, and a one-click restore brings the preset back); unset or empty applies the preset — the blacklist never silently turns off.
Requires an existing DeepSeek Harness installation.
dsh plugin --profile web add dsh-perm-gateFull install, upgrade, migration and troubleshooting steps live in the Installation guide — also available in 中文 / 日本語 / 한국어.
dsh-perm-gate can run gate-allowed shell commands inside a Windows AppContainer instead of handing them back unconfined. The container token is created with zero network capabilities, so non-loopback egress is blocked by Windows Firewall (WFP) itself — not by an advisory environment variable. The container SID is OS-derived from the fixed name dsh-perm-gate.ac, so the one-time CheckNetIsolation LoopbackExempt (which lets the container reach 127.0.0.1) is a per-machine step, not a per-session one. Egress is therefore possible only through the network proxy:
sandboxEnabled (default false) — master switch. When on, every auto-allowed shell call isrewritten into the launcher invocation; a human-approved call is out of scope (the user approved it consciously). If the launcher cannot be built or the OS rejects the container launch, the call is denied (fail-closed) with reason sandbox: … — never run unconfined.
sandboxMode — workspace-write (default; workspace gets Modify + private temp FullControl,system dirs stay readable through the stock ALL APPLICATION PACKAGES ACEs) or read-only.
sandboxProxy — the proxy parameter: empty (default) follows the builtin filtered proxy'sactual 127.0.0.1: when networkEnabled; an explicit URL must be loopback-bound (the container cannot reach anything else) and destination filtering is that proxy's job.
sandboxLoopback — exempt (default; attempt the one-time exemption, warn with the exactelevated command if denied) or off.
The launcher is a small C# program shipped as source (assets/appcontainer-launcher.cs) and compiled on first use by the .NET Framework compiler every Windows carries (csc.exe); the plugin itself keeps zero native dependencies. Verify a machine end-to-end with:
node scripts/smoke-appcontainer.mjsKnown boundary: on Windows 11 25H2+ builds where the classic AppContainer creation APIs have been removed (verified on 26200) and the mxc replacement is not yet exposed (26600+), the launcher fails closed at the kernel step; the sandbox then denies sandboxed calls with a clear reason instead of running them unconfined. On Windows 10 / 11 ≤ 24H2 the documented classic path applies.
Add the plugin to cordis.yml:
- id: dsh-perm-gate
name: dsh-perm-gate
config:
rulesFile: ./permissions.yaml # optional; defaults to $DSH_HOME/perm-gate/rules.yml
dshHome: $DSH_HOME # root pinned for protected-target checks
defaultAction: ask # allow | ask | deny
gatePresets: [permissive, permissive-full] # tiers where the gate is active (default)
sessionSweep: true # hourly cleanup of archived/dead sessions' gate dataOn startup and every hour the gate reads DSH's workspace store ($DSH_HOME/storages/workspace.json, read-only) and classifies every session it holds authorization-chain data for. Sessions DSH has archived (global.archivedSessionIds) or no longer tracks at all have their decision events dropped from $DSH_HOME/perm-gate/events.jsonl and their pre-change snapshot files deleted from $DSH_HOME/perm-gate/snapshots/ — history the review page can no longer reach, for data the harness itself considers gone. Live sessions are untouched, unattributable rows (empty session id) are never deleted, and any failure is fail-open: the round is skipped and retried an hour later. Set sessionSweep: false to disable; workspaceStoreFile overrides the store path. Restoring an archived session does not restore its swept history.
permissions:
defaultAction: ask
deny:
- command: [rm#recursive]
reason: no recursive rm
- command: [ssh]
reason: no direct ssh
- paths: [.dsh/**]
reason: protect harness metadata
allow:
- command: [pnpm, node]
reason: dev tools
- command: [curl, wget]
args: ["https://*.example.com/*"]
reason: allowed endpoint
ask:
- command: [bash, sh]
reason: ask shellsA command entry word#flag matches the command word (word) with the modifier recursive or force — so rm#recursive matches rm -rf, env rm -rf, and sh -c "rm -rf /".