
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-install-guard
Advanced tools
Guard DeepSeek Harness npm installs with vulnerability, license, bundle-size, and package-health audits.
在 DeepSeek Harness 执行 npm install 之前,检查依赖漏洞、许可证、体积与包健康度,并按策略放行、请求人工确认或拒绝。
Audit npm dependencies for vulnerabilities, licenses, bundle size, and package health before DeepSeek Harness executes an install command.
dsh-install-guard 是一个 DeepSeek Harness(DSH)bundle。它监听 tools/pre-execute:
bash 工具中的 npm 安装命令;allow、ask 或 deny。ask 会进入 Harness 原生审批流程,命令尚未执行。插件同时注册只读工具 dep_check,供 agent 在选型时比较包,或显式审计工作区 package.json。
要求:
^22.19.0 || >=24.0.0>=0.1.0-rc.7 <0.2.0把 bundle 安装到 DSH profile(下面使用 web):
dsh plugin --profile web add dsh-install-guard
dsh --profile web --dump-config
dsh --profile web
包内含 dsh.bundle 声明,安装后会自动把 bundle 加入 profile。不要再手工 insert 同一个插件,否则可能产生重复的 loader id。
卸载:
dsh plugin --profile web remove dsh-install-guard
也可以从本地源码构建 tarball 后安装:
npm ci
npm pack
dsh plugin --profile web add ./dsh-install-guard-0.1.0.tgz
bundle 插入的稳定 row id 是 install-guard。在 profile 的 cordis.patch.yml(默认位于 $DSH_HOME/profiles/web/cordis.patch.yml,未设置 DSH_HOME 时通常是 ~/.dsh/profiles/web/cordis.patch.yml)中覆盖它:
- id: install-guard
config:
denySeverity: high
askSeverity: unknown
blockedLicenses:
- GPL
- AGPL
allowPackages:
- '@your-company/*'
maxBundleSizeKb: 20
minWeeklyDownloads: 100
minPackageAgeDays: 30
typosquatMaxDistance: 1
failClosed: false
DSH 的后置 patch 会替换该 row 的整个 config,不是深度合并;建议像上面一样列出完整配置。
| 配置 | 默认值 | 说明 |
|---|---|---|
denySeverity | high | 达到此漏洞等级时拒绝安装。可选 critical、high、medium、low、unknown。 |
askSeverity | unknown | 达到此漏洞等级时要求人工确认。 |
blockedLicenses | ["GPL", "AGPL"] | 许可证黑名单;支持 SPDX 名称或系列前缀。 |
allowPackages | [] | 完全跳过审计的包名;支持精确名称和 @scope/*。 |
maxBundleSizeKb | 20 | 非 tree-shakeable 包允许的最大 gzip 体积(十进制 KB)。 |
minWeeklyDownloads | 100 | 健康度启发式使用的最低周下载量。 |
minPackageAgeDays | 30 | “新且低下载量”检查的最短包龄。 |
typosquatMaxDistance | 1 | 与内置流行包名比较时允许的最大 Damerau–Levenshtein 距离。 |
failClosed | false | 网络检查失败或只能使用过期缓存时是否要求人工确认。 |
denySeverity 应不低于 askSeverity 的风险范围;否则高风险项仍会以 deny 优先。白名单会跳过所有四项检查,应谨慎使用。
registry.npmjs.org 与 api.osv.dev。latest、其他 dist-tag、精确版本或 semver 范围,再用确切版本查询 OSV npm ecosystem。deny,其余或未知等级为 ask。license。AND、OR、WITH 表达式。MIT OR GPL-3.0-only 在默认策略下可接受;只有所有 OR 分支都命中黑名单才标记为 blocked。ask,不直接 deny。bundlephobia.com/api/size。hasJSModule 与 hasSideEffects。ask;可 tree-shake 的包只报告“实际体积取决于用法”,不会仅因整包体积被拦截。api.npmjs.org/downloads 的最近一周下载量。ask。dep_check按包名比较候选依赖:
{
"packages": ["moment@^2", "dayjs@latest"]
}
显式审计工作区依赖:
{
"includePackageJson": true,
"packageJsonPath": "package.json"
}
也可以同时提供 packages 和 includePackageJson。工具会:
dependencies、devDependencies、optionalDependencies 与 peerDependencies;file:、git、URL 等非 registry spec,并在结果中给出原因;.. 或 symlink 逃逸;axios、chalk、lodash、moment、request、uuid 返回经过人工整理的轻量替代品和迁移注意事项。工具输出使用稳定的 schemaVersion: 1 JSON,并汇总 allow、ask、deny、degraded 与 skipped 数量。它不会隐式扫描 package.json;必须显式设置 includePackageJson: true。
| 输入或结果 | 默认行为 |
|---|---|
非 bash 工具、非 npm 安装命令 | 直接交给下游 |
无参数 npm install、npm ci | 直接交给下游(按现有 lockfile 安装) |
npm install/i/add 的 registry 包 | 解析后审计 |
| HIGH / CRITICAL 漏洞 | deny |
| MEDIUM / LOW / UNKNOWN 漏洞 | ask |
| 许可证黑名单命中或缺失 | ask |
| gzip 超限、不能确认可 tree-shake | ask |
| gzip 超限、可 tree-shake | 报告但不拦截 |
| 健康度启发式命中 | ask |
| 所有检查干净 | 交给下游 |
网络失败,failClosed: false | fail-open,记录降级信息后交给下游 |
网络失败,failClosed: true | ask |
命中 allowPackages | 跳过所有检查并交给下游 |
一条命令安装多个包时会去重并行审计,最终采用最严格结果:deny > ask > allow。
支持 npm install、npm i、npm add,以及 env、sudo、command、环境变量前缀、npm 可执行文件绝对路径、&& / ; / || 复合命令、引号与反斜杠转义。registry alias(例如 alias@npm:real-package@2)会审计真实包;本地路径、tarball URL 和 git spec 会被忽略。
插件不需要 API key,也不会读取或上传源码。
每次审计可能向以下公共服务发送最少信息:
| 服务 | 发送内容 | 用途 |
|---|---|---|
| npm registry | 包名 | 解析版本、许可证和健康度元数据 |
| OSV.dev | 包名、确切版本、npm ecosystem | 查询公开漏洞 |
| Bundlephobia | 包名、确切版本 | 查询 bundle 体积与 tree-shaking 元数据 |
| npm downloads API | 包名 | 查询最近一周下载量 |
缓存只存在当前插件进程的内存中,不写磁盘:漏洞结果 TTL 为 24 小时,registry、体积和下载量元数据 TTL 为 7 天。TTL 到期且网络不可用时,插件会明确标记使用了过期值;默认 fail-open,failClosed: true 时要求人工确认。
bash 工具中的 npm 安装请求;终端外部执行、其他工具名、pnpm 和 Yarn 目前不在拦截范围。npm install 与 npm ci 不扫描 lockfile;如需审计声明依赖,请让 agent 调用 dep_check。ask 需要人判断。仓库提供确定性的演示脚本,它调用真实的插件 apply() 和 tools/pre-execute handler,但用固定 fixture 代替公共网络,不会真的安装包:
npm run build
node demo/interception.mjs
输出展示 npm install lodash@4.17.20 在执行前因 HIGH 漏洞被 deny。
生成终端 GIF 需要 VHS:
./demo/record.sh
脚本会生成 demo/interception.gif。仓库不会用手工拼接或伪造的图片代替真实录制;没有 VHS 时,脚本会退出并打印安装与重试说明。
npm ci
npm run typecheck
npm test
npm run build
npm pack --dry-run
npm run typecheck:严格 TypeScript 检查,不输出文件。npm test:运行 Vitest 测试。npm run build:清理并生成 lib/、声明文件和 source map。npm run check:依次执行 typecheck、test、build。npm pack / npm publish 会先运行 prepack,因此发布前自动执行完整检查。dsh-install-guard is a DeepSeek Harness (DSH) bundle that listens to tools/pre-execute:
bash tool.allow, ask, or deny. An ask decision enters Harness's native approval flow before the command executes.The plugin also registers a read-only dep_check tool so an agent can compare candidate packages or explicitly audit a workspace package.json.
Requirements:
^22.19.0 || >=24.0.0>=0.1.0-rc.7 <0.2.0Install the bundle into a DSH profile (web in this example):
dsh plugin --profile web add dsh-install-guard
dsh --profile web --dump-config
dsh --profile web
The package declares dsh.bundle, so installation automatically adds the bundle to the profile. Do not manually insert the same plugin as well; doing so can create a duplicate loader id.
Remove it with:
dsh plugin --profile web remove dsh-install-guard
To build and install a local tarball:
npm ci
npm pack
dsh plugin --profile web add ./dsh-install-guard-0.1.0.tgz
The bundle inserts the stable row id install-guard. Override it in the profile's cordis.patch.yml (normally $DSH_HOME/profiles/web/cordis.patch.yml, or ~/.dsh/profiles/web/cordis.patch.yml when DSH_HOME is unset):
- id: install-guard
config:
denySeverity: high
askSeverity: unknown
blockedLicenses:
- GPL
- AGPL
allowPackages:
- '@your-company/*'
maxBundleSizeKb: 20
minWeeklyDownloads: 100
minPackageAgeDays: 30
typosquatMaxDistance: 1
failClosed: false
A later DSH patch replaces the row's entire config value rather than deep-merging it, so listing every setting as above is recommended.
| Setting | Default | Meaning |
|---|---|---|
denySeverity | high | Deny at or above this vulnerability severity. Values: critical, high, medium, low, unknown. |
askSeverity | unknown | Ask for human approval at or above this vulnerability severity. |
blockedLicenses | ["GPL", "AGPL"] | License denylist; SPDX names and family prefixes are supported. |
allowPackages | [] | Package names that bypass the complete audit; supports exact names and @scope/*. |
maxBundleSizeKb | 20 | Maximum gzip size in decimal KB for packages that are not tree-shakeable. |
minWeeklyDownloads | 100 | Minimum weekly downloads used by health heuristics. |
minPackageAgeDays | 30 | Minimum age used by the young-and-unpopular heuristic. |
typosquatMaxDistance | 1 | Maximum Damerau–Levenshtein distance from the built-in popular-package list. |
failClosed | false | Ask when a network check fails or only expired cache data is available. |
deny always wins over ask when thresholds overlap. An allowlisted package skips all four dimensions; use the allowlist sparingly.
registry.npmjs.org and api.osv.dev.latest, other dist-tags, exact versions, and semver ranges before querying the OSV npm ecosystem with the exact version.license value in the full npm registry packument.AND, OR, and WITH expressions. MIT OR GPL-3.0-only is allowed by the default policy; a license is blocked only when every OR branch contains a blocked term.bundlephobia.com/api/size.hasJSModule and hasSideEffects.api.npmjs.org/downloads.dep_checkCompare package candidates:
{
"packages": ["moment@^2", "dayjs@latest"]
}
Explicitly audit workspace dependencies:
{
"includePackageJson": true,
"packageJsonPath": "package.json"
}
packages and includePackageJson may be combined. The tool:
dependencies, devDependencies, optionalDependencies, and peerDependencies;file:, git, URL, and other non-registry specs with an explicit reason;.. and symlink escapes;axios, chalk, lodash, moment, request, and uuid.Output is stable schemaVersion: 1 JSON with allow/ask/deny, degraded, and skipped counts. The tool never scans package.json implicitly; includePackageJson: true is required.
| Input or result | Default behavior |
|---|---|
Non-bash tool or non-install command | Continue downstream |
Argument-free npm install or npm ci | Continue downstream (existing lockfile install) |
Registry package in npm install/i/add | Resolve and audit |
| HIGH / CRITICAL vulnerability | deny |
| MEDIUM / LOW / UNKNOWN vulnerability | ask |
| Blocked or missing license | ask |
| Oversized gzip, not known to tree-shake safely | ask |
| Oversized gzip, tree-shakeable | Report without blocking |
| Health heuristic finding | ask |
| All checks clean | Continue downstream |
Network failure with failClosed: false | Fail open, log degradation, continue |
Network failure with failClosed: true | ask |
Package matches allowPackages | Skip every check and continue |
For a multi-package command, requests are deduplicated and audited concurrently. The strongest aggregate result wins: deny > ask > allow.
The parser supports npm install, npm i, and npm add; env, sudo, and command wrappers; environment assignments; absolute npm executable paths; &&, ;, and || compound commands; quoting; and backslash escapes. Registry aliases such as alias@npm:real-package@2 audit the real package. Local paths, tarball URLs, and git specs are ignored.
No API key is required. The plugin does not read or upload source code.
Each audit may send the minimum package metadata to these public services:
| Service | Data sent | Purpose |
|---|---|---|
| npm registry | Package name | Resolve versions, licenses, and health metadata |
| OSV.dev | Package name, exact version, npm ecosystem | Query public vulnerabilities |
| Bundlephobia | Package name and exact version | Query bundle size and tree-shaking metadata |
| npm downloads API | Package name | Query last-week downloads |
The cache is process memory only and never writes to disk. Vulnerability results have a 24-hour TTL; registry, size, and download metadata have a 7-day TTL. If data expires while offline, stale reuse is explicitly reported. The default is fail-open; failClosed: true asks for approval instead.
bash tool are intercepted. External terminals, other tool names, pnpm, and Yarn are currently outside the guard.npm install and npm ci do not scan a lockfile. Ask the agent to call dep_check to audit declared dependencies.ask decision needs human judgment.The repository includes a deterministic demo that invokes the real plugin apply() and tools/pre-execute handler while replacing public network calls with fixed fixtures. It does not install a package:
npm run build
node demo/interception.mjs
It shows npm install lodash@4.17.20 being denied before execution because of a HIGH vulnerability.
To generate a real terminal recording, install VHS and run:
./demo/record.sh
The command writes demo/interception.gif. The repository intentionally does not substitute a hand-built or fabricated image when VHS is unavailable; the script prints installation and retry instructions instead.
npm ci
npm run typecheck
npm test
npm run build
npm pack --dry-run
npm run typecheck runs strict TypeScript checking without emitting files.npm test runs the Vitest suite.npm run build recreates lib/, declarations, and source maps.npm run check runs typecheck, tests, and build in sequence.npm pack and npm publish run prepack, so the complete check runs automatically before release.DeepSeek Harness 的 npm 安装前漏洞门禁。插件监听 tools/pre-execute,在 bash
真正执行前解析 npm 安装命令、将版本范围或 dist-tag 解析为 registry 中的确切版本,
再查询 OSV.dev。
当前第一阶段只覆盖漏洞审计:
CRITICAL / HIGH:拒绝安装(deny)MEDIUM / LOW / 无等级漏洞:请求用户确认(ask)next())许可证、体积、健康度、缓存、离线 fail-open、主动 dep_check 工具和发布流程不在
当前阶段范围内。
^22.19.0 或 >=24.0.00.1.0-rc.7 及兼容的 0.1.x 版本npm install
npm run typecheck
npm test
npm run build
本地 bundle 构建后可加入 DSH profile:
npx @deepseek-ai/dsh@0.1.0-rc.7 plugin --profile web add .
npx @deepseek-ai/dsh@0.1.0-rc.7 web
也可以用临时 patch 验证当前 checkout;patch 中的模块路径由 profile 目录解析, 因此需按 DSH 官方加载规则使用可解析的包名或绝对路径。
npm install lodashnpm i -D lodash@^4.17.0 @scope/name@nextnpm add foo bar@1cd packages/app && npm i foo&&、||、; 或换行连接的复合命令无参数 npm install、npm ci、非安装命令、local/file/git/URL 依赖会直接放行。
解析器不会展开 shell 变量、alias、函数或命令替换。
FAQs
Guard DeepSeek Harness npm installs with vulnerability, license, bundle-size, and package-health audits.
We found that dsh-install-guard demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.