deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
INSTALL REFERENCE
dsh plugin --profile web add github:Darren-Tang/dsh-provenance
该命令指向仓库当前默认分支;尚无绑定当前 commit 的完整验证结果。
PROJECT README
The source you read on GitHub is not necessarily the package you install.
A supply-chain preflight for DeepSeek Harness plugins. It answers a question no other scanner in this ecosystem asks.
Existing plugin scanners read the files already on your disk and ask "does this code do something bad?". That is a useful question, but it comes second. The first question is:
Is this code the code the author showed me?
An npm tarball is whatever the publisher uploaded. The registry does not build it from the
repository, and nothing forces the two to agree. A publisher can push clean source to GitHub,
collect stars and reviews, then publish a tarball with one extra file in it. Every scanner that
runs after dsh plugin add will happily scan the injected file as if it belonged there — and by
then the package's install hooks have already executed.
dsh-provenance runs before installation and compares three independent sources of truth:
the npm registry, the upstream repository, and the bytes actually on the wire.
| Check | Question answered |
|---|---|
| Source pinning | Does this specifier identify immutable content, or can it change under the same name? |
| Registry integrity | Do the bytes we received match the digest the registry publishes? |
| Install hooks | Will code execute during dsh plugin add, before any post-install scan can look? |
| Build provenance | Does a SLSA attestation tie this artifact to a specific commit and CI workflow? |
| Artifact vs source | Do the published files actually match that commit — and was anything added at publish time? |
some-plugin@1.2.3 pinned a published npm version is immutable
some-plugin@^1.2.3 NOT pinned the next install may resolve elsewhere
github:owner/repo NOT pinned the default branch can be rewritten under the same name
github:owner/repo#v1.0.0 NOT pinned a tag can be moved by the repo owner
github:owner/repo#<sha> pinned a commit sha cannot be forged
A moving git reference is strictly worse than a floating npm range. With npm, the version you
audited stays byte-identical forever. With a branch, the code you reviewed and the code you
install can differ silently, and the plugin directories are full of github:owner/repo install
instructions.
As a dsh plugin:
dsh plugin --profile web add dsh-provenance
As a standalone CLI (no dsh required, useful in CI):
npm install -g dsh-provenance
Requires Node.js 22.19+. Zero runtime dependencies — a tool that inspects untrusted packages should not drag in a supply chain of its own.
dsh-provenance preflight some-plugin@1.2.3
dsh-provenance preflight github:owner/repo
dsh-provenance preflight some-plugin --json # for CI
Two tools are registered, so the agent can run the checks itself:
provenance_preflight — audit an install source before installingprovenance_verify — inspect what is already installed in a profiledsh-provenance verify --profile web
Fully local: no network, no plugin code executed. It reports which installed plugins are pinned, which can still be traced upstream, and which shipped install hooks that already ran.
dsh-provenance preflight some-plugin@1.2.3 --strict
Exit codes: 0 ok/notice, 1 review (with --strict), 2 block.
A dsh agent can run shell commands, which means the agent itself can be talked into installing a plugin — through a poisoned README, a fetched web page, or a crafted issue comment. Auditing only what a human types misses that path entirely.
So install attempts are intercepted and refused unless that source has already passed a preflight in this session:
dsh-provenance: refusing to install evil-plugin without a supply-chain preflight.
Installing runs the package's install hooks immediately, so this cannot be checked
afterwards. Call provenance_preflight with source="evil-plugin" first, then retry.
Disable with { guardInstalls: false } if it gets in your way.
Implementation note: this uses ctx.tools.guard() rather than the tools/pre-execute waterfall,
because guard's signature is documented exactly ((execution) => string | undefined, synchronous)
and its denial is monotonic — no later plugin can turn the refusal back into permission. The guard
reads execution.arguments, which is the field name the pipeline actually exposes; a comparable
tool in this ecosystem read exec.args and shipped a sentinel that never fired for two releases.
Stated plainly, because overstating scope is how security tooling does harm:
npm audit signatures for that. Every report says so.lib/, dist/ and minified files are reported as
unverifiable, never as match. Verifying them requires reproducing the build.If not a single published file can be matched against the repository, the report does not show a
reassuring 0 mismatch. It raises diff.nothing-verified and says the comparison verified nothing.
A tool that rounds "I could not check this" up to "this is fine" is worse than no tool, because
it manufactures false assurance out of missing evidence.
Auditing hostile packages is itself dangerous. Every report carries a guarantees block asserting:
registry.npmjs.org, codeload.github.com and api.github.com.
This matters: a malicious package controls its own repository.url, so without a fixed host
allowlist a scanner becomes an SSRF pivot into the operator's internal network. Literal IPs,
embedded credentials, non-default ports and redirects off the allowlist are all rejected.GITHUB_TOKEN is optional, used solely to raise the
anonymous rate limit, and never logged or persisted.src/core/ zero framework dependencies — the engine, fully unit-tested
src/index.ts thin dsh adapter
src/cli.ts standalone CLI
dsh v0.1 is a developer preview that states outright that breaking changes are coming. The supply-chain logic is therefore deliberately isolated from the harness interface: when dsh moves, only the thin adapter should need rewriting, and the CLI keeps working regardless.
npm install
npm test # builds core, then runs the suite
npm run typecheck # core only, no peer deps needed
npm run build # full build, needs the dsh peer packages
Tests exercise real gzip bytes, real tar headers and the real documented field names, rather than mocks that could mirror the same wrong assumption as the implementation.
Local development against a dsh source checkout:
npm run build
# set the absolute path inside cordis.yml first
pnpm dsh web --patch /absolute/path/to/dsh-provenance/cordis.yml
MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: 无有效分类标签。