DeepSeek Harness plugin

dsh-secret-paste

DeepSeek Harness plugin: auto-detect secrets pasted into the composer, store them in the official credentials seam, and send [secret:REF] placeholders to the model instead of the value.

Jump to install

Source facts

Repository
zhujiaqi/dsh-secret-paste
Latest update
Aug 20, 2026
Category
Plugin Markets & Managers
GitHub stars
2
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/zhujiaqi/dsh-secret-paste
Plugin: dsh-secret-paste
Author: zhujiaqi

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer4 files
README.mdSource · read only
README language

dsh-secret-paste

> A DeepSeek Harness plugin that detects secrets pasted into the composer, stores > them in the official credentials seam, and sends a [secret:REF] placeholder to > the model instead of the plaintext. The real value never reaches the message, > the session history, or any transcript.

<div align="center">

![npm](https://www.npmjs.com/package/dsh-secret-paste) ![MIT](LICENSE) ![DSH](cordis.patch.yml)

🌐 中文:README.zh.mdEnglish

</div>

Why

You paste an API key or a token into the chat. Without protection it goes straight to the model and into the session log — which is exactly where a secret should never land. This plugin intercepts the paste, stores the value in the official DSH credential seam (~/.dsh/.credentials.yaml, mode 0600), and replaces it in the draft with [secret:REF]. The model only ever sees the placeholder, and can read the real value on demand through a dedicated tool.

How it works

StepWhat happens
Detect@sanity-labs/secret-scan (1,100+ rules derived from gitleaks / TruffleHog) runs on the pasted text.
StoreThe value is written with the official credentials.set Web API — no new server route.
ReplaceThe matched range becomes [secret:PASTE_N] in the draft.
ResolveThe model calls the secret_resolve(ref) tool when it actually needs the value.

The plaintext value lives in exactly two places: (1) this tab's memory, and (2) ~/.dsh/.credentials.yaml (mode 0600). Every other surface — the sent message, session history, transcripts — sees only [secret:REF].

Installation

Prerequisites

  • A DeepSeek Harness Web profile (the examples use web).
  • The dsh CLI and pnpm on your PATH (dsh plugin is a thin pnpm forwarder).

Install from the npm registry (recommended)

dsh plugin --profile web add dsh-secret-paste

What this command does:

1. Runs pnpm add dsh-secret-paste inside the profile directory. 2. Installs the single runtime dependency (@sanity-labs/secret-scan). 3. Because the package declares dsh.bundle.patch, it is auto-registered in dsh.profile.bundles as a profile layer.

No build step runs on install — the browser bundle is prebuilt and shipped.

Restart

The server half (the secret_resolve tool) loads at boot, so restart the dsh web process after installing, then force-refresh the browser tab (Cmd+Shift+R / Ctrl+Shift+R) to load the client bundle:

# restart the dsh web process you manage (Ctrl-C + relaunch, or your process manager)

Verify

  • Settings → Plugins lists dsh-secret-paste.
  • Paste a GitHub token (ghp_...) into the composer: it is immediately replaced

by [secret:PASTE_N] and a chip appears.

Installing from an agent or in automation

The exact same steps work when an AI agent or a CI job installs the plugin:

1. dsh plugin --profile web add dsh-secret-paste 2. Restart dsh web (required for the secret_resolve tool to register). 3. Force-refresh the browser tab. 4. Verify: paste ghp_... and expect [secret:PASTE_N], or confirm the served page's window.__DSH_BOOT__ contains a dsh-secret-paste entry.

Usage

Auto-detect and hide

Paste text that contains a high-confidence secret (ghp_..., sk-proj-..., JWT, …). It is stored and replaced with [secret:PASTE_N] immediately, and a chip shows:

> 🔒 Hidden · <rule> · PASTE_N · Undo

  • Hover the chip to reveal the value in a tooltip — no layout shift.
  • Undo restores the plaintext while you are still drafting.
  • After you send, the chip stays visible but the undo button disappears; once

the answer arrives, the chip is removed.

Medium confidence

confidence === 'medium' hits (e.g. a Bearer <token>) stay in the draft as-is and a "Suspected secret" chip asks you to confirm (Hide) or ignore (Ignore).

Manual marking

Formats the detector does not recognize (ark-..., some sk-...) are never guessed. Select the text and use the "Mark selection as secret" action, then "Hide & store".

Nested placeholders

A selection that already contains [secret:REF] can be wrapped again. The secret_resolve tool resolves such chains recursively down to plaintext (cycles or missing inner refs return found: false).

Model side: secret_resolve

When the model needs the real value, it calls the secret_resolve(ref) tool:

  • Returns { found, value, source }.
  • Resolves nested placeholders recursively to plaintext.
  • The value is SENSITIVE: the tool description instructs the model never to

echo, repeat, or write it into a reply, a file, a command, or a tool argument.

Security model

  • Values never leak: only [secret:REF] appears in the message, history, or

transcripts. Values exist only in tab memory and the 0600 credential file.

  • Detection is conservative: high auto-hides, medium waits for a confirm,

and unknown formats are never guessed (manual marking is the fallback).

  • Collision-safe refs: if a ref is already configured, the next free ref is

used instead of overwriting; the same value is stored once per session.

  • No reveal endpoint: the credential seam reads value-free with no

enumeration; after a refresh the in-memory value is gone and chips do not persist.

  • Use-time visibility (v1): secret_resolve brings the value into model

context only when the model asks for it.

Development

node scripts/build.mjs   # rebuild lib/client.js (no external bundler)
npm test                 # node --test tests/*.test.mjs

Structure

dsh-secret-paste/
├── package.json           # dsh.bundle.patch + dsh.client declarations
├── cordis.patch.yml       # mounts the server row
├── lib/
│   ├── index.js           # server: secret_resolve tool (recursive resolution)
│   └── client.js          # prebuilt browser bundle
├── src/
│   ├── resolve.js         # nested-placeholder resolver (shared with server)
│   ├── scan.js            # detection helpers (shared with tests)
│   └── client/index.js    # paste interception, chips, credentials.set
├── vendor/secret-scan.cjs # vendored @sanity-labs/secret-scan@1.1.0 (MIT)
├── scripts/build.mjs      # assembles lib/client.js
└── tests/                 # node:test unit tests

License

MIT. vendor/secret-scan.cjs is the compiled dist/index.cjs of @sanity-labs/secret-scan v1.1.0 (MIT), whose rules derive from gitleaks (MIT) and TruffleHog detectors; its license is preserved at vendor/secret-scan.LICENSE.