Skip to main content

dsh-security-audit

13Stars0Forks0Issues0Watchers

DSH Read-Only Security Audit Plugin: Scans four dimensions—configuration, plugins, sessions, and network—generating desensitized, reproducible, and locatable risk reports. The plugin does not fix issues, connect to external networks, or execute audited plugins.

Evidence5/5methodologySourceInstallMaintenanceDSH versionSecurity scan
Machine-auditedInstall commandRepo verifieddsh-plugin topicLicenseREADMEAI wiki
Language
TypeScript
License
MIT
Branch
main
auditdshdsh-pluginsecret-scanningsecurity

Install

cmdweb profile
$ dsh plugin --profile web add github:omdsh-dev/dsh-security-audit

Run the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial

Install via your agent

Install the DeepSeek Harness plugin omdsh-dev/dsh-security-audit for me: review the repository at https://github.com/omdsh-dev/dsh-security-audit first, then run the install command and verify the plugin loads successfully.

Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.

One-Line Positioning

DSH Native Security Audit Tool — scans your local DSH environment across four dimensions (configuration, installed plugins, session files, network configuration) in read-only mode, outputs structured risk reports with redacted information, does not auto-fix, does not perform network probing, does not execute audited plugins.

Core Capabilities

  • Scans DSH configuration, profile, credential file metadata, detects疑似明文 token/key/私钥、PEM headers, plaintext never enters canonical output, only retains HMAC fingerprint + path + line number
  • Audits installed plugins' sources, load paths, cordis.patch.yml lines, install scripts, sensitive files like .env/.pem/.key, and optional static scanning of plugin source code for dangerous capabilities (eval/child_process/network capabilities)
  • Checks session directory and file permissions, symlink/reparse escape, session zstd frame structure (truncated by frame budget to defend against decompression bombs)
  • Checks listen configuration, external HTTP plaintext endpoints, proxy and credential routing, model discovery targets — all only do configuration-level classification, no active connection or probing
  • The aggregated report action merges four scan categories, outputs dual-dimension verdict: risk dimension (fail/warning/pass) + coverage dimension (complete/incomplete), and marks whether truncated due to budget
  • Provides rules action to real-time list 33 rules' code / severity / criticality / applicable platform

Technical Implementation

  • Language: TypeScript (ESM, strict)
  • Key Dependencies: @deepseek-ai/dsh-tools (defineTool registration); @deepseek-ai/cordis (Cordis container, inject: ['tools']); @deepseek-ai/dsh-invariants (package-owned invariant companion)
  • Architecture Pattern: Single Cordis plugin registers a tool named security_audit, exposes a multi-action entry via ctx.tools.register(defineTool({...})), output schema is JSON string; injects security-audit row into host layer stack via cordis.patch.yml
  • Entry File: src/index.ts (apply / SecurityAuditConfig), cordis patch cordis.patch.yml, executable compiled entry lib/index.js

Use Cases

When you want to verify "what is the attack surface of my local DSH" after lending your machine to someone, or after installing a batch of new plugins — for example, whether DSH is listening on public network, whether API key ended up in .env instead of credential store, whether the plugin you just installed has install scripts or suspicious capabilities — you can run report once to get dual-dimension verdict and a locatable finding list.

Prerequisites and Compatibility

DependencyMinimum VersionDescription
DeepSeek Harness (DSH)0.1.0-rc.8 (verified in README)README.md:86-94 completes type/runtime/tool registration three-stage verification in rc.8 isolated consumer
Cordis (host)^4.0.1package.json peerDependencies, provided by DSH host
@deepseek-ai/dsh-tools>=0.0.1-rc.1 <0.2.0Provides defineTool registration API
@deepseek-ai/dsh-invariants>=0.0.1-rc.1 <0.2.0package-owned invariant companion
Node.js^22.19.0 or >=24.0.0package.json#engines mandatory declaration
PlatformmacOS / Linux / WindowsCross-platform pure Node script, only uses node:fs / node:os / node:path / node:crypto; permission rules skip on Windows
Native ModulesNoneOnly depends on Node built-in modules, no native binding

Installation

dsh plugin --profile web add github:omdsh-dev/dsh-security-audit

Configuration Options

This plugin has no user-facing runtime configuration — all visible parameters are security_audit tool call inputs (action / profile / strict / detail / includeSourceScan / root), passed by the caller as needed for each action, no pre-declaration required.

