Back to home

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

FieldDefaultMeaning
servicecom.deepseek.dshKeychain 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, undefined when absent or empty.
  • describe(ref){ configured, source?, writable }never the value.
  • set(ref, value) → stores; rejects an empty value (use unset).
  • unset(ref) → deletes; deleting an absent entry is a no-op.
  • set / unset emit credentials/updated after 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() reports writable: false, resolve() answers "absent", and set() 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。