@jayyuen66/dsh-danger-guard

securitynpmMIT

Pre-execution guard: a `tools.guard` predicate decides allow, ask or refuse per permission preset for dangerous shell commands (git hook bypass, catastrophic `rm`, download-and-run, git history rewrites) and for edits to credential paths or to files the turn never read, and hands the model the reaso

下载量 / Downloads
505

Install

dsh plugin --profile web add @jayyuen66/dsh-danger-guard

Sandbox test

This plugin has not been tested yet. Submit a test →

README

<p align="center">

<img src="https://cdn.jsdelivr.net/gh/JayYuen666/dsh-danger-guard@main/icon.svg" width="96" height="96" alt="dsh-danger-guard logo" />

</p>

<h1 align="center">dsh-danger-guard</h1>

<p align="center"><em>Dangerous shell commands and credential edits, physically refused before dispatch.</em></p>

<p align="center">

<a href="https://www.npmjs.com/package/@jayyuen66/dsh-danger-guard"><img src="https://img.shields.io/npm/v/@jayyuen66/dsh-danger-guard?style=flat-square&logo=npm&logoColor=white" alt="npm version" /></a>

<a href="https://www.npmjs.com/package/@jayyuen66/dsh-danger-guard"><img src="https://img.shields.io/npm/d18m/@jayyuen66/dsh-danger-guard?style=flat-square" alt="npm downloads (18 months)" /></a>

<a href="https://github.com/JayYuen666/dsh-danger-guard/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/JayYuen666/dsh-danger-guard/ci.yml?branch=main&style=flat-square&label=ci" alt="ci" /></a>

<img src="https://img.shields.io/badge/license-MIT-4c1?style=flat-square" alt="MIT" />

<img src="https://img.shields.io/badge/node-%3E%3D24.9-4c1?style=flat-square&logo=nodedotjs&logoColor=white" alt="node" />

<img src="https://img.shields.io/badge/dsh-%5E0.2.1--rc.5-658EFF?style=flat-square" alt="dsh" />

<a href="https://github.com/deepseek-ai/deepseek-harness"><img src="https://img.shields.io/badge/powered_by_dsh-4D6BFE?style=flat-square&logo=deepseek&logoColor=white" alt="powered by dsh" /></a>

</p>

<p align="center">

<img src="https://skillicons.dev/icons?i=typescript,nodejs,react,vitest,githubactions" alt="tech stack" />

</p>

<p align="center">

<a href="https://github.com/JayYuen666"><img src="https://img.shields.io/badge/GitHub-JayYuen666-181717?style=flat-square&logo=github&logoColor=white" alt="GitHub" /></a>

<a href="mailto:cqwkkj@gmail.com"><img src="https://img.shields.io/badge/Email-cqwkkj@gmail.com-EA4335?style=flat-square&logo=gmail&logoColor=white" alt="Email" /></a>

<a href="https://twitter.com/JayYuen666"><img src="https://img.shields.io/badge/Twitter-X%2FJayYuen666-000000?style=flat-square&logo=x&logoColor=white" alt="Twitter/X" /></a>

<a href="./README.zh-CN.md"><img src="https://img.shields.io/badge/lang-简体中文-658EFF?style=flat-square" alt="简体中文" /></a>

</p>

A pre-execution guard for dsh: dangerous shell commands and credential edits are physically refused before dispatch, and the model is handed the reason plus a working way out.

<img src="https://api.iconify.design/lucide/file-text.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> Contents

  • [What it does](#what-it-does)
  • [Install](#install)
  • [Verify it is live](#verify-it-is-live)
  • [What it does not provide](#what-it-does-not-provide)
  • [Enabling it in dsh](#enabling-it-in-dsh)
  • [What the rules block](#what-the-rules-block)
  • [Settings](#settings)
  • [What each permission preset blocks](#what-each-permission-preset-blocks)
  • [Known boundaries](#known-boundaries)
  • [Data and privacy](#data-and-privacy)
  • [FAQ](#faq)
  • [Development](#development)
  • [License](#license)

<img src="https://api.iconify.design/lucide/shield.svg?color=%23658EFF&height=22" height="22" width="22" align="absmiddle" alt="" /> What it does

  • It blocks, it does not advise. The decision lives in the synchronous predicate on ctx.tools.guard: returning a string rejects that call. The host turns the reason into the call's error result, so the model reads "why this was refused, and what to write instead" - not a silent failure.
  • Three defences:
  • Dangerous bash / pwsh commands (bashVerdictOf in lib/danger-rules.ts): git hook bypass, catastrophic rm, download-and-run, long-running dev servers, the git destruction family, and the infrastructure destruction family.
  • Credential and secret paths on edit/write/apply_patch tools (secretPathDeny) - matched by argument key shape for single-target editors, and by the official patch parser for apply_patch, never by tool name, because tool names drift with the provider.
  • The editor path face has a second refusal key, opaqueTarget: a target longer than the judgable length limit is neither confirmed nor cleared as a credential, so it is denied with a "paste the path to the user, do not retry verbatim" message. Same principle as nestedShellUnconfirmed on the bash side - cannot judge is not the same as safe. (An over-long command resolves to nestedShellUnconfirmed instead.)
  • The first-edit fact gate (lib/fact-gate.ts): an edit that has not read its target, or that touches a risky surface without layer evidence, gets refused with the missing evidence attached. apply_patch is judged per operation target (a move counts both its source and its destination); an empty patch, one the official parser rejects, or one over APPLY_PATCH_TARGET_LIMIT (128) is refused outright instead of partially applied, and that refusal does not depend on factGateEnabled.
  • "Has read" counts successful calls only: the evidence ledger joins tool/call to tool/result by callId, and a call without one has unknown status and does not count (the host appends the call before dispatching, so a call that never ran or already failed looks exactly like a successful one in the log).
  • "Which revision was read" lives in lib/read-basis.ts: the observation baseline and the staleness point are one record, and it is committed only after a successful result - a failed or blocked read cannot advance the baseline and thereby swallow an external change. Once an external change is attributed it stays in force until a successful read actually lands (or the preflight hands the body over in a deny reason).
  • Preflight gathers that evidence itself (two faces on two waterfalls, split by when evidence actually becomes visible):
  • Face A, on tools/post-execute: a read-only inspection (`rea

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::17,最后更新 2026-11-05

Links

GitHub · Homepage · npm

Same category