Foreword

The dsh web command of DeepSeek Harness (DSH) is by default designed for local browser access: workspace selection triggers the host machine’s native directory dialog, several privileged APIs (host.pickDirectory, settings.*, credentials.*, etc.) are officially hardcoded to loopback only, and the documentation explicitly states this remains the case “until a real authentication layer is implemented.” If DSH is exposed to the local network or the internet via nginx, SSH tunnels, Tailscale, or Frp, remote users cannot access the native selection dialog and cannot securely use these interfaces without authentication.

@xgone/dsh-remote (GitHub: xgone/dsh-remote) addresses this exact gap: it adds username/password login, MFA (TOTP) gating, signed session cookies, and role-based permissions in front of dsh web, and replaces the directory selection with an in-browser dialog. After successful authentication, the DSH endpoints originally restricted to loopback are automatically permitted, without triggering any native windows on the host machine throughout the process.

What is this

@xgone/dsh-remote is published by maintainer xgone, categorized as admin-security, and licensed under MIT. The current npm version is 0.2.8. The GitHub repository has approximately 42 stars and 2 forks.

In one sentence: It enables secure remote access to DeepSeek Harness—once logged in via a browser on the public internet or local network, you can use the full web functionality, including workspace selection and account management.

Core Features

Remote Access & DSH Privilege Permitting

After exposure via a reverse proxy or tunnel, logging in from an external browser grants access to all features. The plugin acts as an authentication layer; after verification, it automatically permits the privileged methods within DSH’s /api that were originally pinned to loopback.

WebSocket event streams (events.mux / events.host) establish normally while the session is valid.

In-Browser Directory Selection

DSH’s default directory selector invokes the host OS’s dialog in a loopback deployment, which remote users cannot operate. This plugin replaces it with a browse backend: selecting or creating a workspace becomes an in-browser dual-pane directory view with breadcrumbs and a “new folder” option, without launching any host windows.

Username/Password & Login Gating

Accessing any path without logging in returns a self-contained login page; both /api and WebSocket require a valid session cookie.

Sessions use HMAC-SHA256-signed HttpOnly cookies, configurable with expiration time, Secure, and SameSite attributes; the signing key is randomly generated and persisted, so sessions survive restarts.

Passwords are stored using scrypt hashing (N=16384, r=8, p=1) with constant-time comparison, and plaintext is never written to disk. Login failures are rate-limited by “IP + username,” with a default limit of 5 attempts within a 15-minute window.

On first run with no accounts, the login page offers to “Create the first administrator,” which can only be submitted from the local loopback to prevent remote front-running. The root account cannot be deleted or have its role changed; only password resets are allowed. The default adminOnly mode disables account creation and enforces the admin role; when disabled, it enables three-tier method-level permissions: admin, user, and guest.

MFA Two-Factor Authentication (TOTP)

Compatible with standard authenticators like Google Authenticator, 1Password, and Authy (RFC 6238, 6 digits / 30 seconds). When enabled, it displays a QR code (SVG), manual key, otpauth link, and 10 one-time backup codes (backup codes are stored only as SHA-256 hashes). The login page shows a countdown for the remaining seconds of the dynamic code; input of 6 digits triggers automatic verification; backup codes containing letters require manual confirmation. Administrators can disable MFA for any account using their own password.

Settings Page & Experience Details

Settings → Login & Account: MFA self-service, account list, password reset, logout. When a session expires, a full-screen re-login overlay appears within the SPA.

The interface uses DSH’s official design tokens (--dsw-alias-*) for coloring, automatically following light/dark/system modes. The login page, MFA guide, re-login overlay, and settings page all offer bilingual (Chinese and English) support, following the DSH application’s language setting; for remote browsers, the plugin also接管 the read/write channel for language preferences, syncing via standard settings.describe / settings.mutate RPC and settings.yaml.

Newer versions also fix issues like a blank plugin configuration page in remote scenarios, repeated appearance of the welcome popup, and the “settings are unavailable” message on the model page (noted in the README for v0.1.5+, v0.1.6+, and v0.2.6+, respectively).

Installation & Enabling

Prerequisites

  1. DeepSeek Harness is installed and dsh web can run (default port 3080);
  2. The web profile is initialized (auto-initialized on first run of dsh web);
  3. pnpm is in the system PATH (needed by dsh plugin for profile plugin management).

Install the Plugin

NPM install (recommended):

dsh plugin --profile web add @xgone/dsh-remote

