Skip to content
dsh.fish
Bundle

dsh-codex-keychain

Unofficial ChatGPT OAuth provider for DeepSeek Harness with strict native OS keychain storage

Source
CpfPatrick
stars
2 stars
License
MIT
Updated
Updated 12 days ago

Readme

# dsh-codex-keychain

[中文](README.zh.md)

An unofficial, independent ChatGPT OAuth provider for
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness). It adds the
`openai-codex` model route while keeping the complete OAuth credential in the
operating system's native credential store:

- macOS Keychain
- Windows Credential Manager
- Linux Secret Service

There is no OpenAI Platform API key involved, no fallback plaintext credential
file, and no reuse of `~/.codex/auth.json`.

> [!IMPORTANT]
> ChatGPT subscription access and OpenAI Platform API access are different
> products. This package connects only to the Codex backend made available to
> eligible ChatGPT accounts. It is not affiliated with or endorsed by OpenAI or
> DeepSeek.

## Status

`0.1.0-alpha.1` is a developer preview targeting DeepSeek Harness
`0.1.0-rc.6` and `@earendil-works/pi-ai` `0.82.1`.

## Install

Install the prebuilt bundle into a DSH profile:

```sh
dsh plugin --profile web add dsh-codex-keychain@next
dsh web
```

Open **Settings → OpenAI Codex**, choose **Sign in with browser**, then click
**Open authorization page** and finish the OpenAI authorization. The plugin
deliberately does not change the default model; select an `openai-codex` model
from DSH's model picker after signing in.

For headless hosts or when the localhost callback cannot bind:

```sh
dsh plugin --profile web exec dsh-codex-keychain login --device-code
```

## CLI

```sh
dsh plugin --profile web exec dsh-codex-keychain login
dsh plugin --profile web exec dsh-codex-keychain login --device-code
dsh plugin --profile web exec dsh-codex-keychain status
dsh plugin --profile web exec dsh-codex-keychain status --json
dsh plugin --profile web exec dsh-codex-keychain logout
```

`status --json` contains only the sign-in state, provider, platform, backend,
and—on failure—a stable code and safe message. It never includes tokens,
account IDs, or token timestamps.

## Security model

The plugin stores a versioned manifest and bounded Base64 chunks entirely as
native credential items. The service is
`io.github.CpfPatrick.dsh-codex-keychain`; its root account is a SHA-256 digest
of the normalized `DSH_HOME`, and chunk accounts are derived from that digest.
Different Harness homes therefore do not share rotating refresh tokens. Two
fixed chunk banks keep updates crash-safe: a new bank is written and verified
before the small manifest is switched, then the retired bank is cleared. The
bounded items also stay below Windows Credential Manager's per-item limit.

Token refresh and logout use a non-secret cross-process lock under
`$DSH_HOME/.locks`. A refresh failure preserves the previous credential for a
later retry or explicit re-login. If the native credential store is missing,
locked, or unavailable, the plugin reports `KEYCHAIN_UNAVAILABLE` and refuses
to sign in—there is no silent file fallback.

Web authentication RPC is loopback-only. A remote DSH browser must run the CLI
on the DSH host. OAuth URLs and device codes are transient; the plugin does not
write them to application logs or persistent storage. The CLI displays them
when required for login, so do not share or capture that terminal output.

See [SECURITY.md](SECURITY.md) for reporting and operational guidance.

## Troubleshooting

- **`KEYCHAIN_UNAVAILABLE` on macOS:** unlock the login keychain and allow the
  terminal or DSH process to use it. The plugin stays loaded but refuses model
  requests until secure storage works.
- **`KEYCHAIN_UNAVAILABLE` on Windows:** make sure Windows Credential Manager
  is available for the current user and that DSH is not running under a
  different service account.
- **`KEYCHAIN_UNAVAILABLE` on Linux:** run DSH inside a desktop or server
  session with a Secret Service provider, such as GNOME Keyring or KWallet,
  and a working D-Bus session. The plugin never substitutes a file backend or
  the Linux kernel keyring.
- **Browser callback cannot bind:** the browser flow uses localhost port 1455.
  Stop the process occupying that port, use **device-code login**, or paste the
  callback response when the CLI or settings page asks for it.
- **Another login is already running:** one OAuth flow is allowed at a time
  across DSH and CLI processes. Finish or cancel that flow, then retry.
- **A process crashed while holding a lock:** first confirm that no DSH or
  `dsh-codex-keychain` process for this `DSH_HOME` is still running. Only then,
  remove the orphaned
  `$DSH_HOME/.locks/dsh-codex-keychain-openai-codex.lock` and/or
  `$DSH_HOME/.locks/dsh-codex-keychain-openai-codex-login.lock`. Never remove a
  live process's lock.
- **Duplicate `openai-codex` provider:** disable the other Codex/OAuth provider
  plugin and restart DSH. Two adapters cannot own the same model route.
- **Refresh or authorization failed:** run login again. A failed refresh or
  incomplete login does not replace the previously stored credential.
- **After a DSH upgrade:** this alpha is pinned to DSH `0.1.0-rc.6`; wait for a
  compatibility update or test the newer Developer Preview in an isolated
  profile before upgrading a working profile.

Remote browsers cannot call the authentication RPC. Run the CLI command on the
DSH host instead. To remove the native credential before uninstalling:

```sh
dsh plugin --profile web exec dsh-codex-keychain logout
dsh plugin --profile web remove dsh-codex-keychain
```

## Supported scope

The alpha includes:

- browser and device-code ChatGPT OAuth
- automatic locked token refresh
- the Codex model catalog and DSH model-picker integration
- DSH-native streaming, reasoning, tool calls, replay, and existing DSH image
  attachments/model vision
- a dedicated Web settings page and a headless CLI

It intentionally does not include quota displays, web search, a standalone
image-viewing UI, or image generation.

Known alpha limitation: DSH `0.1.0-rc.6` resolves adapter authentication before
it creates the per-stream cancellation signal and idle watchdog. Normal model
streaming remains cancellable, but a network-stalled token refresh cannot be
cancelled by the current request. Do not remove a live process's writer lock;
stop that process first if recovery is required.

## Development

Requirements: Node.js `^22.19 || >=24` and pnpm `11.7.0`.

```sh
pnpm install
pnpm check
node scripts/native-keyring-smoke.mjs
```

The native smoke script sends a disposable OAuth-shaped document larger than
4 KiB through the production chunk store, verifies it, and deletes every item
in `finally`. Unit tests use an injected in-memory driver and never touch the
developer's real keychain.

## Acknowledgements and clean-room boundary

The DSH community already has OAuth plugins, including
[`Yan-Zero/dsh-codex`](https://github.com/Yan-Zero/dsh-codex). This repository
was implemented independently against the public DSH and pi-ai interfaces; it
does not copy that project's source. The narrow differentiator here is strict,
cross-platform native credential storage with no ordinary-file fallback.

## License

MIT

Install

dsh plugin --profile web add github:CpfPatrick/dsh-codex-keychain

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source