zhujiaqi/dsh-secret-paste
DeepSeek Harness plugin: detect pasted secrets, store them in the credentials seam, and send [secret:REF] placeholders to the model.
Project Overview项目介绍
dsh-secret-paste is a DSH plugin that scans pasted text for secrets using a 1,100+ rule detector, stores the plaintext in the official 0600-mode credentials seam, and replaces the draft with a [secret:REF] placeholder so models and transcripts never see the raw value; the model retrieves the real value on demand via the secret_resolve tool. Use it when handling API keys, tokens, or JWTs in the Web profile. Note: unknown formats are never guessed—manual marking is required.
dsh-secret-paste 是 DSH 插件,在编辑器粘贴时检测密钥(基于 1100+ 条规则的 secret-scan),通过官方 credentials seam(0600 权限)存储原文,并在草稿中替换为 [secret:REF] 占位符,模型仅在调用 secret_resolve 工具时按需取回。适用于在 Web 配置中粘贴 API key、token、JWT 等场景。注意:高置信度自动隐藏,中等置信度需手动确认,未识别格式不会猜测,必须手动标记。
请帮我了解并安装插件:【dsh-secret-paste】【https://github.com/zhujiaqi/dsh-secret-paste】
Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。
Or use CLI install (for developers)或使用命令行安装(适合开发者)
CLI Install命令行安装
dsh plugin --profile web add dsh-secret-paste
把 zhujiaqi/dsh-secret-paste 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
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.
🌐 中文:README.zh.md | English
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
| Step | What happens |
|---|---|
| Detect | @sanity-labs/secret-scan (1,100+ rules derived from gitleaks / TruffleHog) runs on the pasted text. |
| Store | The value is written with the official credentials.set Web API — no new server route. |
| Replace | The matched range becomes [secret:PASTE_N] in the draft. |
| Resolve | The 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
dshCLI andpnpmon yourPATH(dsh pluginis a thin pnpm forwarder).
Install from the npm registry (recommended)
dsh plugin --profile web add dsh-secret-paste
What this command does:
- Runs
pnpm add dsh-secret-pasteinside the profile directory. - Installs the single runtime dependency (
@sanity-labs/secret-scan). - Because the package declares
dsh.bundle.patch, it is auto-registered indsh.profile.bundlesas 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:
dsh plugin --profile web add dsh-secret-paste- Restart
dsh web(required for thesecret_resolvetool to register). - Force-refresh the browser tab.
- Verify: paste
ghp_...and expect[secret:PASTE_N], or confirm the served page'swindow.__DSH_BOOT__contains adsh-secret-pasteentry.
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 · · 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:
highauto-hides,mediumwaits 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_resolvebrings 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.
Minglink/dsh-infinite-gen-4
toby-bridges/api-relay-audit
howmp/dsh-pentest
SeaOf0/dsh-redteam-model
saya-ch/dsh-mobile
liguobao/ds-harness-remote
zhu1090093659/dsh-trading
PerryLink/dsh-auto-review