Introduction

In the security ecosystem of DeepSeek Harness (DSH), permission control, automatic approval, and semantic classification are usually distributed across different plugins (such as dsh-permission-rules, dsh-auto-mode, etc.). This fragmentation leads to cross-plugin version coupling and inconsistent audit trails.

dsh-perm-gate is a plugin that merges “gate + approval + classifier” into a single package. It solves the above problems through unified audit trails and deterministic decision precedence.

What Is It

This is an independent, determinism-first, fail-closed permission gate designed for DeepSeek Harness.

The plugin is maintained by drscrewdriver. It uses a fixed priority chain to decide every tool call, ensuring that high-risk operations cannot be bypassed.

Core Features

  • Command allowlist / blocklist: Matching based on argv decomposition, supports recursive parsing of sh -c/bash -c, detects pipelines, redirection targets, and recursive/forced deletion instructions.
  • Denial first: Once a deny rule matches, it has higher priority than any allow rule.
  • Session grants: Provides precise (tool, canonical fingerprint) authorization, supports TTL and maxUses. Different targets cannot reuse grants. Sub-agents can inherit grants, but cannot issue them independently.
  • Pure-function rule engine: Supports glob/regex compilation with ReDoS bounds, fails loudly when rules are in an invalid format, and uses source-code hashes for compilation caching.
  • Audit: Every decision is recorded as an {ignorable:true} event with its callId; the model-visible reason is consistent with the recorded result.
  • Automated review tier: Includes permissive and permissive-full modes. This is an independent approval mode (between read-only and full access); the frontend displays only one toggle, while backend policies can be composed. The permissive-full variant removes the built-in file sandbox.
  • Sandbox escalation auto-response: When a sandbox escalation request is issued from inside the shell, the plugin automatically responds. In this case, the gate plugin itself does not see the call, but records the associated callId.
  • Tiered-risk llmAssist: Uses an OpenAI-compatible LLM to rate ask decisions. High-risk categories (deletion, credentials, remote, system, bulk) always ask, while neutral categories enter adjudication learning.
  • Adjudication learning: Neutral-risk operations that are manually approved and actually executed will be automatically allowed after reaching a threshold, provided they are exactly identical operations (fingerprint match).
  • Decision event stream: Each decision is appended to a JSONL stream. The browser displays it as a notification bar, and in the conversation view’s “Approval Records” tab, entries are shown in reverse chronological order.

Decision Flow

The plugin adjudicates tool calls in priority order:

Stage Decision Description
P0 deny Deterministic hard deny: credential material, protected path changes, dangerous shell
P1 allow Precise, bounded session grants
P2 deny/allow/ask Static rule chain: blocklist first, then allowlist, then ask
P3 allow/deny/ask Optional LLM semantic classifier (disabled by default)
P4 ask Official approval interface

Key point: Strict fail-closed. P0 decisions cannot be overridden by any subsequent step (grants, rules, classifier, or manual review).

Installation and Enablement

First ensure DeepSeek Harness is installed in your environment.

dsh plugin --profile web add dsh-perm-gate

After installation, add the plugin configuration to cordis.yml:

- id: dsh-perm-gate
  name: dsh-perm-gate
  config:
    rulesFile: ./permissions.yaml   # 可选,默认为 $DSH_HOME/perm-gate/rules.yml
    dshHome: $DSH_HOME              # 受保护目标检查的根目录
    defaultAction: ask              # allow | ask | deny
    gatePresets: [permissive, permissive-full]   # 启用自动审查的层级
    sessionSweep: true              # 每小时清理归档/失效会话的授权数据

Typical Usage

The plugin ships with a preset deny keyword blocklist (inherited from dsh-approval-gate), including rm -rf, push --force, drop table, mkfs, git reset --hard, docker system prune, and so on.

These keywords match call text case-insensitively and take effect before allowlists, grants, and LLM decisions. You can edit this list directly in the settings card. Preset entries are marked, and clicking “Restore preset” restores them in one click.

Compatibility and Notes

  • DSH version compatibility: Supports DSH 1.x (legacy branch), 2.x (main branch), and 5.x (0.2.0 line).
  • Language pack limitations: v2.0.0 includes ja/ko dictionaries, but the official DSH LocaleRuntime exposes only zh / en (LOCALE_IDS = ["zh", "en"]). Directly selecting ja/ko on official DSH will raise the error locale "<id>" is not registered. If Japanese or Korean is required, you need to fork DSH, update the LOCALES label in locale-settings.ts and client/index.ts, and then rebuild.
  • Sandbox escalation: Sandbox escalation auto-response runs inside the shell. The gate plugin cannot directly observe this operation, but it records the callId for traceability.
  • File sandbox removal: The permissive-full variant removes the built-in file sandbox, allowing operations that require named pipes, such as git clone, Cygwin, or ConPTY, to pass through.

Conclusion

dsh-perm-gate provides a unified permission-gate mechanism, covering the full range of requirements from security to efficiency, from hard denials to semantic analysis to learned automatic approval. It does not rely on complex cross-plugin version management, making it suitable for development scenarios that require fine-grained control and auditable traceability.