irisnb
dsh-credentials-keyring
OS-keychain credentials provider (Windows Credential Manager / macOS Keychain / Linux Secret Service) for the DeepSeek Harness credential seam
- Stars
- 2
- Language
- TypeScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-credentials-keyring
An OS-keychain credentials provider for the DeepSeek Harness credential seam (ctx.credentials).
It stores API keys and other secrets in the operating system's native credential store — Windows Credential Manager, macOS Keychain, or Linux Secret Service — instead of the plain-text file used by the built-in @deepseek-ai/dsh-credentials-local.
中文说明见文末。
Why
DeepSeek Harness ships a credentials seam (ctx.credentials) with exactly one provider, dsh-credentials-local, which writes secrets to a .credentials.yaml / .env file. The Harness's own docs mark the OS-keychain provider as deferred:
an OS-keychain provider — a store the model's processes cannot read at all — is the deferred answer and belongs beside this provider as a sibling package.
This package is that sibling provider. It keeps the same four-operation seam (resolve / describe / set / unset), so mounting it changes where secrets live, not how consumers read them — LLM adapters and other consumers keep calling ctx.credentials.resolve() unchanged.
Install
Not published to npm yet — install straight from the Git repository:
npm install git+https://github.com/irisnb/dsh-credentials-keyring.git
The compiled lib/ output is committed, so the Git install works without a build step.
Peer dependencies are @deepseek-ai/cordis and @deepseek-ai/dsh-credentials; install them to match the Harness version you run against.
Usage
The provider implements CredentialProvider, so it plugs into the credentials seam and stores one value per credential reference (a POSIX identifier such as DEEPSEEK_API_KEY).
import { Context } from '@deepseek-ai/cordis'
import { KeyringCredentialProvider } from 'dsh-credentials-keyring'
const ctx = new Context()
await ctx.plugin(KeyringCredentialProvider, { service: 'com.your-app.desktop' })
// Consumers then resolve through the seam as usual:
const hit = await ctx.credentials.resolve(credentialRef('DEEPSEEK_API_KEY'))
// { value: 'sk-…', source: 'keyring' } | undefined
Config
| Field | Default | Meaning |
|---|---|---|
service | com.deepseek.dsh | Keychain service namespace. Set it to your app's identifier so your secrets never collide with another app's. |
Every other value lives in the keychain under (service, account), where account is the credential reference.
Semantics
resolve(ref)→{ value, source: 'keyring' }when stored,undefinedwhen absent or empty.describe(ref)→{ configured, source?, writable }— never the value.set(ref, value)→ stores; rejects an empty value (useunset).unset(ref)→ deletes; deleting an absent entry is a no-op.set/unsetemitcredentials/updatedafter committing, like every provider.
Platform support and degradation
The native layer is @napi-rs/keyring (the Rust keyring crate behind an N-API binding). It is loaded lazily and probed once:
- Windows / macOS / Linux (with Secret Service) — full support.
- Headless Linux without Secret Service — the provider still mounts, but
describe()reportswritable: false,resolve()answers "absent", andset()throws a clear error. It never silently pretends a secret was stored.
Development
npm install
npm run typecheck # tsc --noEmit over src + tests
npm test # vitest: unit tests against an in-memory backend, never the real keychain
npm run build # tsc emit to lib/
Unit tests inject an in-memory KeyringBackend, so they run everywhere without touching the OS keychain. The one file that depends on @napi-rs/keyring's exact API is NapiKeyringBackend; its "not found" error mapping should be re-verified against the pinned version with a one-off smoke test on a real machine before release.
Security note
Secrets never enter this package's public API as config values; they move between the caller and the OS keychain only. Keep in mind the OS keychain protects against other processes on the machine and plain-text leaks on disk — it does not hide a secret from a caller your own code chose to trust.
License
MIT
中文说明
这是给 DeepSeek Harness 凭据接缝(ctx.credentials)写的「系统钥匙串」提供方:把 API Key 等秘密存进操作系统原生凭据存储(Windows 凭据管理器 / macOS 钥匙串 / Linux Secret Service),替代内置的明文文件实现 dsh-credentials-local。
它实现与内置提供方完全相同的四个操作(resolve / describe / set / unset),所以挂上去之后,所有读取凭据的消费者(如 LLM 适配器)一行都不用改。唯一可配置项是 service(钥匙串命名空间,默认 com.deepseek.dsh)。
无图形界面的 Linux 上原生层不可用时,插件仍能挂载,但会明确报「不可写」,绝不静默假装存成功。单元测试用内存后端,不碰真实钥匙串。
安装:目前尚未发布到 npm,可直接从 Git 仓库安装:
npm install git+https://github.com/irisnb/dsh-credentials-keyring.git
仓库已提交编译产物 lib/,所以 Git 安装后无需再手动 build。