dsh-secrets
A DeepSeek Harness plugin that lets the agent ask you for API keys, passwords, and tokens through a secure form, without the values ever reaching the model.
How it works
- The agent calls
request_secretwith the variable names, a purpose, and a dotenv file. - A password form appears in that tool row in the conversation.
- You type the values. They travel over an authenticated
/api/dsh-secrets.*route straight to the Host. They are never a tool argument, a tool result, or a session event. - The values are written to the dotenv file with mode
0600. Existing lines, comments, and line endings are kept. - The agent receives only
{ status, path, names, added, updated, unchanged, kept }.
The bundled secrets skill teaches the agent when and how to call the tool.
Defences
| Layer | Mechanism | What it does |
|---|---|---|
| L1 read guard | ctx.tools.guard() |
Denies read/edit/write/grep, and shell commands that read a managed file (cat, cp, source, python -c open(...), …). Other plugins cannot override the denial. |
| L2 redaction | tools/post-execute |
Replaces managed values in every tool result with [REDACTED:NAME], including base64 (all alignments, e.g. inside Basic auth), URL encoding, JSON escaping, and hex. If redaction fails, the output is withheld. |
| L3 approval | tools/pre-execute → ask |
A shell command that uses a managed variable together with curl, echo, printenv, ssh, … asks you first. |
| No values in logs | Separate fetch route | The session log records only names, path, and counts. registry.json stores names, paths, and an 8-char fingerprint. |
Other rules:
env_filemust be inside the working directory.- Subagents and
run_code(PTC) programs cannot open the form. - After you cancel, the same names cannot be requested again in that turn.
Settings → Secrets lists the managed variables. You can stop managing one, or delete it from its file. The page does not show values.
Known limits
- An agent that writes its own program to read the file and transform the value arbitrarily before sending it can get past L1–L3. Use it in workspaces you trust. These defences raise the bar; they are not a sandbox.
- Values shorter than 6 characters cannot be redacted. The settings page flags them.
- Approval (L3) is per command. There is no "always allow for this session" button yet.
- Only dotenv files are supported (no Keychain, no environment injection).
Install
Requires DeepSeek Harness 0.2.x and Node 22 or later.
From inside a Harness session, ask the agent to install the bundle:
plugin_manager install_bundle target: https://github.com/SiyuQian/dsh-secrets.git
Or clone the repo and install from the local directory:
git clone https://github.com/SiyuQian/dsh-secrets.git
# then in Harness: plugin_manager install_bundle target: /absolute/path/to/dsh-secrets
Refresh the Web GUI after installing.
Configuration
Optional. Set these in your profile cordis.patch.yml:
- id: dsh-secrets
name: dsh-secrets
config:
timeoutMs: 600000 # form timeout, default 10 min
dataDir: /abs/path # registry location, default $DSH_HOME/plugins/dsh-secrets
allowOutsideCwd: false # allow env_file outside the working directory
Development
npm test # node:test, no dependencies
| File | Contents |
|---|---|
lib/index.js |
Host: tool, routes, guard, hooks, skill provider |
lib/dotenv.js |
Dotenv reconcile, parse, and remove |
lib/redactor.js |
Value-variant redaction |
lib/policy.js |
L1 and L3 rules |
lib/store.js |
Atomic 0600 writes with sha256 conflict retry, and the registry |
client/client.js |
Form toolview and settings page (plain JS, no build step) |
docs/api-findings.md |
The Harness APIs this plugin relies on, with sources |
License
MIT
中文说明
Agent 需要 API key、密码或 token 时,调用 request_secret,对话里会弹出一个密码表单。
- 你填写的值直接写入工作目录里的 dotenv 文件,权限 0600。
- 这些值不会进入模型上下文,也不会写进会话记录。
- Agent 只拿到文件路径、变量名和数量。
插件在 skill 约束之外,还加了三道防线:
- L1 读取拦截:读取这些文件的工具调用一律拒绝。
- L2 输出脱敏:任何工具输出里出现的值(包括它的常见编码形式)都会被替换掉。
- L3 外发确认:命令同时用到 secret 和
curl、echo这类命令时,要先经过你的确认。
已知限制:如果 agent 自己写程序,读出值并做任意变换后再外发,这些防线无法完全拦住。请只在可信的工作区中使用。
No comments yet. Be the first to write one.