DeepSHPlugins
dsh-provenance 项目预览
GITHUB / COMMUNITY PROJECT

dsh-provenance

安全与运维TypeScriptMIT

为 DeepSeek Harness 插件做安装前供应链校验:在代码运行前核对即将安装的包是否与你读到的源码一致。

1 StarsDarren-Tang 更新时间 2026-08-19
访问 GitHub 仓库
dsh-provenance 项目预览
dsh-provenance 界面截图dsh-provenance 界面截图

项目介绍

中文

为 DeepSeek Harness 插件做安装前供应链校验:在代码运行前核对即将安装的包是否与你读到的源码一致。

English

Pre-install supply-chain checks for DeepSeek Harness plugins: verify the tarball you are about to install matches the source you read, before any code runs.

项目信息与收录信号

快照 2026-09-11
作者 / 组织
Darren-Tang
仓库
Darren-Tang/dsh-provenance
GitHub Stars
1
Forks
0
开发语言
TypeScript
许可证
MIT
最近推送
2026-08-19
Manifest
数据中检测到声明

公开仓库不自动等于可商用;许可证与当前兼容性以原项目文档为准。Manifest 和数据评分不构成安装安全认证。

数据评分

52/ 100
维护活跃
85
文档与实用信息
85
生态关注度
9
安装便捷信号
100
项目声明信号
100

近 23 天仍在更新;README 含完整安装与使用说明;关注度尚低(1)。

评分来自已有数据快照的五维模型,仅作浏览参考,不是实际使用评测或安全检测结论。

安装与使用

所有项目资料与许可均以对应 GitHub 仓库为准。

dsh plugin --profile web add dsh-provenance

复制命令不会自动执行。请先阅读仓库文档,确认环境要求与许可证。

项目截图

仓库 README

GitHub 原文

已保存的仓库文档快照;文档抓取时间未记录,可能与上方目录介绍处于不同版本。安装前请核对当前仓库说明。

dsh-provenance

English | 中文

npm version npm downloads license dsh-plugin CI

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.

dsh-provenance demo

dsh-provenance demo (animated)

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.


What it checks

CheckQuestion answered
Source pinningDoes this specifier identify *immutable* content, or can it change under the same name?
Registry integrityDo the bytes we received match the digest the registry publishes?
Install hooksWill code execute during dsh plugin add, before any post-install scan can look?
Build provenanceDoes a SLSA attestation tie this artifact to a specific commit and CI workflow?
Artifact vs sourceDo the published files actually match that commit — and was anything added at publish time?

Why pinning matters more than it looks

[email protected]          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.


Install

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.


Use

Before installing anything

dsh-provenance preflight [email protected]
dsh-provenance preflight github:owner/repo
dsh-provenance preflight some-plugin --json      # for CI

Inside dsh

Two tools are registered, so the agent can run the checks itself:

  • provenance_preflight — audit an install source before installing
  • provenance_verify — inspect what is already installed in a profile

Auditing what you already installed

dsh-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.

CI

As a gate in your own pipeline:

dsh-provenance preflight [email protected] --strict

Exit codes: 0 ok/notice, 1 review (with --strict), 2 block.

A full example — re-check the sources daily, because a moving git reference can change under the same name (see *Why pinning matters* above):

# .github/workflows/preflight.yml
name: preflight plugins

on:
  push:
    branches: [main]
  schedule:
    - cron: "0 3 * * *"   # daily: upstream branches/tags can move

jobs:
  preflight:
    runs-on: ubuntu-latest
    steps:
      - run: npm install -g dsh-provenance
      - run: dsh-provenance preflight [email protected] --strict
      - run: dsh-provenance preflight github:owner/repo#<sha> --strict

The install guard

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.


What this tool does NOT do

Stated plainly, because overstating scope is how security tooling does harm:

  • It does not verify sigstore signatures. Attestation payloads are parsed, not

cryptographically verified. Run npm audit signatures for that. Every report says so.

  • It cannot verify build output. lib/, dist/ and minified files are reported as

unverifiable, never as match. Verifying them requires reproducing the build.

  • A clean report is not proof of safety. It means these rules found nothing.
  • It is not a code scanner. It checks *where code came from*, not what it does. Pair it with a

behavioural scanner; the two answer different questions.

  • It is not a runtime ledger. It does not observe or record what a plugin does after install.

That is provenance in the audit-log sense, not provenance in the supply-chain sense. This tool runs *before* install and refuses; it does not run after and record.

The failure mode it refuses to have

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.


Safety properties

Auditing hostile packages is itself dangerous. Every report carries a guarantees block asserting:

  • The audited package is never executed. No package manager is invoked, so no install hook can

fire as a side effect of auditing.

  • Nothing is written to disk. Archives are parsed entirely in memory, which structurally

eliminates zip-slip, symlink escape and disk exhaustion rather than defending against them.

  • Egress is allowlisted to 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.

  • Bounded everywhere. Response size, gzip output, entry count and per-entry size all have hard

ceilings, so an archive cannot exhaust memory.

  • Credentials from the environment only. GITHUB_TOKEN is optional, used solely to raise the

anonymous rate limit, and never logged or persisted.


Architecture

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.

Development

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

License

MIT

使用前核对

安装步骤、兼容版本与授权范围以原项目当前文档为准。Stars 和评分是快照中的导航信号。

安装与排错 · 项目问题反馈

同类项目