Foreword

DSH credentials can be stored in a local credentials file. For users who wish to retain the original file path and switch from plaintext credentials to password-protected ciphertext, dsh-encrypt provides a bundle-form plugin. This section introduces its purpose, installation, activation, and common operations.

What Is This

dsh-encrypt is a DSH credentials encryption plugin maintained by yauntyour, licensed under MIT, with the current version 0.1.0-rc.12.

It transforms $DSH_HOME/.credentials.yaml into a single-file dual-form: plaintext YAML when no password is set; after setting a password, the same file is replaced in-place with an AES-256-GCM ciphertext document. The key is derived using Argon2id, and documents and entries use SHA3-256 fingerprints for integrity checks.

The plugin launches with the profile and belongs to the bundle form: dsh.bundle.patch is added to cordis.patch.yml.

Core Features

  • Single-file dual-form: Plaintext YAML and ciphertext JSON are converted in-place, with no second file created and no path migration.
  • Encryption: AES-256-GCM; each credential uses an independent random nonce; reference names are bound as GCM AAD.
  • Integrity: SHA3-256 entry-level and document-level fingerprints; corrupted files are rejected on startup.
  • Password derivation: Argon2id; old scrypt (v2) ciphertexts remain unlockable and are automatically upgraded upon unlocking.
  • Web input: The browser computes the SHA3-256 digest of the password, and the backend only receives the digest; the original password never leaves the browser.
  • Unlock brute-force protection: Persistent consecutive failure counting; exponential backoff after reaching the threshold, returning HTTP 429 + Retry-After.
  • Output sanitization: Credential values in HTTP response bodies and WebSocket text frames are replaced with [REDACTED:dsh-encrypt].
  • Release self-check: lib/integrity-manifest.json is generated at build time and verified file-by-file at startup; it is used to detect installation corruption, not as a trust root for preventing malicious package modification.
  • Passwordless tickets: Upon successful unlock, a 256-bit ticket is issued, defaulting to HttpOnly Cookie only.
  • Localhost restriction: Unlocking, setting, changing passwords, and passwordless settings require Host loopback and socket loopback.
  • Permanent ciphertext: After setting a password, the file never reverts to plaintext; external plaintext replacements are immediately re-encrypted when unlocked and rejected when locked/at startup.
  • Memory cleanup: Ciphertext is decrypted only when in use, intermediate buffers are zeroed immediately; keys are zeroed on lock/unload.
  • Request-level decryption: Plaintext exists only for a single operation, with no caching or logging.
  • File and runtime: Hot reload, atomic writes, file locks (POSIX enforce 0600), automated unlock via DSH_CREDENTIAL_PASSWORD.
  • Runtime guardrails: Detects the running DSH version at load time and throws UNSUPPORTED_DSH across threads.

Installation and Activation

Environment

Node.js >= 24
DSH @deepseek-ai/dsh@0.0.1-rc.1+
Compatible with runtime dsh 0.1.0-rc.7 line (tested combinations; cross-line explicitly reports UNSUPPORTED_DSH)

Dependencies are recorded as follows:

  • Seam packages pinned versions: cordis 4.0.1, dsh-credentials, etc., 0.1.0-rc.6
  • Standalone packages with range versions: @node-rs/argon2, chokidar, yaml

@node-rs/argon2 is a native dependency with precompiled binaries. In the rare case of missing platform combinations, you can run:

pnpm rebuild @node-rs/argon2

Packaging and Installation

First, package locally, then install to the web profile:

corepack enable
pnpm install --frozen-lockfile
pnpm pack
dsh plugin --profile web add ./dsh-encrypt-0.1.0-rc.12.tgz

Source Directory Installation

If you want to install directly from a local source directory, you can use:

dsh plugin --profile web add "D:/Developments/DSH/DSH-Encrypt"

Mounting Web Password Routes

The bundle patch only inserts the provider line; browser routes are independent combination lines. Add the dsh-encrypt-web line to the user layer in $DSH_HOME/profiles/web/cordis.patch.yml:

- insert:
    - id: dsh-encrypt-web
      name: 'dsh-encrypt/web'
      config:
        trustedHosts: []

For LAN/tunnel deployments, you need to add the allowed authoritative sources to trustedHosts. If the configuration uses !!js expressions to reference ctx.webRuntime, you must add the line-level inject: [webRuntime].

For example:

- insert:
    - id: dsh-encrypt-web
      name: 'dsh-encrypt/web'
      inject: [webRuntime]
      config:
        trustedHosts: []

Verifying Installation

After completing the above steps, check the configuration output of the current profile:

dsh --profile web --dump-config | grep dsh-encrypt

Expected result: Both the dsh-encrypt and dsh-encrypt-web lines are present, and the base credentials line is disabled.

Common Usage

Setting an Encryption Password

Enter a password of at least 8 characters twice. Upon completion, the same file is replaced in-place with a ciphertext document, and the process remains unlocked.

Unlocking

During unlock, the password digest is verified, the key is derived, and then model invocation is restored.

Changing the Password

After entering the current password, all entries are re-encrypted, and existing tickets are invalidated.

Passwordless Login

The slider supports the following values:

  • 0: Every time
  • 1-30: Days
  • -1: Forever

These passwordless settings are only available locally.

Applicable Scenarios and Notes

Suitable for local or single-machine deployments where users wish to retain the original .credentials.yaml path and switch from plaintext credentials to password-protected ciphertext.

Notes:

  • The plugin runs with the current DSH process permissions; check the source code and license before installation.
  • Forgotten passwords are irrecoverable; after deleting .credentials.yaml, the settings page still requires you to establish a new password before you can reconfigure credentials.
  • allowEnvFallback: false can disable environment and .env fallback, enforcing a strict file-only policy.
  • Release file consistency self-checks are used to detect installation corruption, not as a trust root for preventing malicious package modification.
  • Local password operations require Host loopback and socket loopback; requests with proxy forwarding headers are not treated as local requests.

Conclusion

dsh-encrypt keeps DSH credentials encryption within a single file: after setting a password, the file remains ciphertext, the browser only submits digests, requests are decrypted on demand, outputs are sanitized, and brute-force locking and integrity checks are retained.

GitHub: https://github.com/yauntyour/DSH-Encrypt