dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
Harness 的本地加密凭据保险库:Web 设置页与 vault_* 工具,可存取与复制密码、API 密钥、TOTP 与银行卡信息,支持健康审计、到期轮换、导入导出以及只读/询问访问模式。
English | 中文
dsh-vault is a security-focused plugin for DeepSeek Harness that stores sensitive credentials — usernames, emails, phone numbers, passwords, TOTP secrets, and developer credentials like SSH connections, API keys, secrets, and OAuth access/refresh tokens — encrypted at rest, and exposes them to the model through CRUD, search, password generation, and TOTP tools, plus a Settings UI page.
node:crypto (AES-256-GCM authenticated encryption, scrypt key derivation, RFC 6238 TOTP).scrypt(master password, salt) and AES-256-GCM. The key never touches disk; after unlock it is cached in-process and re-derived on restart.writeFileAtomic + file lock; in-process writes are serialized, cross-process writers take the lock.vault_search returns summaries only (id/title/kind/username/email/phone/host/port/url/tags) — never passwords, keys, tokens, or TOTP secrets. Full credentials are readable only via explicit vault_get by id.Each record has a title, an optional kind, and any combination of fields:
| Field | Description |
|---|---|
kind | login (default) / ssh / api-key / secret / oauth / cookie / card / custom |
username / email / phone | Account identity |
password | The password |
host / port | SSH host and port (e.g. db.internal / 2222) |
privateKey | SSH private key (PEM) |
apiKey | API key |
secret | Generic secret (client secret, shared secret, …) |
accessToken / refreshToken / expiresAt | OAuth token pair and expiry (epoch millis) |
otpSecret | TOTP secret (bare Base32 or otpauth:// URI) |
url / notes / tags | Metadata |
Two kinds carry their own shape: a cookie entry stores a captured browser session, and a card entry stores cardNumber / cardExpiry (MM/YY) / cardCvv / cardHolder — search summaries expose only the expiry and holder, never the number or CVV, and the Bitwarden JSON export maps it to a card item (type 3, brand inferred).
| fields | Arbitrary key/value pairs (e.g. {"region": "us-east-1"}), searchable |
113 tools in five groups. Basic is what a default install registers; the rest are switched on through Tool profiles (Settings → Credentials → Permissions → Model tools).
Eleven tools. Everything below is opt-in.
| Tool | Purpose |
|---|---|
vault_list | List available vaults in the vault directory (one .json file per vault, excluding access/meta/export files) |
vault_search | Search titles/categories/usernames/emails/phones/hosts/ports/URLs/notes/tags/custom fields (incl. numeric/boolean/nested values; whitespace-separated terms OR-match); optional createdAfter/createdBefore epoch-millis filters; returns secret-free summaries; limit must be an integer 1–100 |
vault_get | Read a full entry by id (including all secrets) |
vault_add | Add an entry (any combination of fields; empty strings/arrays are ignored) |
vault_update | Update fields by id (unprovided fields kept; empty string clears a field; title is renamable; rotationDays: 0 clears rotation = never rotate) |
vault_delete | Soft-delete an entry (moves it to the trash, still encrypted on disk) |
vault_fill | Find the entry matching a host/URL/username/title and return its credentials |
vault_clipboard | Fetch one entry secret field for direct copy (username/password/apiKey/...) |
vault_totp | Generate the current 6-digit code for a stored otpSecret (or a bare Base32 / otpauth URI) |
vault_generate_password | Generate a strong random password (length/classes/grouping) or a memorable passphrase (passphrase: true, EFF-style word list, words/separator/wordDigits) |
vault_strength | Zero-dependency password strength estimate (score 0–100, weak/fair/strong/very strong) |
Favourites, tags, history, health, templates, attachments, card and 2FA detail.
| Tool | Purpose |
|---|---|
vault_compare | Compare two entries field by field (onlyA/onlyB/differ/equal) — field names only, never secret values |
vault_rename | Rename an entry in one call (shortcut for vault_update) |
vault_restore / vault_purge / vault_restore_recent | Bring a trashed entry back / purge it / undo the last delete |
vault_lock / vault_unlock | Explicitly lock the vault (wipe the in-memory key) / re-unlock it |
vault_password_history | List an entry's previous passwords (1Password/Bitwarden-style, newest first, capped at 10; current password excluded) |
vault_password_rollback | Restore an entry password to a stored history entry (current password is archived first, so it is reversible) |
vault_apply_tags | Bulk add/remove/replace tags on every entry matching a query (dry-run supported, no secrets) |
vault_totp_uri | Build an otpauth:// provisioning URI for a stored or bare TOTP secret |
vault_rotation | Report expired / due-for-rotation / expiring-soon credentials; soonWindowDays (1-90, default 7) tunes the soon horizon (no secrets) |
vault_health | Vault health scan: weak/reused passwords, missing 2FA, insecure http:// sites, and an overall security score (0–100) |
vault_watchtower | Watchtower-style per-entry risk analysis (1Password/Bitwarden-inspired): flags short/weak passwords, keyboard sequences, embedded years, common passwords, reuse, http:// sites, missing 2FA, expiry — with a 0–100 score and good/warn/poor verdict (no secrets); entry rows show ⚠ badges |
vault_breach_check | Watchtower-style breach scan against Have I Been Pwned (k-anonymity: only the SHA-1 prefix leaves the machine), with an offline common-password fallback |
vault_integrity | Verify the on-disk vault file decrypts correctly and matches the in-memory store |
vault_merge | Merge one entry into another; keepSource: true keeps the source after merging |
vault_attach / vault_attachments / vault_attachment / vault_detach | Attach files to entries (private keys, certs, configs, recovery codes) — stored base64 inside the encrypted entry, encrypted at rest; list names/sizes, read content, remove |
vault_quick_add | Fast capture (title + one secret) with optional tags/notes |
vault_expiry | Set/clear expiry (expiresAt: 0 removes it) |
vault_stats | Overview counts incl. trashCount (no secrets) |
vault_verify | Verify one entry or audit every entry (all: true) for per-kind completeness, port/expiry sanity (no secrets) |
vault_duplicates | Find duplicate groups: mode = both (default) / title / content (no secrets) |
vault_report | Printable inventory with expiry/rotation columns and a stats footer (no secrets) |
vault_match_url | Find login entries matching a URL (Bitwarden/1Password-style: exact host, subdomain, parent domain, path-prefix; www./port normalization) with a 0–100 score — never returns the password |
vault_env | Render env-flagged entries (tags contain env) as KEY=VALUE lines — see Environment export |
vault_copy | Copy an entry (secrets included) into another named vault |
vault_templates | Built-in + user-defined templates (save/list/remove), KeePassXC-style; built-ins now include Wi-Fi, Server, Database, Identity, Bank account, Card (1Password-inspired) |
vault_notes | Append to or replace the free-form notes of an entry (a convenient shortcut for vault_update) |
vault_changes | List vault activity within a time window (default 24h): entries created, updated, or soft-deleted, newest first |
vault_find | Fuzzy-find entries: matching ignores case, punctuation and whitespace, so gh reaches GitHub |
vault_mask | Redact likely credentials in arbitrary text (API keys, tokens, passwords, private keys) so it can be logged or quoted safely |
vault_history | Show recent activity on the vault within this process, newest first: mutations (add/update/delete/restore/purge/merge/rollback) plus reads (read, totp), searches and vault switches. Records only the action, entry title and timestamp — never passwords, keys, usernames or other secret values |
vault_recent | List the most recently created or updated entries (newest first), as secret-free summaries |
vault_pin | Pin (favorite) an entry so it ranks first in search and list |
vault_unpin | Unpin an entry (remove its favorite flag) |
vault_tags | List every tag used across entries with the number of entries per tag |
vault_generate_username | Generate a random username or an anonymous email suggestion |
vault_rotate_password | Generate a new strong password, store it on the entry, and return the new value for the caller to hand to the target service |
vault_touch | Mark an entry as recently used (update its updatedAt without changing content) |
vault_note_secret | Store a single secret under a generated title (a one-off note without naming it) |
vault_search_advanced | Search with multiple optional criteria: title substring, username/email substring, kind, tag, created-after/before (epoch millis), and favorite-only |
vault_count | Return the number of active entries (optionally filtered by kind and/or tag) |
vault_set_icon | Set the UI icon (emoji) and/or accent color on an entry |
vault_describe | Describe an entry in plain language (kind, identity, host/url, tags, expiry) without revealing secrets |
vault_last_modified | List entries most recently modified (updatedAt), newest first |
vault_has | Quickly check whether the vault contains a credential matching a title/username/host (substring, or exact title when exact is set) |
vault_autofill_check | Check whether the vault has a credential usable for a URL/host: returns the best matching entry (username/email only, never the secret) or a not-found verdict |
vault_undelete_all | Restore ALL soft-deleted (trashed) entries back to the active set |
vault_get_many | Read multiple entries by id, returning only the requested fields for each |
Migrating in and out of other password managers, bulk operations, and env/CSV/1Password/Bitwarden/KeePass/pass interop.
| Tool | Purpose |
|---|---|
vault_import_csv | Bulk-import credentials from a CSV file (custom columns become fields; overwrite: true merges fields into existing entries instead of duplicating) |
vault_bulk_delete | Soft-delete entries matching a query/kind/tag or explicit ids; confirm: true required (dry-run by default); trashed entries are restorable |
vault_export / vault_import | Portable encrypted backup/migration of the whole vault (separate export password) |
vault_export_bitwarden / vault_import_bitwarden | Bitwarden/Vaultwarden JSON interop (full field mapping, overwrite support) |
vault_import_bitwarden_encrypted | Decrypt a Bitwarden password-protected JSON export (PBKDF2/Argon2id + HKDF → AES-256-CBC + HMAC) and import it; pass the export passphrase |
vault_import_manager_csv | Password-manager CSV auto-detected by header: Bitwarden (login_uri/login_username/…), 1Password 8, Dashlane, NordPass, Keeper, LastPass (fav/grouping/extra); dryRun preview |
vault_import_kdbx | KeePass KDBX: 3.1 and 4.x, AES-KDF or Argon2 (RFC 9106), AES-256-CBC or ChaCha20 payload, keyfile support |
vault_export_1password | Export entries as a 1Password 1PUX archive (ZIP + export.data) for import into 1Password or re-import here; item categories map to login / credit card / API credential / server |
vault_import_1password / vault_import_1pif | 1Password 1PUX (ZIP) and legacy 1PIF text exports |
vault_import_enpass | Enpass JSON export (folders → tags, typed fields, TOTP) |
vault_import_keepass_xml | KeePass 2.x XML export (plaintext or ******** masked values) |
vault_import_chrome / vault_import_keychain | Import passwords from Chrome's Login Data (macOS keychain / Linux keyring or peanuts / Windows DPAPI) or the macOS Keychain (internet passwords inet by default — the ones that actually back website logins — or generic genp via classes; session cache + preview, no prompt spam); every file import supports dryRun preview |
vault_import_firefox | Firefox profile import (logins.json + key4.db, NSS 3DES / PBES2-AES, primary-password aware) |
vault_export_totp | List every entry that has a TOTP secret, with its title and issuer label |
vault_bulk_export | Export ALL entries (including secrets) as a JSON file for audit or migration |
vault_export_browser | Export login entries in the browser password-manager CSV format (name,url,username,password) for importing into Chrome/Firefox/Edge |
vault_migrate_keepass | Export entries in KeePass 2.x import CSV format (Group,Title,Username,Password,URL,Notes) for migrating into KeePass |
vault_export_keepass_xml | Export entries as a KeePassXC-compatible XML document (KeePass 2.x schema) |
vault_import_browser | Import a browser password-manager CSV (name,url,username,password — Chrome/Firefox/ Edge export format) |
vault_export_wallet | Export entries as a directory tree of files compatible with pass (the standard Unix password manager): one file per entry containing the password, with metadata in comments |
vault_import_wallet | Import entries from a pass directory tree: each .gpg file (or plaintext file) becomes an entry titled by its filename; the first line is the password, remaining lines are parsed as login:/email:/url: metadata. Returns added/skipped |
vault_export_env | Write env-flagged entries (tags contain "env") to a .env file at the given path as KEY=VALUE lines (values shell-quoted) |
vault_export_csv | Export vault entries to a CSV file (the same shape vault_import_csv accepts), optionally filtered by kind |
Capturing and replaying cookie sessions; needs the optional playwright-core.
| Tool | Purpose |
|---|---|
vault_session_open | Open a real headed browser window at a URL so the user can log in manually (password, 2FA, captcha) — the portable way to capture login state for sites that block embedding — requires the optional playwright-core |
vault_session_collect | Collect every cookie of an open browser session (incl. HttpOnly) and save it as a cookie entry |
vault_session_import | Save session cookies from pasted JSON (devtools export shape) or a raw Cookie header string — the no-browser alternative |
vault_session_import_file | Import a Netscape cookie-jar file (curl -b / wget / browser-extension export; the same format vault_session_export writes) |
vault_session_list | List saved login sessions with cookie counts, expired and expiring-in-7d counts (no values) |
vault_session_export | Export a saved session as a Cookie header value, a Netscape cookie-jar file (curl -b), raw JSON (Playwright addCookies shape), or a ready-to-run Playwright snippet |
vault_session_close | Close an open browser login session (collected cookies stay in the vault) |
vault_session_prune | Remove expired cookies from a saved session (session cookies are kept); preview: true reports without writing |
Backups, vault switching, rekeying, recovery codes and system search.
| Tool | Purpose |
|---|---|
vault_recovery_code / vault_verify_recovery / vault_recovery_status | One-time vault recovery code (1Password/Bitwarden-style): 32-char code shown once, only its SHA-256 hash is stored; verify possession of the code; check whether one is set |
vault_rekey | Upgrade the vault to fresh scrypt KDF parameters in place |
vault_switch | Switch the active vault for this session |
vault_backup / vault_backup_now | Timestamped encrypted backup named <vault>-backups-YYYY-MM-DD_HH-MM-SS-<hex>.json (owning vault + date visible); retention pruning keeps the newest N (maxBackups, default 10) |
vault_restore_backup | Restore from a backup: mode: "merge" (default) copies the backup entries INTO the current vault so they appear in the entries list; mode: "replace" overwrites the whole vault with a safety snapshot first |
vault_vault_rename / vault_vault_delete | Rename a named vault (file moves, active session follows) or permanently delete one (default vault protected) |
vault_search_system | Search Chrome / Keychain for sites & usernames — never exposes passwords |
vault_backup_status | Report how many days have passed since the last backup file was written (1Password-style backup reminder; new-style <vault>-backups-<date>.json and legacy vault-backup-<epoch>.json names are both recognized). Returns daysSinceBackup and a suggestion |
vault_search_history | Search including soft-deleted (trashed) entries, marked with their deleted state |
vault_backups | List available encrypted vault-backup-*.json files (newest first) with their absolute paths and timestamps |
Typical workflows: store an SSH credential (kind: ssh + host/port/username/password or privateKey) and have the model vault_search for the host then vault_get the connection details; keep api-key/oauth entries for API-gateway access/refresh token rotation.
dsh-vault is a bundle (a package declaring dsh.bundle): once installed into a profile, its cordis.patch.yml automatically inserts the vault plugin row (referenced by package name dsh-vault; the master password is injected via the DSH_VAULT_PASSWORD environment variable). The package ships a self-contained build script — git installs compile lib/ automatically.
All four install paths below are verified end-to-end (install → bundle layer recognized → plugin activates with all 7 vault_* tools registered → real vault_add/vault_get round trip → uninstall removes the layer):
| Path | Command | Build needed | allowBuilds |
|---|---|---|---|
| npm | add dsh-vault | no (prebuilt lib/) | no |
| GitHub | add github:Ox0400/dsh-vault#v0.1.1 | yes (prepare) | yes (first run) |
| local path | add /abs/path/to/dsh-vault | no (link to built source) | no |
| tarball | add ./dsh-vault-0.1.1.tgz | no (prebuilt lib/) | no |
dsh plugin --profile web add dsh-vault
npm packages ship prebuilt lib/ artifacts — no allowBuilds, no local compilation, install and go. Set the master password before launching:
export DSH_VAULT_PASSWORD='your strong master password'
dsh plugin --profile web add github:Ox0400/dsh-vault#v0.1.1
A git install fetches sources, not built artifacts, so the prepare script builds lib/ at install time. pnpm ≥10 blocks git dependencies from running build scripts by default. The verified flow:
Run the add command — it fails with an allowBuilds error and prints the exact key to allow (the line containing the repo URL, including the resolved commit hash):
allowBuilds:
dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
Append that exact key to the profile's pnpm-workspace.yaml ($DSH_HOME/profiles/<name>/pnpm-workspace.yaml):
packages:
- .
allowBuilds:
dsh-vault@https://codeload.github.com/Ox0400/dsh-vault/tar.gz/<sha>: true
Re-run the add — pnpm now runs the prepare script, builds lib/, and installs.
Pin a tag/commit so a later upstream push cannot silently change what runs on install. Treat the allowance for what it is: permission to execute that package's code on your machine at install time — only grant it to sources you trust.
dsh plugin --profile web add /absolute/path/to/dsh-vault
pnpm links the checkout into the profile; the bundle is recognized as long as lib/ exists (run pnpm build in the checkout first if needed).
npm pack && dsh plugin --profile web add ./dsh-vault-0.1.1.tgz
The tarball ships prebuilt lib/ artifacts, so no build step or allowBuilds is required.
dsh plugin --profile web remove dsh-vault uninstalls (removes both the dependency and the layer).
The plugin hands the vault to the assistant. The bundled dsh-vault command
hands the same vault to shells and scripts, so a skill's child process can read
a secret without the plaintext ever entering the model's context.
Nothing provides a dsh-vault binary until the package is installed — the
plugin is a Cordis bundle, and dsh has no plugin-subcommand registry (the
launcher parses only its own flags; dsh plugin … just forwards to pnpm, so
dsh web exec … hands its arguments to the web app and fails with
error: too many arguments). Pick your row before reading the examples:
| your setup | the command |
|---|---|
source checkout (git clone + pnpm build) | pnpm vault — or node lib/cli.js, or ./lib/cli.js |
| plugin installed into a profile | pnpm dsh plugin --profile web exec dsh-vault |
globally installed (npm i -g dsh-vault) | dsh-vault |
| nothing installed | npx dsh-vault |
# source checkout — this repository, right now:
pnpm vault list
# after a global install (or via npx) the same commands are:
dsh-vault list
npx dsh-vault list
Every example below is written as dsh-vault …; substitute the form from your
row (pnpm vault … in a checkout).
env is forget fetches one value and needs no tag. dsh-vault env is for the other
case: a script that needs several secrets at once. It prints the entries you
tagged env as shell assignments, so the script picks them up itself:
$ dsh-vault env
DEMO_API_KEY='sk-demo-123'
OTHER_PASSWORD='pw-not-exported'
eval "$(dsh-vault env)" reads those assignments into the current shell —
the usual reason to reach for it:
eval "$(dsh-vault env)" # KEY=VALUE lines become shell variables
echo "$DEMO_API_KEY"
Two things worth knowing:
env-tagged entries are exported. With none tagged you get
`dsh-vault: nothing to export — no entry carries