Introduction

DSH (DeepSeek Harness) adopts a plugin-based architecture, and its Web GUI provides powerful visual management capabilities. However, when exposing DSH Web on a LAN or the public internet, directly exposing the port bypasses access control at the SSH layer, leaving an Agent with Bash execution capabilities directly at risk. The lack of a built-in HTTP authentication mechanism leaves the Web UI running “naked” in reverse-proxy scenarios.

Below is an introduction to dsh-web-auth, a plugin that adds password-based access authentication and reverse-proxy-friendly configuration to DSH Web. It implements site-wide access control through a login page and HttpOnly signed cookies, and handles WebSocket upgrades and cookie security in reverse-proxy environments.

Plugin Overview

  • Name: fonlan/dsh-web-auth
  • Purpose: DSH Web plugin that provides password-gate authentication (login page + HttpOnly signed cookie) for exposing DSH Web behind a reverse proxy.
  • Maintainer: fonlan
  • Category: admin-security
  • License: MIT

Core Features

By using server-side interception and client-side cookie issuance, the plugin provides the following capabilities:

  1. Login page and cookie management: Provides a login page, signs cookies with HMAC-SHA256, and applies a 7-day sliding renewal. Browsers automatically send the cookie, covering HTTP, WebSocket, SSE, and static resources.
  2. Initial setup and password change: Displays a setup form if no password is configured. Supports changing the password in the GUI; a password change rotates the signing key and forces all users to log out.
  3. Brute-force protection: IP-based rate limiting; consecutive failures trigger exponential backoff, with cumulative limits within 15 minutes.
  4. Reverse-proxy compatibility: Cookies are automatically marked Secure (following x-forwarded-proto), and rate limiting trusts the reverse proxy’s X-Forwarded-For.
  5. Listening address switching: Supports one-click switching of the listening address (127.0.0.1 <-> 0.0.0.0) in the settings card, taking effect immediately without restarting the process.
  6. Remote settings unlock (optional): When enabled via configuration, allows logged-in users to access the settings UI under a reverse-proxy domain (model page, plugin configuration, etc.). Disabled by default.
  7. Startup token takeover: The plugin takes over DSH’s startup-token logic, so users do not need to manually visit ?token= links; after login, the DSH session is automatically renewed.
  8. Password storage: Stored using salted scrypt hashes, with file permissions 0600 and no plaintext on disk.

Installation and Activation

Installing the plugin requires DSH version 0.1.5 or later.

  1. Install it from the command line:
dsh plugin --profile web add @fonlan/dsh-web-auth
  1. Restart the DSH Web process to activate the plugin.

  2. Set the initial password: After restarting, open the DSH Web UI; the system automatically redirects to the login page. If no password has been set, the page will display a “Set Access Password” form. Enter a new password with ≥8 characters and confirm it to complete initialization.

Typical Usage

Change Password

After logging in, go to Settings → Plugins → Plugin Configuration → Access Authentication and click Change Password. You must enter the old password. Once the new password has been set successfully, the old sessions become immediately invalid.

Switch Listening Address

At the bottom of the “Access Authentication” card, you can switch the listening address.
* 127.0.0.1: Accessible only from the local machine.
* 0.0.0.0: Listen on all network interfaces; accessible from the LAN.
Switching triggers an HMR hot reload of the WebServer; WebSocket connections disconnect briefly and then reconnect automatically.

Enable Remote Settings Unlock

By default, when accessed through a reverse-proxy domain, the settings page returns an error (because the dsh client treats the domain as non-loopback). To enable it, add the following configuration to the profile’s cordis.patch.yml:

- id: web-auth
  config:
    unlockRemoteSettings: true

Behavior Details

The plugin handles different request categories as follows:

Scenario Behavior
Unauthenticated page access 302 redirect to /login?next=original path
Unauthenticated API access 401 JSON response
DSH startup-token exchange Allow only plugin-server-side mint re-entry or requests holding a plugin session; forward the dsh-auth Set-Cookie in the response to the browser
Browser directly opens an old token URL 302 redirect to /login and drop the token parameter (the old token becomes invalid after restart)
Logged-in access under a reverse-proxy domain The request is rewritten as coming from a loopback source, and the plugin guardrail no longer intercepts it
Settings page under a reverse-proxy domain Errors by default (settings are unavailable); usable after enabling unlockRemoteSettings
Cross-site request 403 rejection
Unauthenticated WebSocket upgrade 401 handshake rejection
Session expired Redirect back to the login page; if the remaining time is < 24h, automatically refresh and renew
Password change Rotate the key and log out all users
Switch listening address Write to settings and trigger HMR to rebind the webserver

Security Model and Risks

When using this plugin, pay special attention to the following security points:

  1. Authentication is access control, not a security boundary: DSH Agent has Bash execution capabilities; even with password protection, do not treat the deployment as impregnable.
  2. Initial password window: Before a password is set, anyone can access the login page and claim the first password. It is recommended to set the password immediately after installation, or complete initial password setup via SSH port forwarding before exposing the service on the network.
  3. Stateless sessions: The server cannot revoke individual sessions; if a password leaks, change the password to rotate the signing key.
  4. Storage location: The password hash and key are stored in $DSH_HOME/web-auth/ with permissions 0600.
  5. Rate-limit limitations: Rate limiting is process-memory level; in multi-instance deployments, each instance maintains independent limits.

Development

The plugin’s source code and build workflow are as follows:

pnpm install
npm run build      # host: tsc;client: esbuild
npm run typecheck
npm run test       # 单元 + 集成测试

Summary

dsh-web-auth provides DSH Web with necessary authentication and reverse-proxy support through a lightweight plugin. It addresses the question of “how to safely expose a Web interface” and, through strict session management, brute-force protection, and transparent startup-token handling, reduces the risks of directly exposing the Web UI.