irisnb/dsh-credentials-keyring

插件Plugin ⭐ 3 MIT 其他Other

OS-keychain credentials provider (Windows Credential Manager / macOS Keychain / Linux Secret Service) for the DeepSeek Harness credential seam

项目介绍Project Overview

为 DeepSeek Harness 凭据接缝提供系统钥匙串后端:API Key 等秘密写入 Windows 凭据管理器、macOS 钥匙串或 Linux Secret Service,替代内置的明文文件。实现与原提供方一致的 resolve、describe、set、unset,挂载后 LLM 适配器等消费者无需改动。可配置 service 命名空间。无图形界面 Linux 上原生层不可用时,插件仍可挂载但明确报不可写。尚未发布至 npm,仅支持从 Git 仓库安装。

A credentials provider for the DeepSeek Harness seam that stores API keys and other secrets in the operating system's native keychain (Windows Credential Manager, macOS Keychain, or Linux Secret Service), replacing the built-in plaintext file provider. It implements the same four operations (resolve, describe, set, unset), so LLM adapters and other consumers keep calling ctx.credentials.resolve() unchanged. A configurable service namespace scopes entries per app. On headless Linux without Secret Service, the provider still mounts but reports writable: false and never silently claims storage. The package is not on npm and must be installed from the Git repository.

或使用命令行安装(适合开发者)Or use CLI install (for developers)

命令行安装CLI Install

dsh plugin --profile web add github:irisnb/dsh-credentials-keyring

irisnb/dsh-credentials-keyring 加入你的 DSH 配置(web profile)即可启用。

READMEREADME

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, 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。

上一个 Prev ipss-agent 下一个 Next DeepDeck