dsh-keychain-credentials
Manifest validPure JavaScript macOS Keychain credentials provider for DeepSeek Harness, replacing plaintext .credentials.yaml storage and fully supporting both refs and records without native builds, signing, or Xc
dsh-keychain-credentials
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
Comments
Loading…
Similar plugins
by YYfather
Secure credential vault for DeepSeek Harness: tokens never leave the host — the agent runs gh/npm/npx/node/git with the token injected in the environment. Manage from 设置 → 凭证库 / 市场 → 已安装.
★ 0
MIT
JavaScript
Aug 23, 2026
dsh plugin --profile web add @yyfather/dsh-token-vaultby rogerdigital
DeepSeek Harness (dsh) plugin that adds a SearXNG-backed web_search provider to the ctx.web seam — free, self-hosted, key-less search instead of paid Exa/Perplexity APIs.
★ 7
↓ 449/wk
MIT
TypeScript
Sep 21, 2026
dsh plugin --profile web add dsh-searxngby yoggu
Brave-backed ctx.web search provider and settings card for the DeepSeek Harness.
★ 0
MIT
JavaScript
Sep 29, 2026
dsh plugin --profile web add dsh-brave-search-providerby HaydenSmith1121
Codex (ChatGPT) model provider for DeepSeek Harness - serves the ChatGPT subscription models the Codex CLI uses, over OAuth session credentials instead of an API key
★ 1
MIT
JavaScript
Sep 18, 2026
dsh plugin --profile web add dsh-codex-providerby dongsheng123132
Offline content-addressed DSSE/in-toto attestation proof for DeepSeek Harness
★ 0
MIT
JavaScript
Sep 7, 2026
dsh plugin --profile web add dsh-attestation-proofby maxwell-feng
DeepSeek Harness plugin: back the native web_search / web_fetch tools with your self-hosted SearXNG instance — keyless, private, no third-party search vendor.
★ 7
↓ 158/wk
MIT
TypeScript
Sep 13, 2026
dsh plugin --profile web add dsh-searxng-web