纯 JavaScript 实现的 macOS Keychain 凭据提供器,替换 DeepSeek Harness 的明文 .credentials.yaml 存储,完整支持 refs 和 records,无需原生构建、代码签名或 Xcode。
安装
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:nengong-ai/dsh-keychain-credentials
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
该插件的 README 只有英文版本。
macOS Keychain credentials provider for DeepSeek Harness (dsh).
The stock provider (dsh-credentials-local) stores secrets in $DSH_HOME/.credentials.yaml with 0600 permissions. As its own README states: that file is protected from other OS users, but not from the model — tool processes (bash, filesystem tools) run as the same user and can read it like any other file.
This provider moves secrets into the macOS login keychain. A file that does not exist cannot be cat-ed; nothing lands in backups, sync folders, or git.
What this buys you
- Fixed: the secret is no longer a file. The stock file is reachable by every read primitive the model has —
read,cat,grep,tar,node -e …, in-process or subprocess. With this provider, values live in the login keychain. - Not fixed (be honest): while the login keychain is unlocked (the default once you are logged in), any same-user process can read the item by invoking
/usr/bin/security— the CLI is ACL-trusted and no prompt appears. An agent with an unrestricted shell that knows to ask the keychain can still exfiltrate. Pairing with a sandbox that constrains tool subprocesses narrows this; a hard boundary needs OS-level separation (a signed broker with a private access group, e.g. keyringseam, or a separate OS user).
Net: the bar rises from "any read primitive" to "must exec /usr/bin/security as the same user" — a real improvement, not a complete boundary.
Why this one, not the others
- Full seam coverage: implements both halves of
ctx.credentials—refs(API keys) andrecords(structured credentials likeclient-connection/browser-sessiongrants). Several other providers implement only the refs half, which means DSH's own session records fall back to the plaintext file. - Zero build step: pure JavaScript, no Swift, no code-signing certificate, no Xcode. Install and go.
- No auth prompts: reads and writes never ask the user for Touch ID / password. (That is a deliberate trade: keyringseam offers device-owner authentication at the cost of a prompt on every operation.)
Requirements
- macOS (
/usr/bin/security) - DeepSeek Harness ≥ 0.1.0-rc.6 (peer ranges cover both the 0.1.x line and
0.2.0-rc.1)
On DSH 0.2 and newer the plugin must be mounted as a package — installed into the profile, or linked into its node_modules — and referenced by package name. A row that points at an absolute index.js path does not work there, for two reasons: the runtime applies its peer-compatibility gate to plugin rows (ranges that do not admit the running version disable the row), and a module loaded from an absolute path gets no host peer resolution (the harness's own packages live inside app.asar, so there is no on-disk copy to resolve).
Install
dsh plugin --profile <profile> add dsh-keychain-credentials
# or from source:
dsh plugin --profile <profile> add github:<you>/dsh-keychain-credentials
Then the bundle's cordis.patch.yml disables the stock provider and mounts this one. If you prefer to wire it by hand, add to your patch layer (~/.dsh/profiles/<profile>/cordis.patch.yml or --patch <file>):
- id: credentials
disabled: true
- insert:
- id: credentials-keychain
name: dsh-keychain-credentials # 包名,不是绝对路径;插件须已装/链接进该 profile
config:
servicePrefix: dsh-credentials # keychain service prefix
account: dsh # keychain account name
Usage
Store a secret (account = credential reference name):
security add-generic-password -U -s dsh-credentials -a DEEPSEEK_API_KEY -w 'sk-…'
The LLM adapter resolves the reference per request — no restart needed after rotation.
Semantics kept from the seam contract:
- Process environment shadows the keychain (per-run operator intent wins).
- An empty stored value counts as absent.
set/unsetreject while a read-only source (the environment) shadows the ref.describechecks existence without reading the value — a status query never pulls plaintext into the agent process.- Errors from the
securityCLI are sanitized: exit code and stderr only, never the command line (which would carry the secret on a failedset). - Secrets are always fed to
securityover stdin, never argv, so they never appear inps. - Values longer than 128 bytes are written through
security -irather than the stdin password prompt: that prompt stores at most 128 bytes and truncates anything longer silently. Interactive mode has no such limit but reports no failure exit code, so those writes are confirmed by reading the value back. (The account token DSH stores as arecordsentry is one such value.)
Test
npm install # or pnpm install — devDependencies supply the seam packages
npm test
test/test-provider.mjs exercises the real macOS login keychain with throwaway probe entries under the dsh-credentials-test service prefix (it writes, reads back, and deletes them; it never touches a real key). test/test-e2e.mjs checks the peer ranges against the installed harness and, given a profile name (node test/test-e2e.mjs desktop), the profile's mount shape.
License
MIT
链接
同类插件
kenryu42/cc-safety-net★ 1900
执行前守卫,在工具调用运行前拦截破坏性 Git 与文件系统命令,以及对 SSH 密钥、.env 等机密文件的访问。
ADWMC/helm-d#helmd★ 984
DeepSeek Harness 的安全分析插件:33 个工具覆盖六大安全域、证据/报告与工具集,并提供案件生命周期、路由和工具账本;按会话绑定的案件工作区支持证据链、E 编号校验与可复现结论(repro_cmd);内置 362 篇按需参考、三档可热切换人设,以及带案件状态恢复的破甲 / Case / 拦截 / 关于四页工作台。
toby-bridges/api-relay-audit★ 904
从 DeepSeek Harness 对 AI API 中转站和 LLM 代理运行本地安全审计,生成 Markdown 报告,覆盖提示词注入、模型替换信号、工具调用改写、错误泄漏、流完整性和按 profile 启用的 Web3 风险。
SeaOf0/dsh-redteam-model★ 807
面向授权安全研究的 DSH 合集:九个工作模式(redteam 总控、渗透测试、代码审计、二进制分析、攻防评估、免杀对抗、应急溯源、云安全攻防、CTF 解题)与十五个运行时插件,设置页管理台支持一键部署、安装、更新与卸载。
howmp/dsh-pentest★ 616
面向 DeepSeek Harness 的授权渗透模式:以探索链路记录目标、线索、资产与漏洞,并在 Web 中可视化展示。
PerryLink/dsh-auto-review★ 244
审批链上的第二模型自动审查:只读审查子代理返回带理由的 allow/deny 结构化裁决,默认 fail-closed。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。