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.jsonis 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_DSHacross 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 time1-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: falsecan disable environment and.envfallback, 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.