dsh-auth-lock
English | 中文
   
为 DeepSeek Harness Web 部署提供 Host 端密码认证,统一保护 DSH API、SSE、WebSocket 以及第三方插件注册的服务端路由。
dsh-auth-lock 是一个双端 DSH 插件:Host 入口负责密码验证、Cookie Session 和 WebServer 策略;浏览器入口负责首次设置、登录、修改密码、自动锁定和响应式界面。
> [!IMPORTANT] > 本插件要求 DSH WebServer 提供 webserver/request 与 webserver/upgrade Cordis waterfall。若当前 DSH 版本没有这两个扩展点,Auth Lock 会保持停用,不注册任何认证策略,也不会影响 DSH 正常启动。页面和 Host 日志会明确提示当前没有认证保护,并给出卸载命令 dsh plugin --profile web remove dsh-auth-lock。
功能
- 首次设置默认只允许从 DSH Host 的 loopback 连接完成,防止新实例被远程抢先注册。
- 设置 4–16 位密码,不做复杂度检查,允许纯数字 PIN。
- Node
scrypt密码派生:N=32768、r=8、p=1,随机 128-bit salt。 timingSafeEqual恒定时间 verifier 比较,不保存明文密码。- 随机 256-bit Session Token;Host 内存只保留 token 的 SHA-256 key。
- HttpOnly、SameSite=Strict Cookie;TLS 连接自动启用
Secure。 - 默认 10 分钟无操作自动退出,可配置 1–1440 分钟。
- 24 小时绝对 Session 上限。
- 每个远端地址 15 分钟内最多 8 次密码失败;同一地址的高成本密码派生按队列串行执行。
- 同源
Origin校验和 16 KiB 请求体上限。 - 修改密码时验证原密码,并撤销全部旧 Session。
- 忘记密码时通过 DSH Profile 内的管理员命令重置。
- 桌面、平板和手机响应式登录界面。
- 登录成功后自动重载或返回原始页面,重新建立 API、SSE 和 WebSocket 连接。
- 与移动端、远程控制、配对和其他业务插件解耦;认证策略按 WebServer 路由统一生效。
安全模型
Browser / Mobile / Third-party route
│
▼
webserver/request / upgrade
│
dsh-auth-lock policy
│ │
unauthenticated authenticated
401/302 │
▼
DSH / plugin route handlerAuth Lock 只依赖 DSH WebServer 的通用策略扩展点,不导入或配置其他 UI、远程控制、移动端或配对插件。任何独立插件通过同一个 WebServer 注册的 HTTP、SSE 或 upgrade route,都会自动经过相同认证策略。
兼容性
- Node.js:
^22.19.0 || >=24.0.0 - DSH:认证功能需要包含 WebServer policy waterfalls 的版本或构建;旧版 DSH 可正常启动,但插件保持停用并提示卸载
- 浏览器:支持现代 JavaScript、Cookie 和 CSS
env(safe-area-inset-*) - 平台:macOS、Linux,以及 DSH 支持的其他 Node Host
DeepSeek Harness 仍处于快速演进阶段,插件可能需要随 DSH 的扩展点变化更新。建议安装时锁定 Git commit 或使用明确版本。
安装
从 GitHub 安装
dsh plugin --profile web add github:imchenmin/dsh-auth-lock生产或长期部署建议锁定 commit:
dsh plugin --profile web add github:imchenmin/dsh-auth-lock#COMMIT_SHA仓库直接包含已构建的 lib/ 文件,因此 GitHub 安装不需要执行 prepare,也不需要配置 pnpm allowBuilds。
从 npm 安装
发布到 npm 后:
dsh plugin --profile web add dsh-auth-lock从本地目录安装
dsh plugin --profile web add /absolute/path/to/dsh-auth-lock从 tarball 安装
npm pack
dsh plugin --profile web add ./dsh-auth-lock-0.1.0.tgz验证并启动
dsh --profile web --dump-config
dsh web确认配置中存在:
- id: auth-lock
name: dsh-auth-lock如果页面提示当前 DSH 不兼容,请先继续使用未受 Auth Lock 保护的 DSH,并执行:
dsh plugin --profile web remove dsh-auth-lock然后重启 dsh web。不要把不兼容状态误认为已经受到密码保护。
兼容版本中,重启 dsh web 并在运行 DSH 的电脑上通过 http://127.0.0.1:<port> 打开页面完成首次设置。首次设置成功后,才从手机、隧道或反向代理地址登录。
使用
登录与锁定
- 首次打开:设置 4–16 位密码。
- 后续打开:输入密码登录。
- DSH 设置面板提供独立的访问锁项目,用于管理自动退出时间和密码。
- 右侧紧凑控制栏只保留立即锁定操作。
- 登录后页面会自动重新加载;如果认证前访问的是受保护 HTML 页面,登录后会返回该页面。
修改密码
打开设置 → 访问锁,填写:
1. 当前密码; 2. 新密码; 3. 确认新密码; 4. 点击保存。
修改成功后,Host 会生成新 salt 和 verifier,撤销所有旧 Session,并为当前浏览器签发新的 Cookie。
忘记密码
密码 verifier 不可逆,无法找回原密码。请在运行 DSH 的电脑上执行管理员重置。
先停止 dsh web,然后:
dsh plugin --profile web exec dsh-auth-lock-reset -- --yes重新启动:
dsh web下一次访问会重新进入密码设置流程。
如果配置了自定义状态文件:
dsh plugin --profile web exec dsh-auth-lock-reset -- \
--path /absolute/path/auth-lock.json \
--yes重置命令只删除 Auth Lock 状态文件,不删除 DSH Profile、会话、凭据、项目或其他插件数据。命令不带 --yes 时会拒绝执行。
配置
插件 bundle 插入以下 Cordis row:
- id: auth-lock
name: dsh-auth-lock
config:
language: zh可以在 Profile 的 cordis.patch.yml 中覆盖:
- id: auth-lock
config:
# Auth Lock 界面语言:zh(默认)或 en
language: en
# 自定义 Host 状态文件
path: /absolute/path/auth-lock.json
# TLS 在反向代理终止时,强制添加 Secure Cookie
secureCookie: truelanguage 只支持 zh 和 en,默认值为 zh(中文)。上面的配置只决定首次设置时的默认语言。创建密码后,可以直接在设置 → 访问锁中选择中文或 English 并保存。Auth Lock 会把选择写入状态文件并自动刷新浏览器,使登录页、锁定提示、快捷锁定标签、设置导航名称和独立设置项目一起切换。
默认状态文件:
$DSH_HOME/auth-lock.json如果没有设置 DSH_HOME,默认是:
~/.dsh/auth-lock.json首次设置默认只允许 loopback 请求。对于无法在 Host 浏览器中完成设置的特殊部署,可以在仅首次设置期间使用环境变量:
DSH_AUTH_LOCK_ALLOW_REMOTE_SETUP=1 dsh web设置成功后立即停止该进程,并在不带此变量的情况下重新启动。不要在长期远程部署中保留它。
Host API
| Method | Path | Purpose |
|---|---|---|
GET | /auth-lock/status | 查询配置和登录状态 |
POST | /auth-lock/setup | 首次设置密码 |
POST | /auth-lock/login | 密码登录 |
POST | /auth-lock/logout | 注销当前 Session |
POST | /auth-lock/password | 使用原密码修改密码 |
POST | /auth-lock/settings | 修改自动退出时间 |
所有状态修改请求都要求同源 Origin。API JSON 响应带 Cache-Control: no-store。
公开资源
为了让未登录浏览器能够加载登录 UI,以下启动资源保持公开:
- SPA 根页面
/ /assets/*/plugins/<plugin-id>/client.js/plugins/<plugin-id>/client.js.map- favicon 和 manifest
/auth-lock/*登录接口
其他未认证 HTML 页面会跳转到根登录页,并保留安全的站内返回路径。API 请求返回 401,HTTP upgrade 返回 401。/plugins/events 等动态插件端点不在公开白名单中。
这意味着插件保护 DSH 数据和服务端操作,但不隐藏公开的 JavaScript 与 CSS 源资源。需要隐藏静态资源的部署应在 DSH 前配置带认证的 HTTPS 反向代理。
数据与 Session
状态文件只保存:
{
"version": 1,
"salt": "...",
"verifier": "...",
"idleMinutes": 10
}文件所在目录按 0700 创建,文件按 0600 创建,并通过随机临时文件替换。
登录 Session 只存在于当前 DSH 进程内:
- 重启
dsh web会使所有设备退出; - 修改密码会使所有旧 Session 失效;
- 当前版本不支持集群或共享 Session 存储。
安全边界
- 本插件不加密项目文件、会话、凭据或网络流量。
- 通过 HTTP 远程访问会暴露密码和 Cookie;LAN、Tailscale 出口或公网部署应使用 HTTPS。
- 如果 TLS 在反向代理终止,配置
secureCookie: true。 - 4 位 PIN 的搜索空间很小;虽然有 scrypt 和失败限速,但面向不可信网络时建议使用更长密码。
- 失败限速存储在单进程内,重启后清空。
- 静态应用和插件资源有意公开,以便渲染登录 UI。
- 本项目不是多用户系统,不提供用户名、角色、项目 ACL、OAuth、OIDC 或集群 Session。
安全问题请参阅 [SECURITY.md](SECURITY.md),不要在公开 Issue 中披露可利用细节。
卸载
dsh plugin --profile web remove dsh-auth-lock卸载后可选择手动删除状态文件:
rm "${DSH_HOME:-$HOME/.dsh}/auth-lock.json"开发
git clone https://github.com/imchenmin/dsh-auth-lock.git
cd dsh-auth-lock
npm test
npm run check发布前检查 tarball:
npm pack --dry-run项目使用预构建的原生 ESM Host 与 Client bundle,不需要运行时依赖。
贡献
欢迎提交 Issue 和 Pull Request。开发与测试约定见 [CONTRIBUTING.md](CONTRIBUTING.md)。
License
[MIT](LICENSE)