Only administrator-declared "host layer" options (written in the corresponding profile's cordis.patch.yml, passed as plugin initialization inputs, cannot be modified by normal model calls):

ConfigTypeDescriptionDefault
allowedRootsstring[]Additional scannable root paths declarable only by administrators; model parameter root must equal $DSH_HOME or one of the paths listed here, cannot use this field to expand read scopeUndeclared = empty, only $DSH_HOME
allowedEndpointsstring[]Administrator-declared endpoint exact whitelist (normalized scheme+host+port, no wildcard/path/userinfo)Undeclared = empty, all go to default risk rules

Normal users don't need to write these; they are only used when administrators intentionally want audit to cover multiple root directories or multi-endpoint environments. See src/index.ts:29-42 / src/types.ts:136-156 for details.

FAQ

Q: Will plaintext keys appear in the output report?

A: No. Redactor uses an in-process random 32-byte HMAC key to convert each suspected secret into a hexadecimal fingerprint; the original value is only used for fingerprint calculation, not written to canonical output, and does not appear in error messages or logs (src/redact.ts:83-115); moreover, all secret evidence is forced to carry redacted: true as a protocol field (not a truncation hint). Even if root covers a file containing plaintext, the report will only show "file/line number/type/length/fingerprint".

Q: Will the report modify any local files?

A: No. The design guarantees read-only from the ground up: all paths go through lstat (reject symlink/reparse) → realpath → containment check, root is fixed to $DSH_HOME resolved at process startup, model parameters cannot expand the read scope; the plugin itself does not execute child_process, does not touch ACLs, does not install any dependencies. Source capability scanning is also pure static regex matching — you can verify by running strings lib/index.js | grep chmod.

Q: Why doesn't scan_network do actual port probing?

A: This is an intentional design boundary. scan_network only parses listen / URL / proxy fields in local configuration and classifies them according to spec (loopback / unspecified / private / external), returns unknown-listener-state info finding when unable to determine; it never actively probes or connects to remote targets, so the audit itself does not generate real network traffic, nor will it be misidentified by local IDS.

Q: Can it run on Windows? What differences are there?

A: Yes — the plugin main program is pure Node scripts. But permission rules (credential-file-permissions / session-root-permissions / session-file-permissions) have no zero-side-effect ACL APIs on Win32, so they return skipped(skipReason=platform), not counted as pass; report coverageVerdict will be judged incomplete. This is the "honest judgment" design: better to mark incomplete than to pretend security (src/platform/windows.ts:7-16 / src/runner.ts:138-150).

Q: What does includeSourceScan do? Should I enable it?

A: When enabled, it additionally performs source code regex scanning on each installed plugin (depth 3, skipping node_modules/.git) to match high-risk capability strings like eval / new Function / vm / child_process / spawn / fork / Worker / net|http|https|dgram / fetch / WebSocket. Capability hits never adjudicate malicious, they only state in findings "capability present, intended use requires manual confirmation" — you or your team need to confirm the intent. Therefore it's slower with more false positives; README marks it as optional, default off; recommend enabling only when "just installed an unfamiliar plugin and want to triangulate source credibility".

Q: Is it bad news when report coverageVerdict shows incomplete?

A: It doesn't necessarily mean missed detection. It represents that critical rules could not give conclusions due to skipped (platform unsupported or insufficient permissions) or scanner error — Windows permission rules are a typical trigger. summarize separately counts skipped / errors, combine with checks list to see specific rule names and skipReasons, then decide whether to accept current coverage, run with elevated privileges, or only merge in-domain sub-scan reports.

Q: Should I enable strict mode?

A: For personal self-check, keep default (false) to avoid medium findings alone triggering fail; enable strict in pre-production or CI gate scenarios to treat medium same as high. Prioritize fixing found issues rather than repeatedly re-running — the auditor only diagnoses, does not fix, and does not replace permission boundary and key management specifications.

Q: How to uninstall or downgrade?

A: Use dsh plugin remove security-audit for the corresponding profile; there is no global state in tool call inputs, no daemon, no side effects outside $DSH_HOME; after removal, history only exists in JSON reports you saved. It is v0.0.1, no schema preserved across versions — upgrading just means dsh plugin add to overwrite.

Learning Curve

Advanced — single command to install and directly call report action, but to understand the 33 rules' code/exposure/recommendation from coverageVerdict: incomplete / verdict: fail JSON and fix configurations or swap plugins accordingly requires familiarity with DSH's ~/.dsh directory layout and profile layer stack.

Known Issues and Limitations

  • Permission rules always return skipped on Windows (src/platform/windows.ts:7-16); coverageVerdict must be incomplete, need independent interpretation in riskVerdict and rule list dimensions
  • Report capacity has hard limits: single action 10s, report 30s; files ≤ 200, plugins ≤ 200, sessions ≤ 1,000, findings ≤ 1,000; canonical output ≤ 2 MiB; exceeding limits sets truncated:true (src/limits.ts:6-43)
  • Source capability scanning depth only 3 layers, single file ≤ 1 MiB, cumulative ≤ 64 MiB, only matches .ts/.js/.mjs/.cjs/.tsx/.jsx; intentionally does not parse AST, no deobfuscation (src/plugins/source-capabilities.ts:20-24, 89-93)
  • All path operations reject symlink / reparse point; as long as your profile's link field points to a soft link, audit sees not "soft link" but "out-of-root" alert (src/paths.ts:80-95)
  • zstd scanning uses self-implemented frame parser to parse header and block header, does not expand block data; so it won't trigger decompression bombs, but also won't give judgment on "whether decompressed content is healthy" (src/sessions/zstd-scan.ts:1-6, 45-50)
  • scan_network will never give real listening state — 0.0.0.0 config doesn't mean process is really listening, undeclared config doesn't mean it's not listening; this is intentional boundary, explicitly marked unknown-listener-state
  • Among 31+ different secret patterns, rule dsh_test_not_a_real_secret_* uses allowlist (src/redact.ts:28-30); other obviously invalid test tokens will also be reported as real secrets — when self-deploying, remember to change tokens in fixtures to this prefix, or add to your own allowlist
  • Admin-injected allowedRoots / allowedEndpoints use exact matching (no wildcard/path/userinfo), entries with these elements are silently considered invalid, never match (src/network/classify.ts:84-96)

Read the usage guide →

Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.

Listing badge

Listed on deepseek-plugin.org
[![Listed on deepseek-plugin.org](https://img.shields.io/badge/listed_on-deepseek--plugin.org-007EC6)](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-security-audit)

Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.

← Back to plugin directory