Pin a version example:

dsh plugin --profile web add @xgone/dsh-remote@0.1.0

You can also install from Git or a local directory:

dsh plugin --profile web add git@github.com:xgone/dsh-remote.git
dsh plugin --profile web add ~/path/to/dsh-remote

dsh plugin will install the package using pnpm under ~/.dsh/profiles/web/ and automatically append @xgone/dsh-remote to the profile’s dsh.profile.bundles, without needing to manually edit the bundles list.

Confirm Installation & Restart

python3 -c "import json; print(json.load(open('$HOME/.dsh/profiles/web/package.json'))['dsh']['profile']['bundles'])"

Expected output similar to: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app', '@xgone/dsh-remote'].

The web surface disables HMR, so a restart of dsh web is required for changes to take effect:

dsh web

First-Time Administrator Creation

After restarting, open http://127.0.0.1:3080 in the browser:

  1. You’ll see the login page if not logged in;
  2. If no accounts exist, it enters guided mode with the title “Create the first administrator account”;
  3. Enter a username and a password of at least 6 characters, then click create—this is only allowed from the local loopback;
  4. Upon successful creation, you are logged in and a session cookie is issued.

Verify with:

curl http://127.0.0.1:3080/auth/me

It should return a JSON containing fields like authEnabled and authenticated.

Headless Server (Without Browser)

If you cannot complete the setup in a local browser, you can pre-set the first administrator in ~/.dsh/profiles/web/cordis.patch.yml (effective when the account database is empty, idempotent):

- id: remote
  config:
    enabled: true
    bootstrap:
      username: admin
      password: 'replace_with_a_strong_password'

After the first login, it’s recommended to remove the bootstrap section from the configuration; for reverse proxy deployments, trustProxy: true is also often needed (enabled by default).

Uninstall

dsh plugin --profile web remove @xgone/dsh-remote

After restarting dsh web, the gating disappears. $DSH_HOME/auth/store.json will be retained; to remove it completely, delete it manually.

Typical Usage

Binding MFA

After logging in, go to Settings → Login & Account → Two-Factor Authentication (MFA) → Enable Two-Factor Authentication:

  1. Scan the QR code or manually enter the key, and save the 10 one-time backup codes;
  2. Enter the current 6-digit dynamic code in the authenticator for automatic verification and enablement;
  3. Thereafter, login requires password + dynamic code (or backup code).

You can also bind MFA directly on the login page after password verification, following the on-screen guide.

Remote Exposure

After exposing dsh web via nginx, SSH tunnel (ssh -L), Tailscale, or Frp, accessing the same entry URL from a remote browser goes through the login gate first, then allows normal use of workspace selection and API. For HTTPS deployments, it’s recommended to set session.secure to true in cordis.patch.yml.

Key Configuration Items

Edit the config under the remote entry in ~/.dsh/profiles/web/cordis.patch.yml:

- id: remote
  config:
    enabled: true
    session:
      cookieName: dsh_session
      ttlSeconds: 604800
      secure: false
      sameSite: lax
    enforceRoles: true
    adminOnly: true
    trustProxy: true
    mfa:
      enabled: true
      issuer: DeepSeek Harness
      window: 1
      backupCodes: 10
    rateLimit:
      maxAttempts: 5
      windowMs: 900000

Emergency bypass: set enabled: false and restart, or delete $DSH_HOME/auth/store.json to re-bootstrap. If MFA is forgotten, an administrator can disable MFA for that account on the settings page (requires admin password).

Use Cases & Considerations

Suitable for developers who need to securely expose DSH Web to non-local browsers: remote work, intranet penetration, headless deployment on servers without a graphical interface, etc.

The plugin runs with the current dsh process’s permissions; before installation, you should review the GitHub source code and the MIT license to ensure it meets your security policies. Creating the first administrator is restricted to loopback to prevent front-running on the public internet; before public exposure, ensure account creation is complete and consider enabling MFA.

The DSH ecosystem philosophy is “everything is a plugin”; community directories like SkillHub are independent sites with no official affiliation with DeepSeek / High-Flyer. @xgone/dsh-remote is a community-maintained admin-security category plugin, not a built-in component of DSH.

Links

  • Directory page: https://www.skillhub.cn/plugins/xgone/dsh-remote
  • GitHub: https://github.com/xgone/dsh-remote
  • npm: https://www.npmjs.com/package/@xgone/dsh-remote