dsh-auth-gate
English | 简体中文
A login door for your DeepSeek Harness (dsh) web instance. Put it in front of a public dsh deployment and nobody can reach your agents, your chat sessions, or your LLM credentials without signing in first.
What it does
Everything needs a login. Every page, API call, and WebSocket connection is checked. Visitors without a valid session are sent to a simple login page (or rejected with
401for API/script requests).Two ways to sign in (pick one in the configuration):
- Password (recommended): each admin gets a username and password.
- Token: one shared secret token for the whole instance.
Works for browsers and scripts. Browsers use the login page; scripts and curl can pass
Authorization: Bearer <token>and skip the page entirely.Safe by default. Passwords are stored hashed, logins are rate-limited (repeated wrong attempts temporarily lock the address), session cookies are secure, and any missing or broken configuration blocks access instead of silently opening the door.
A small command-line tool for managing users:
dsh-auth user add admin --password-stdin # add a user dsh-auth user list # list users dsh-auth user disable admin # block a user's future logins
Quick start
# 1. Install the plugin from npm into your dsh profile.
# Since 0.4.1 the package declares a `dsh.bundle` manifest, so `dsh plugin add`
# also registers the mount (dsh.profile.bundles) automatically:
dsh plugin --profile web add dsh-auth-gate
# 2. Create an admin account
printf '%s\n' 'choose-a-strong-password' | dsh-auth user add admin --password-stdin
# 3. Turn on password login: override the plugin config in $DSH_HOME/cordis.patch.yml
# (a ready-to-use config-override template ships in deploy/cordis.patch.yml;
# see Configuration below — the mount itself needs no manual patch row)
# 4. Restart dsh. Open your site — you will be asked to sign in.
See it in action
Visitors without a session are sent to the login page:

After signing in, they land on your instance:

Configuration
The bundle mount (id dsh-auth-gate, inserted by dsh plugin add) uses the
default config: mode: "token" backed by the DSH_AUTH_TOKEN environment
variable. To change it, override the config in $DSH_HOME/cordis.patch.yml
(or the profile's cordis.patch.yml — a ready-to-use override template ships
in deploy/cordis.patch.yml). The override targets the mounted row by id
(no insert — adding one would double-mount the plugin):
- id: dsh-auth-gate
config:
mode: "password" # "password" (recommended) or "token"
cookieSecure: true # keep true when you use https
| Option | Default | What it does |
|---|---|---|
mode |
"token" |
"password" = username/password login; "token" = one shared secret |
sessionTtl |
604800 |
How long a login lasts (seconds) before you must sign in again |
cookieName |
dsh_auth |
Name of the session cookie (rarely needs changing) |
tokenRef |
"DSH_AUTH_TOKEN" |
Token mode only: which environment variable holds the shared secret |
cookieSecure |
true |
Set to false only if you are testing over plain http |
usersFile |
"" |
Password mode: where your user list lives. Defaults to $DSH_HOME/auth/users.yaml |
Deployment
- Reverse-proxy deployment guide — Caddy/nginx
setups, the browser-trust fence gotcha (Settings-page
403s behind a proxy, and why auth alone doesn't fix them), and the recommended semi-shell topology. docs/deployment.md— ops checklist, acceptance steps (A–I) and troubleshooting. Chinese version:docs/deployment_zh.md.
Requirements
- Node ≥ 22.19 and pnpm on the server.
- The dsh
webprofile running (dsh --profile web). - If
cookieSecureistrue, your site must be served over https (browsers refuse secure cookies on plain http).
License
Notes & limitations
- Disabling a user only stops new logins; already-signed-in sessions stay valid until they expire.
- Login rate limiting resets when the server restarts.
- Behind a reverse proxy, rate limiting counts by the proxy's address.
- There is no logout button in the dsh interface yet — visit
/auth/logout?next=/to sign out. - The plugin only protects dsh's web surface. It is not a replacement for
server-level security: keep the server OS user locked down and the config
files private (
.credentials.yamlandauth/users.yamlare created with0600permissions).
No comments yet. Be the first to write one.