A DeepSeek Harness Plugin Security Checklist (10 Points)
A 10-point checklist for vetting a DeepSeek Harness plugin before dsh plugin add: what allowBuilds grants, what to read in the patch file, what to pin.
Installing a DeepSeek Harness (dsh) plugin means running code you didn't write on your machine — at install time, and again every time the plugin's apply() function executes. There's no official plugin review process and no marketplace vetting anything before you dsh plugin add it. This checklist covers the ten things worth checking, in the order they actually matter, before you install a plugin you haven't personally reviewed.
Why this matters more than it sounds
dsh's own documentation is unusually direct about this. Describing the allowBuilds permission that a GitHub-sourced plugin's build step may require, the docs state plainly:
Treat that allowance as what it is: permission to execute the package's code on your machine at install time, outside any sandbox the agent runs under. Only allow packages whose source you trust, and pin a commit.
That warning generalizes beyond allowBuilds — it's true of installing any plugin at all, because a plugin's apply(ctx) function runs with whatever access the Node.js process itself has, not constrained by dsh's runtime sandbox modes (read-only, workspace-write, danger-full-access). Those sandbox modes govern what the agent can do through its tools during a session; they don't govern what a plugin's own code can do when it loads.
1. Confirm it's actually a plugin, not just topic-tagged
Open the repository's package.json and look for a dsh field with a bundle or profile sub-key. A repo can carry the dsh-plugin GitHub topic without declaring this field — that's a self-reported tag, not a functional signal. No dsh field means dsh plugin add won't activate any configuration from it even if pnpm installs it fine. See our guide on finding DeepSeek Harness plugins for the full discovery landscape.
2. Read the patch file the dsh.bundle field points to
{ "dsh": { "bundle": { "patch": "./cordis.patch.yml" } } }
That cordis.patch.yml (or whatever it's actually named — the path is read from the field, not a fixed filename) is a YAML list describing exactly what the plugin inserts or overrides in your configuration tree. Reading it tells you what modules it's loading, what services it depends on, and — critically — whether it's overriding an existing config line rather than just adding a new one. A patch overrides the entire config block for a matched id, not a deep merge, so an override can silently change more than its README implies.
3. Check package.json for a prepare script and dependencies
A prepare script runs automatically on install for GitHub-sourced plugins (see point 5 below). Independent of that, look at the full dependencies list — an unusually long dependency tree, or dependencies with no obvious relationship to what the plugin claims to do, is worth a second look before installing.
4. Look for outbound network calls in the source
A plugin that calls a tool or an LLM adapter needs network access to function — that's expected. What's worth scrutinizing is a call to an endpoint that has nothing to do with the plugin's stated purpose, especially one made during module load or apply() rather than in response to something the agent explicitly did. Grep the source for fetch, http, https, or any HTTP client import as a starting point.
5. Understand what allowBuilds actually grants
GitHub installs pull source, not build output. If a plugin needs a prepare script to compile itself, pnpm 10+ blocks that script by default, and you'll be asked to explicitly allow it in the profile's pnpm-workspace.yaml:
allowBuilds:
dsh-hello-plugin: true
This is the single highest-leverage moment in the whole install flow — it's the one point where you're granting arbitrary code execution before dsh's own sandboxing has any chance to apply. Our GitHub install guide covers this prompt in full detail.
6. Pin to a commit, not a branch
dsh plugin --profile web add github:owner/repo#a1b2c3d
A branch reference (or the default, unpinned form) means a future push to the same branch changes what code runs on your machine the next time you reinstall or update — without any new approval from you. A commit SHA is the only pin that's actually immutable; a tag can technically still be force-moved by the repo owner.
7. Prefer npm-published plugins with prebuilt output when available
An npm-published plugin ships compiled output directly, so there's no prepare script and no allowBuilds decision to make at all — one fewer install-time code-execution surface. This is also the path dsh's own documentation recommends to plugin authors. If a plugin you want exists in both forms, the npm version is the lower-risk install.
8. Install new or unreviewed plugins under workspace-write, not danger-full-access
dsh's default permission preset for a new session is workspace-write + ask approval — writes are confined to the session's workspace and platform temp directories, and risky actions prompt for approval. danger-full-access removes both constraints entirely. When trying an unfamiliar plugin for the first time, stay on the default preset rather than switching to danger-full-access "to make it work" — if a plugin only functions under full access, that's itself worth treating as a signal to investigate why before granting it. See our permissions and sandbox guide for how the presets actually work.
9. Isolate new plugins in a dedicated profile
Because a profile is just a directory with its own bundle list and cordis.patch.yml, trying a new or unfamiliar plugin in a throwaway profile (dsh plugin --profile scratch add ...) keeps it separate from the plugins and config you rely on daily. If something goes wrong, the blast radius is that one profile, not your primary setup.
10. Treat community security tools as a second opinion, not a guarantee
A few community-built plugins exist specifically to help with this kind of review. dsh-security-audit runs a local, read-only audit covering config, plugin origins, sessions, and network exposure. dsh-plugin-check runs health checks against the manifest protocol and patch format, and flags known build traps. dsh-mcpguard scans skills and MCP configs specifically for prompt injection patterns, homoglyphs, and hidden Unicode. Separately, a plugin called dsh-poison-guard — described in community discussion as an AST-based scanner for obfuscated malicious code (hex-encoded Buffer.from calls, atob-hidden URLs, and similar patterns) — has come up in community channels, but it does not appear in FindHarness's own plugin index and we have not independently verified it. All of these are community projects, not part of dsh itself, and none of them have been independently verified by us. Running a scanner is a reasonable second opinion; it's not a substitute for reading points 1 through 4 yourself.
Being listed on a directory isn't a security audit
Being indexed here — whether in the curated set sourced from the community awesome list or the broader discovery set from npm and GitHub topic search — means a plugin's package.json declares a real dsh field and has a working GitHub repository behind it. It is a discoverability signal, not a security review. Nothing on this site substitutes for reading a plugin's source before you grant it allowBuilds or install it into a profile you rely on.
FAQ
Is it safe to install any plugin listed on an awesome list?
No list — community-maintained or otherwise — implies a security review. Manual curation filters out dead or unrelated repos, but it doesn't check what a plugin's code actually does. Apply this checklist regardless of where you found the plugin.
What's the single riskiest moment in installing a plugin?
Granting allowBuilds: true on a GitHub-sourced plugin you haven't read. That's the specific point where you're authorizing arbitrary code execution on your machine, outside any dsh sandbox.
Does workspace-write mode actually protect me from a malicious plugin?
Only partially, and only against the agent's actions during a session — not against a plugin's own code at load time or install time. A plugin's apply() function and any install-time prepare script run with the Node.js process's own permissions, unaffected by the session's sandbox mode.
Should I trust a plugin more if it has a high star count?
Star count reflects popularity, not security. It's a weak, gameable signal at best. Reading the patch file and the plugin's actual entry point is a stronger check than any star count.
Is dsh-poison-guard an official DeepSeek tool?
No. It's a community-built scanner mentioned in public discussion, not part of the official deepseek-ai/deepseek-harness repository, and it isn't in our own plugin index. Treat any third-party scanning tool — including this one — as an unverified community project.
Next steps
For the mechanics of a GitHub install specifically, read installing plugins from GitHub. For the permission and sandbox model this checklist references, see permissions and sandbox in DeepSeek Harness. If you're rolling this out across more than one person, running DeepSeek Harness in a team covers plugin approval policy at that scale.