- 1024 store channel:
npm i -g dsh1024once, thendsh1024 plugin --profile web add dsh-defend(counts toward the deepseek1024.com install ranking).
Prompt-injection, jailbreak, and secret-leak defense for DeepSeek Harness.
Rules decide the known. Interception decides the rest — and everything is audited.
| Surface | Status |
|---|---|
| Harness | DeepSeek Harness 0.1.1-rc.2 (peer ranges >=0.1.0-rc.8 <0.2.0; verified against checkout 0.1.2-alpha.3 on 2026-09-01) |
| Node | ^22.19.0 || >=24.0.0 |
| Platforms | All (pure host; no native code, no network) |
| Model | Any (detection runs before content reaches the model) |
dsh-defend puts two independent layers in front of the agent:
- Destructive-delete guard — the executable form of the 8·14/8·16 postmortem lesson. On
tools/pre-execute, recursively deleting shell commands are refused unless every target is an explicit absolute path inside the session workspace and outside the protected prefixes (home config,.dsh/.claude, system directories). Dry-run markers (-WhatIf,--dry-run,git clean -n) pass, because they are exactly the check the lesson demands. - Detection layer — ported from four upstream assets (all Apache-2.0, see THIRD_PARTY_NOTICES.md): 25 Prompt-Injection-Payloads rules, 25 Jailbreak-Detector patterns through a pure-TypeScript Aho-Corasick automaton, 12 secret grammars from Secret-Key-Leaker-Detect plus the issuers' public references, and the Prompt-Attack-Dataset kept verbatim as the regression benchmark.
Three interception points, one decision model each:
| Point | Scanned | Decision |
|---|---|---|
agent/pre-step |
inbound user messages | allow → next(); ask → approval; block → reject the step |
tools/pre-execute |
tool arguments | allow → next(); ask → approval; block → deny |
tools/post-execute |
tool results | allow → next(); ask → approval; block → corrective feedback |
Defaults: ask for every family, block for critical secrets (the upstream interrupt-on-sight semantics). No approval answerer = fail closed. Every pass-through calls next() — downstream policy plugins are never short-circuited.
inbound message ── agent/pre-step ── scan ── clean → next()/enter
tool arguments ── tools/pre-execute ── scan ── allow → next()
tool results ── tools/post-execute ── scan ── block → feedback
│
└─ defend/detection audit (rule id, family,
severity, decision — never matched text)
# 1. install the bundle into your profile
dsh plugin --profile web add "github:PerryLink/dsh-defend#main"
# or from npm (published releases)
dsh plugin --profile web add dsh-defend
# 2. restart and verify the row
dsh --profile web --dump-config | grep -A3 'id: dsh-defend'- git channel (latest
main):dsh plugin --profile web add "github:PerryLink/dsh-defend#main"— thepreparescript builds with production dependencies only. - npm channel (published releases):
dsh plugin --profile web add dsh-defend. - tarball channel:
pnpm packin this repo, thendsh plugin --profile web add ./dsh-defend-<version>.tgz. - uninstall:
dsh plugin --profile web remove dsh-defend(or remove the row from the profile patch).
All tunables are Schemastery Config fields (changeable from cordis.yml). An id-targeted override replaces the whole row — restate every key you need. cordis.patch.yml documents each key inline.
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
Master switch for both layers |
action |
deny |
Destructive-delete guard action (deny / ask) |
toolNames |
['bash','persistent-bash','terminal-bash'] |
Tool names whose command arguments the guard reviews |
detection.enabled |
true |
Detection-layer switch |
detection.maxScanChars |
10000 |
Scan cap per interception (head only) |
detection.normalizeUnicode |
true |
NFKC-normalize text before scanning (blocks lookalike-Unicode bypass) |
detection.secretMinEntropy |
3.0 |
Minimum Shannon entropy (bits/char) to admit a secret regex hit; 0 disables |
detection.injectionAction |
ask |
Injection family: allow / ask / block |
detection.jailbreakAction |
ask |
Jailbreak family: allow / ask / block |
detection.secretAction |
ask |
Secret family: allow / ask / block |
detection.secretBlockCritical |
true |
Critical secrets always block regardless of secretAction |
detection.audit |
true |
Write defend/detection session audit events |
detection.allowUnmarkedAudit |
false |
Keep writing session audit on hosts whose Session.append predates the ignorable marker (every released line so far) or that fail-closed on unknown event types (host 0.1.2-alpha.3+), accepting the unresumable-session hazard |
detection.maxReportEntries |
200 |
In-memory report ring-buffer cap |
registerCommand |
true |
Register the /defend command |
registerTool |
true |
Register the defend_report tool |
| Surface | Kind | Notes |
|---|---|---|
defend_report |
tool | Totals (recorded/blocked/asked), per-family counts, and the 20 most recent matches — never matched text |
/defend |
command | The same summary as text |
agent/pre-step |
listener | Inbound message scanning (enter/reject) |
tools/pre-execute |
listener | Tool-argument scanning (deny/ask) + the destructive-delete guard |
tools/post-execute |
listener | Tool-result scanning (block feedback) |
- Permissions: ask decisions ride the official approval seam; nothing is re-implemented or bypassed. The plugin declares
session:appendandnetwork:nonein its workshop manifest. - Data: nothing is stored on disk; the report ring buffer is in-memory and bounded. No network requests, no subprocesses.
- Session log:
defend/detectionevents carry rule id, family, category, severity, secret type, decision, and scan facts — matched text never reaches the log, and secret matches are type-only by construction.
- Detection, not enforcement. The guard and the detection layer only produce deny/ask/block decisions on official seams; the sandbox and approval systems remain the enforcement authorities.
- Fail closed. Missing approval answerer, missing session, or a missing services surface degrades to the strictest decision — never to silent pass-through.
- No content leaves the process. Scanning is local; audit events are sanitized; secrets are never logged, displayed, or reported.
- Bounded work. Scan caps, one match per rule, and ring-buffer bounds keep hostile inputs from consuming unbounded resources.
- Detection gaps. The rule library catches the ported vocabularies and their tolerant variants; novel phrasing, lookalike-Unicode encodings (NFKC normalization is tracked as future work), and multi-step attacks can evade it. The benchmark pins the measured floor (27/28 on the upstream dataset) so regressions are visible.
- No model-level verdicts.
dsh-defendis deterministic; it never calls a model and cannot judge novel intent. - Message rejection is silent.
agent/pre-stepreject carries no reason to the model (the seam has no reason field); the audit event records the rule facts. - Session audit and the
ignorablemarker. Audit appends request the envelope'signorable: truemarker so any harness build can load the log. Every released harness line so far (0.1.0-rc.1–0.1.0-rc.8,0.1.1-rc.1–0.1.1-rc.2) silently drops it — the event lands unmarked and makes the session unresumable on stricter builds; host0.1.2-alpha.3retains the envelope field for stored-log read compatibility only, butSession.appendstill cannot stamp it and the read path rejects unmarked unknown event types (defend/detectionis not registered), so writing there also makes the session unloadable. dsh-defend therefore decides BEFORE the first append (peer-version pre-check; unresolvable versions fail closed) and disables session-log audit with a one-time warning. Setdetection.allowUnmarkedAudit: trueto opt back in. See issue #2.
pnpm install # node ^22.19 || >=24
pnpm run typecheck # tsc: src + tests against the local harness checkout
pnpm run typecheck:ci # tsc against the published 0.1.1-rc.2 types (no paths)
pnpm test # vitest: 75 tests, 8 suites (detection benchmark incl.)
pnpm run build # tsdown bundle + tsc declarations (lib/)
pnpm run verify:self-contained # dependency specs resolve from the registry
pnpm run verify:artifacts # built ESM face + shipped files present
pnpm pack # the published tarballThe red-team benchmark (per-category P/R/F1 over 105 samples, plus the 27/28 fixture floor) is published in benchmark/RESULTS.md; regenerate it with node --experimental-strip-types benchmark/run.mjs (zero new dependencies, no build step).
dsh, dsh-plugin, deepseek-harness, deepseek, cordis, security, prompt-injection, jailbreak, secret-scanning, ai-safety
- @PerryLink — creator and maintainer: destructive-delete guard, the four-asset detection port, interception wiring, audit surface, and the five-language docs.
- @cuohua — the precise report on
defend/detectionevents landing unmarked and making sessions unresumable on stricter builds (#2); the runtime host-capability detection and theignorable-marker discipline derive directly from that analysis.
This project is one of the 33 DeepSeek Harness plugins maintained by PerryLink. If this one helps you, the others likely will too:
| Plugin | One-liner |
|---|---|
| dsh-dsh-auto-review | Second-model auto-review on the approval chain, fail-closed by default |
| dsh-dsh-background-agents | Durable background child agents with a Web UI sidebar, messaging and interrupt |
| dsh-dsh-budget | Cost governance for DeepSeek Harness: budgets, carbon, and latency in one panel. |
| dsh-dsh-checkpoint-rewind | Claude Code /rewind-equivalent: snapshots, session forks, one-shot restore |
| dsh-dsh-claude-move | Migrate Claude Code sessions, memory, skills and CLAUDE.md into DSH |
| dsh-dsh-click | Cross-platform native desktop control for DeepSeek Harness — Windows first. |
| dsh-dsh-composer-history | Terminal-style input history for the web composer: arrows, Ctrl+R search |
| dsh-dsh-data-quality | Dataset quality checks and citation cross-checks (the optional numeric bridge consumed here) |
| dsh-dsh-doublecheck | Engineering-discipline guard: requirements grill, test gates, adversary review |
| dsh-dsh-draw | Unified static-image generation routing for DeepSeek Harness. |
| dsh-dsh-fast | Read-only performance diagnostics for DeepSeek Harness. |
| dsh-dsh-fund-research | Deterministic research reports for Chinese public mutual funds |
| dsh-dsh-github | GitHub PR/issues integration for DSH, every write gated by approval |
| dsh-dsh-industry-research | Industry research orchestration that seals its deliverables through this plugin's ctx.researchReport.assemble |
| dsh-dsh-library | Local document knowledge base for DeepSeek Harness. |
| dsh-dsh-local-ai | Local-model (Ollama) integration for DeepSeek Harness. |
| dsh-dsh-lsp-actions | LSP diagnostics, formatting, completion, code actions and rename over language servers |
| dsh-dsh-mask | PII masking middleware: anonymize at the model boundary, restore at the display layer |
| dsh-dsh-mcp-panel | Read-only MCP runtime panel: /mcp command + Settings tab with status, tools and errors |
| dsh-dsh-memento | Approval-gated cross-session memory: ctx.memory seam + SQLite + memory tool |
| dsh-dsh-observe | OpenTelemetry and Langfuse observability exporter for DeepSeek Harness. |
| dsh-dsh-output-styles | Claude Code outputStyles-equivalent runtime style switching |
| dsh-dsh-permission-rules | Claude Code-style declarative allow/deny/ask permission rules with audit |
| dsh-dsh-plugin-guide | Plugin-development knowledge base as an on-demand agent skill |
| dsh-dsh-research-report | Verifiable research-report engine: content-addressed evidence ledger and sealed versions |
| dsh-dsh-score | Multi-dimensional quality scoring for DeepSeek Harness plugins. |
| dsh-dsh-session-pin | Pin sessions in the Web sidebar with durable ordering |
| dsh-dsh-session-sync | Cross-device session sync for DeepSeek Harness — a dedicated git mirror of your session store. |
| dsh-dsh-skill-pack-security | Security-audit skill pack: secret scan, dependency and supply-chain review |
| dsh-dsh-talk | Voice-first session loop for DeepSeek Harness: talk to it, hear it answer. |
| dsh-dsh-test-drive | Isolated install-and-smoke test drives for DeepSeek Harness plugins. |
| dsh-dsh-translate | Vendor parameter translation and deterministic JSON repair for DeepSeek Harness. |
Apache License 2.0 © 2026 dsh-defend contributors