DeepSeek Harness Web Authentication Plugin
dsh-plugin-auth-webserver
Native Web authentication bundle for DeepSeek Harness (DSH).
Give your self-hosted deployment a DSH-styled web login page, cookie sessions, Basic Auth fallback, a Web UI settings card, and a Web Crypto polyfill — in English and Simplified Chinese.
简体中文 | English
Features
- DSH-themed web login page
- Replaces native browser authentication popups with a dark, glassmorphism login interface matching DeepSeek Harness's design system.
- Bilingual (English / Simplified Chinese, following the browser's language), password show/hide toggle, error animations, Enter-to-submit, responsive on mobile and desktop.
- HMAC cookie sessions and logout
- Issues 30-day cryptographically signed HMAC session tokens on login.
- Dedicated
/api/auth.logout endpoint and a Web UI logout button.
- Web GUI settings card
- Live configuration in the DSH Web UI (Settings -> Plugins -> Web authentication).
- Hot-updates credentials in memory instantly and persists them to a plugin-owned state file under
$DSH_HOME/plugins/dsh-plugin-auth-webserver/, so they survive restarts without touching your config layers.
- Dual-mode authentication and WebSocket protection
- Prefers web form / cookie sessions while staying backward-compatible with
HTTP Basic Auth for CLI tools, curl, and automated API clients.
- Full authentication coverage for both HTTP routes and WebSocket (
upgrade) channels.
- Remote IP privileged RPC trust delegation
- Normalizes request
Host and Origin headers for authenticated sessions, eliminating HTTP 403 errors when accessing privileged RPC endpoints via a public IP.
- The rewrite never runs while authentication is disabled, so the stock loopback
Host fence keeps defending against DNS rebinding (see Security).
- Brute-force throttling and credential hardening
- Per-IP failed-login lockout (5 failures, doubling backoff) on the login endpoint and Basic Auth path, constant-time credential compares,
no-store/nosniff on auth responses, and no password ever echoed back over the wire.
- Web Crypto UUID auto-polyfill
- Injects a safe UUID generator into the HTML
<head> for non-HTTPS and direct-IP environments, preventing client-side crashes.
Security
This plugin is the security boundary of a self-hosted deployment, so its own
exposure is hardened accordingly (as of 0.4.0, following QVD-2026-57410 - the
unauthenticated RCE in DeepSeek Harness 0.1.1-rc.2, CVSS 9.8, whose root cause
is that the stock /api trust fence decides "loopback" from the
client-controlled Host header and is not an authentication layer):
- Credentials run before the
/api fence. Every request - HTTP and
WebSocket - must pass the cookie/Basic credential gate before reaching any
privileged RPC. That is the advisory's architecture-level fix
(authentication independent of the Host header) deployed at the webserver
layer.
- Secure by default on non-loopback bindings. Booting with an empty
password while listening on
0.0.0.0 generates a strong random password
(persisted to the plugin state file, printed once to the log) instead of
serving an unauthenticated privileged RPC surface; clearing the password
from the settings card is refused on non-loopback bindings.
- Host/Origin normalization never launders unauthenticated requests. The
rewrite only vouches for sessions that passed the credential gate; with no
password in force it is skipped entirely, so a DNS-rebound page carrying
Host: attacker.example is still rejected by the stock fence.
- Brute-force resistance. Five consecutive failed logins from one IP lock
it out with a doubling backoff (15s base, 15min cap), on both the login
endpoint and the Basic Auth path; all credential compares are constant-time.
- No secret echo.
/api/auth.get returns only the username, realm, and
whether protection is enabled - never the password.
Recommended deployment posture: use a long unique password; put HTTPS with a
Host-validating reverse proxy in front for public access; keep the bind on
127.0.0.1 for single-user local use; upgrade DeepSeek Harness once a patched
release ships.
Installation
Install the bundle into a profile with dsh plugin:
# From a git host (pin a commit so later pushes cannot change what runs):
dsh plugin --profile web add github:kolawong/dsh-plugin-auth-webserver#<commit-sha>
# Or from a tarball / npm registry once published:
dsh plugin --profile web add ./dsh-plugin-auth-webserver-0.4.0.tgz
dsh plugin --profile web add dsh-plugin-auth-webserver
The package declares dsh.bundle, so dsh plugin appends it to the
profile's bundle list automatically; its patch disables the stock
webserver row and inserts the auth-gated server. Then boot:
dsh --profile web
Open http://your-server-ip:3080 to see the login page.
Configuration
Every option has a default; override the webserver-auth row in your
profile's own patch ($DSH_HOME/profiles/web/cordis.patch.yml), which is
applied after every bundle layer:
- id: webserver-auth
config:
host: '0.0.0.0'
port: 3080
username: 'admin'
password: 'your_secure_password'
Changes made in the Web UI settings card apply immediately and are stored
in $DSH_HOME/plugins/dsh-plugin-auth-webserver/state.json (mode 0600).
Environment variables DSH_AUTH_USER and DSH_AUTH_PASS override both the
config and the saved state.
| Option | Type | Default | Description |
|---|
host | string | '0.0.0.0' | Listening interface (0.0.0.0 or 127.0.0.1). |
port | number | 3080 | HTTP/WebSocket listen port. |
username | string | 'admin' | Authentication username. |
password | string | '' | Authentication password. Empty disables authentication, but only on 127.0.0.1; on 0.0.0.0 a random password is generated at boot. |
realm | string | 'DeepSeek Harness Authentication' | Realm string used for fallback Basic Auth. |
API endpoints
POST /api/auth.login — Authenticate and receive a session cookie ({ username, password }).
POST /api/auth.logout — Invalidate the current session and clear the cookie.
GET /api/auth.get — Retrieve the effective username, realm, and auth status (requires authentication; never returns the password).
POST /api/auth.update — Live-update credentials and persist them (requires authentication; refuses to clear the password on non-loopback bindings).
License
MIT License © 2026 kola