给 DeepSeek Harnessdsh的网页版加一道登录关卡。把它放在公网上
42.3/100
综合分
18
GitHub 星标
1,399
npm 周下载
—/5
用户评分
数据截至 2026/10/27 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-auth-gatenpm 源 · dsh-auth-gate 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:需留意
是什么
dsh 原生插件 · security
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
⚠︎ 实装验证未通过(runtime_smoke_failed · 2026/10/31) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-auth-gate @ 0.18.0
✓Node 引擎要求 >=22.19.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/30 15:48:51
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件发起外部网络请求
查看扫描证据(共 7 处,展示前 7 条)
- 发起网络请求lib/client.js:714
return fetch(PASSWORD_TARGET, { - 发起网络请求lib/client.js:1165
const res = await fetch(USERS_TARGET, { - 发起网络请求lib/client.js:1223
return fetch(RESET_TARGET, { - 发起网络请求lib/client.js:1740
fetch(STATUS_TARGET, { - 发起网络请求lib/client.js:1866
fetch(STATUS_PATH).then((res) => res.json()).then((body) => { - 发起网络请求lib/client.js:1979
fetch(STATUS_PATH).then((res) => res.json()).then((body) => { - 读取本地文件lib/host/shared/skill/skill-install.js:41
await stat(dir);
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-storage@deepseek-ai/dsh-storage-domain@deepseek-ai/dsh-storage-json给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
6 张 · 点击查看大图功能亮点
- 账号密码或共享令牌登录
- 可选TOTP两步验证
- 登录限速与自助改密
最近更新
在 GitHub 查看全部 →v0.18.02026-10-26
· 0.18.0 (2026-10-26)
· Features
· first-run launch-token onboarding for unconfigured instances (#117) (f73a13e)
原文(未汉化)
v0.17.42026-10-16
· 0.17.4(2026-10-16)
· 代码重构
· 把两部分都按 FSD 布局,并让它们共用 /auth 契约(#113)(dbc9b04)
v0.17.32026-10-13
· 0.17.3 (2026-10-13)
· Bug Fixes
· gate: bounce cross-site navigations so dsh's Strict cookie is sent (#111) (ea84e6b)
原文(未汉化)
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-auth-gate
给 DeepSeek Harness(dsh)的网页版加一道登录关卡。把它放在公网上运行的 dsh 实例前面,任何人在登录之前都碰不到你的 agent、聊天会话和 LLM 凭据。
在 dsh 官方推出认证功能之前,本仓库会一直维护。 dsh 目前还没有内置登录,这个仓库就是用来补上这个缺口的:我们会跟进 dsh 的新版本(挂载点变化、兼容的版本范围、Linux 与 Windows 双平台 CI)、修复升级引入的问题,并照常发版。等官方认证落地,我们会给出迁移方案,同时继续支持大家仍在使用的
dsh 版本,不会让任何人留在一个无人维护的 fork 上。
目录
- 它能做什么
- 它不做什么
- 市场的「会用你的密钥」徽章
- 快速开始
- 首次运行
- 效果预览
- 配置
- 命令行工具
- 管理工具:列出用户与重置密码
- 内置配置技能
- 故障排查
- 部署
- 认证本地代理(可选)
- 环境要求
- 注意事项与局限
- 开发
- 许可证
它能做什么
- 所有请求都要先登录。 每个页面、每个 API 调用、每条 WebSocket 连接都会检查登录态。没有有效会话的访客会被引导到登录页;API 和脚本请求直接返回 401。
展开完整文档(README 剩余 1 节)
dsh-auth-gate
给 DeepSeek Harness(dsh)的网页版加一道登录关卡。把它放在公网上运行的 dsh 实例前面,任何人在登录之前都碰不到你的 agent、聊天会话和 LLM 凭据。
在 dsh 官方推出认证功能之前,本仓库会一直维护。 dsh 目前还没有内置登录,这个仓库就是用来补上这个缺口的:我们会跟进 dsh 的新版本(挂载点变化、兼容的版本范围、Linux 与 Windows 双平台 CI)、修复升级引入的问题,并照常发版。等官方认证落地,我们会给出迁移方案,同时继续支持大家仍在使用的
dsh 版本,不会让任何人留在一个无人维护的 fork 上。
目录
- 它能做什么
- 它不做什么
- 市场的「会用你的密钥」徽章
- 快速开始
- 首次运行
- 效果预览
- 配置
- 命令行工具
- 管理工具:列出用户与重置密码
- 内置配置技能
- 故障排查
- 部署
- 认证本地代理(可选)
- 环境要求
- 注意事项与局限
- 开发
- 许可证
它能做什么
- 所有请求都要先登录。 每个页面、每个 API 调用、每条 WebSocket 连接都会检查登录态。没有有效会话的访客会被引导到登录页;API 和脚本请求直接返回 401。唯一的例外是 GET /manifest.webmanifest:浏览器请求 Web App Manifest 时不带凭据,所以只开放这一条路径,响应里也只有应用名、图标和显示模式。
- 两种登录方式(配置里二选一):
- 密码(推荐):每个管理员使用自己的用户名和密码。
- 令牌:整个实例共用一个密钥。
- 浏览器和脚本都能用。 浏览器走登录页;脚本和 curl 带上 Authorization: Bearer <token> 就能跳过登录页。
- 管理工具。 密码模式下,管理员可以在设置面板的「账号安全」分区里,或通过 HTTP (GET /auth/users、POST /auth/users/password)列出用户、重置他人口令;重置会吊销该用户已有的全部会话,并让他在下次登录时先设置新口令,之后才能访问其他任何内容。只有处于正式会话的 admin 才看得到面板里的管理块;管理面不允许重置自己(自己的口令用上方自助表单,忘记了自己的口令才走 CLI)。
- 可选的两步验证(TOTP)。 密码模式下,账号里添加了 TOTP 密钥的用户登录时,除了密码还要输入验证器应用生成的 6 位验证码(遵循 RFC 6238;配置有 off/optional/required 三档)。
- 默认配置就是安全的。 密码以哈希形式保存;登录有限速,密码连续输错会临时锁定来源地址;会话 cookie 带有安全属性;配置缺失或损坏时直接拒绝访问,而不是悄悄放行。用户名或密码错误时,登录卡片会重新显示,并带上 Invalid username or password.:用户名保留,密码需要重新输入。
触发锁定后(HTTP 429 + retry-after),同一张登录卡片会显示需要等待的秒数,并提示该限制只针对当前网络;剩余尝试次数刻意不显示;浏览器启用了 JavaScript 时,刷新页面也不会再额外消耗一次尝试机会。
它不做什么
先把边界讲清楚,方便你在安装前判断风险(完整清单和背后的机制见 docs/deployed/known-limitations_zh.md):
- 不等于服务器级安全。 操作系统账号和配置文件仍需要你自己看管(auth/users.yaml 和 .credentials.yaml 生成时权限即为 0600);本插件只守住 dsh 的 Web 入口。
- 不是每个改密码入口都会让会话失效。 dsh-auth user disable 会阻止该用户今后登录,并吊销其已签发的会话(默认 5 秒内生效,见 revokeSweepMs);设置面板里的自助改密会吊销该用户的全部会话,管理员在面板里重置他人口令同样如此;CLI 的 dsh-auth user passwd 只重写存储的密码哈希。
- 不能替代 HTTPS。 配置了 cookieSecure: true,站点就必须通过 https 提供服务。
- 不是完整的身份提供方(IdP)。 没有 OAuth/OIDC,没有自助注册,也没有邮件重置;用户一律由管理员通过 CLI 创建和管理。
市场的「会用你的密钥」徽章
插件市场的条目会扫描你会安装的那个包,把里面碰到的能力列出来。本插件扫出来的结果是 credentials(会用你的密钥)、network、fs-read、fs-write 和 env,另加一句红线: _读凭据的同时还能联网_。这是披露,不是判决;对本插件来说它是准确的。下面说明它对应代码里的什么。
- 只有一处读凭据,而且只在令牌模式下发生。 apply() 只在 mode: "token" 时构造令牌解析器(src/index.ts);密码模式完全不碰凭据服务。令牌模式下,门禁通过 src/token-resolver.ts 里的 credentials.resolve(config.tokenRef) 解析共享密钥,而 tokenRef(默认 DSH_AUTH_TOKEN)是插件唯一会去要的引用;它不会列出、遍历或读取其他凭据。
- 凭据服务是 harness 自己的一层,取值顺序为 $DSH_HOME/.credentials.yaml(创建时权限即为 0600)、进程环境变量、.env 文件。服务缺失或引用解析不出来时,门禁会拒绝所有请求,而不是放行。
- 联网能力来自插件自身的流量:浏览器请求插件自己的端点(登录、用户管理、重置口令),以及可选的认证本地代理。数据不会发往其他地方。
- 静态扫描说不了的事:它能证明某个能力存在,证明不了某个能力不存在,也读不出意图。
如果你希望实例完全不读凭据,用密码模式即可。
快速开始
装上插件、重启 dsh,然后打开 dsh 启动时打印的那条链接。全新安装的实例还没有任何配置,所以这条链接会直接进入首次配置向导:整个过程不需要开 shell,也不需要改配置文件。
1. 从 npm 装进你的 dsh profile。
自 0.4.1 起,包里声明了 dsh.bundle manifest,dsh plugin add 会顺带自动注册挂载(dsh.profile.bundles),不需要再手动添加挂载行:
dsh plugin --profile web add dsh-auth-gate
2. 重启 dsh,然后打开它启动时打印的链接(http://<host>:<port>/?token=<launch token>)。
dsh --profile web
向导给出的选项跟随当前模式:token 模式(出厂默认)生成并保存共享访问令牌,password 模式创建第一个管理员。新令牌只在结果页显示一次,点一下就能继续进入 dsh。从下次访问起,那条启动链接又只是一条普通 URL:在登录页用刚设好的令牌或密码登录即可。其余的事(加用户、开 TOTP、改 mode)仍然在 shell 里做:见 首次运行、配置 和 命令行工具。
首次运行
启动链接会不会打开向导,每次请求都会重新判一次,判据只有一个:这个实例配置好了没有?
- 默认模式是 mode: "token"。 没有 DSH_AUTH_TOKEN 时,未配置的 token 模式实例会拒绝所有人,所以启动链接是唯一的入口。只有读取成功且值为空才算未配置;credentials 服务缺失或读取抛错,一律按已配置处理,不会打开向导。password 模式在 users.yaml 缺失或零用户时同理。
- ?token= 是什么。 它是 dsh 自己的启动令牌,dsh 每次启动打印一次,只在这个进程活着的时候有效。
插件把它当成「你能读服务器控制台」的凭证,随后签一张 bootstrap 会话:最长 1 小时,除了插件自己的 /auth/ 页面什么都打不开。
- 向导能改什么。 它生成并保存共享令牌(token 模式)或创建第一个管理员(password 模式),两者一旦存在,窗口立刻关闭。它改不了 mode、totp、cookieSecure、sessionTtl 和 proxy:这些要改 $DSH_HOME/cordis.patch.yml 再重启 dsh。
- 之后启动链接会怎样。 它不再放你进来,而且要走两跳:门先把请求转到 /auth/bootstrap?token=...,端点判定实例已配置,再回 302 /auth/login?next=%2F。两跳都不下发 cookie、都不放行,所以启动令牌不是第二把钥匙。
- 怎么再打开向导。 删掉已保存的令牌(或者让 users.yaml 没有用户),然后重启 dsh。如果 credentials 服务返回的是缓存值,正是这次重启让它看到变化。
效果预览
本节的截图统一使用英文界面:插件自己的面板跟随 GUI 语言,服务端渲染的页面在任何语言下都是英文,两版 README 因此共用同一套图。
未登录的访客会先看到登录页(登录卡片由插件在服务端渲染,文案固定为英文,与 GUI 语言无关):
登录页
账号启用了 TOTP 两步验证时,登录还有第二步:输入验证器应用里的 6 位验证码(先密码,后验证码):
两步验证码页
登录后进入你的实例:
dsh 实例
在 dsh 0.1.2-alpha 及更高版本上(这些版本的页面带有 launch token 校验),登录会自动跨过这道校验:登录跳转会先经过一次相对地址 /?token=… 换取 dsh cookie,然后进入 /(细节见 docs/implemented/impl-launch-token-bridge_zh.md)。
设置面板里有一个醒目的「Sign out」(退出登录)按钮,位置在Settings → General (设置 → 通用设置)页最后一行设置项的下方。它是居中、危险色的实心按钮(16px 门形图标加本地化文字,配色使用主题 token,深浅色自适应);文案跟随 GUI 语言切换,用的就是设置页语言切换那套机制。点击后执行的仍是原有的原生登出流程 POST /auth/logout?next=/。
已登录的用户还可以在设置面板的「Account security」(账号安全)分区里自助改密码(仅密码模式):需要填写当前密码和两次新密码,账号绑定了 TOTP 时再加一次验证码。面板标题旁的图标是本插件自己设计的(16px 描边风格的盾牌加钥匙孔)。
设置导航里那一枚图标同样来自本插件:宿主目前没有给单个设置分区配图标的接口(settings.section 只有 id/order/label 三个字段,导航图标由宿主硬编码的 navIcon(id) 决定,第三方分区一律回退到默认齿轮),所以插件用一层临时 DOM 垫片(stopgap)只替换自己那一行,匹配不到时静默退回齿轮。等 dsh 官方支持 icon 选项,这层垫片和它的代码会整体删除(迁移条件见 ADR D24.1)。
设置导航里的「账号安全」行
管理员账号下的「账号安全」面板:上面是改密表单,下面紧跟用户管理块
面板提交到 POST /auth/password(字段为 current / password / code,form-urlencoded 编码)。
修改成功后,该用户的全部会话都会被吊销,包括发起这次改密的那条会话;客户端会立即把用户带回登录页并附上原因,登录页会说明为什么被登出(成功提示面板只在浏览器或运行环境拒绝跳转时才会留在屏幕上,上面的「Sign in again」(重新登录)按钮是那时的退路):
带原因的登录页
新密码至少 14 位、须同时包含四类字符,且不能与当前密码相同。启用 TOTP 后,当前 30 秒窗口内已经用过的验证码会视为重放并拒绝,需要等下一个验证码。
处于正式会话的管理员,还会在上方表单下面看到用户管理块(上面那张面板截图里就能看到):一张只读列表(用户名、角色,以及互斥的「已禁用 / 需改密 / 正常」状态徽标和两步验证徽标,本人行标「本人 / You」),外加一条针对他人的重置表单。重置会让目标用户在下次登录时被要求改密,并吊销该用户已有的全部会话;发起重置的管理员自己的会话不受影响。管理员自己开启了 TOTP 时,重置还需要填写一枚当前验证码。该模块只在 role === "admin" 且会话为正式会话(非强制改密受限会话)时渲染,非 admin 客户端 根本不会请求用户列表。不允许重置自己:服务端会拒绝,下拉也排除本人;管理员若忘记自己的口令,只能在服务器上用 dsh-auth user passwd <name> 重置。
用户管理块里的重置成功:绿色确认文案、目标用户已标记「需改密」、字段全部清空
配置
bundle 挂载行(id 为 dsh-auth-gate,由 dsh plugin add 自动插入)使用默认配置:mode: "token",共享密钥来自环境变量 DSH_AUTH_TOKEN。要修改配置,在 $DSH_HOME/cordis.patch.yml(或 profile 目录下的 cordis.patch.yml)里按 id 覆盖即可;仓库自带可直接使用的覆盖模板 deploy/cordis.patch.yml。覆盖条目按 id 定位已经挂载的那一行,不要再写 insert (否则插件会被挂载两次):
- id: dsh-auth-gate
config:
mode: "password" # "password"(推荐)或 "token" totp: "optional" # "off"(默认)、"optional" 或 "required" cookieSecure: true # 使用 https 时保持 true
| 选项 | 默认值 | 作用 |
| mode | "token" | "password" 为用户名密码登录;"token" 为全实例共用一个密钥 |
| totp | "off" | 仅密码模式。"optional":绑定了 TOTP 密钥的用户登录时需要密码加验证码;"required":所有用户都必须绑定密钥(没有密钥的用户在密码阶段就得到统一的 401,响应体与密码错误相同,避免暴露账号是否存在) |
| sessionTtl | 604800 | 一次登录的有效时长(秒),到期后需要重新登录 |
| cookieName | dsh_auth | 会话 cookie 的名称(一般不需要修改) |
| tokenRef | "DSH_AUTH_TOKEN" | 仅令牌模式:共享密钥存放在哪个环境变量里 |
| cookieSecure | true | 只在纯 http 测试环境下设为 false |
| usersFile | "" | 密码模式:用户列表文件的位置,默认 $DSH_HOME/auth/users.yaml |
| publicHost | "" | 登录页身份区显示的域名(用于防钓鱼,让用户确认"这是哪个实例")。留空则使用请求头里的 Host;反向代理改写了 Host 时必须显式配置(例如 Caddy 的 header_up Host 127.0.0.1:3080),否则卡片上显示的是回环地址而不是你的公网域名。自 D25 起,它还决定管理与改密端点能否校验 Origin 头:publicHost 留空时这些端点只接受 Sec-Fetch-Site: same-origin,生产部署应当配置它;TLS 终止在反代后面时请写成带 scheme 的形式(https://host) |
| revokeSweepMs | 5000 | 密码模式:被 dsh-auth user disable 禁用的用户,其已签发的会话会在多长时间(毫秒)内被吊销。0 表示不清理已有会话(此时禁用只拦新登录) |
| clientIpHeader | "" | 限速用的客户端真实 IP 请求头(x-forwarded-for;Cloudflare 后面可用 cf-connecting-ip)。留空表示完全不读取请求头。只有当请求的对端落在 trustedProxyCidrs 内时才会读取;不配置时,同机反代会造成所有客户端共用一个锁定桶(issue #74) |
| trustedProxyCidrs | ["127.0.0.0/8", "::1/128"] | 哪些对端有权提供 clientIpHeader(默认只信任回环;没有地址的对端,例如 Unix socket,视为本地)。无效条目会被丢弃并记 error 日志,信任范围收窄为回环;显式写成 [] 表示谁都不信任;0.0.0.0/0 和 ::/0 一律拒绝 |
| logoutOrder | 1000 | 「退出登录」按钮在 设置 → 通用设置 页里的排序值(数值越大越靠下)。如果其他插件注册了更大的值,可以调大这个数 |
给用户启用 TOTP:运行 dsh-auth user totp enable <name>,把打印出的密钥录入验证器应用,或扫描 otpauth:// URI 二维码(Google Authenticator、1Password 等)。验证码每 30 秒变化一次,前一个和后一个窗口内的码也接受(容忍时钟漂移)。
命令行工具
dsh-auth 用于在命令行管理用户:
dsh-auth user add admin --password-stdin # 添加用户(加 --admin 直接创建管理员) dsh-auth user list # 列出用户 dsh-auth user passwd admin # 修改密码(需要输入两次;不提供 --password 参数) dsh-auth user role admin user # 授予/撤销管理员角色:user role <name> <admin|user> dsh-auth user disable admin # 阻止该用户今后登录,并吊销其已登录的会话 dsh-auth user enable admin # 重新启用被禁用的用户(只重置口令仍登不进来) dsh-auth user totp enable admin # 生成 TOTP 密钥(打印 otpauth:// URI) dsh-auth user totp disable admin # 删除 TOTP 密钥
全局安装后,dsh-auth 会直接出现在 PATH 里;通过 dsh plugin add 安装时,可执行文件位于 profile 内,需要经由 profile 调用,详见快速开始。
dsh-auth user passwd 只重写存储的密码哈希,不会吊销该用户已经登录的会话。需要让会话立即失效时,请使用设置面板里的自助改密;dsh-auth user disable 也能阻止今后登录,但已签发的会话要等周期扫描(revokeSweepMs,默认约 5 秒)才会被吊销。
管理工具:列出用户与重置密码
密码模式下,管理员可以在设置面板的「账号安全」分区里列出用户、重置他人口令,也可以在脚本里走 HTTP(/auth/users 是字段白名单列表,/auth/users/password 是重置)。两条通路行为一致;所有已认证的状态变更 POST 都会校验 Origin,所以脚本必须显式带上它(没有豁免):
列出用户(jar 里是管理员会话 cookie)。
curl -s -H "Origin: https://dsh.example.com" -b jar https://dsh.example.com/auth/users
重置某人的口令。只有「你自己」的账号启用了 TOTP 时才需要 code。
curl -s -H "Origin: https://dsh.example.com" -b jar \
-d "target=alice&password=<新口令>&confirm=<新口令>&code=<你自己的验证码>" \
https://dsh.example.com/auth/users/password
缺少 Origin、或 Origin 与实例不匹配的请求一律以 403 拒绝(fail-closed);唯一被接受的另一个信号是浏览器自己发的 Sec-Fetch-Site: same-origin。反向代理改写了 Host 时必须配置 publicHost:否则服务端推导不出自己的对外来源,改密与重置端点就只认 Sec-Fetch-Site: same-origin,而上面的命令行调用并不会带它。TLS 终止在反代后面时要把 publicHost 写成带 scheme 的形式(https://dsh.example.com):只写 host:port 时,scheme 由连接本身是否为 TLS 推导,反代到插件这一段若是明文,脚本走 Origin 通道就会 403(浏览器不受影响)。
重置会把目标账号标记为「必须修改口令」,并吊销该用户已有的全部会话(发起重置的管理员自己的会话不受影响)。目标用户下次登录会拿到受限会话(15 分钟、不续期):它只能到达插件自己的改密页 GET /auth/password,其他一律进不去,包括宿主界面。该页面由服务端渲染,没有 JavaScript 也能用(零外链、无脚本);提交时仍然要求当前口令,成功后清除标记并把该用户登出,之后即可正常登录。
重置不会改动目标的 TOTP 密钥;重置一个仍处于禁用状态的账号也不会让它登得进来(登录路径恒拒禁用用户),需要先执行 dsh-auth user enable <name>。完整契约见 D25。
内置配置技能
本包内置了一份配置速查技能(.agents/skills/dsh-auth-gate-config/,内容与本页相同)。把它安装到用户级技能目录后,部署环境里的 dsh agent 就能直接回答「auth-gate 支持哪些配置」:
pnpm --dir "${DSH_HOME:-$HOME/.dsh}/profiles/<profile>" exec dsh-auth skill install [--force]
该命令会把技能复制到 $DSH_HOME/skills/dsh-auth-gate-config/,dsh 的技能发现机制会自动加载。
重复执行且不带 --force 时,你对技能的本地修改会被保留;带 --force 则从包内重新覆盖。
这是一份用户专用(user-only)技能(frontmatter 里的 disable-model-invocation: true):它不会出现在模型可自动调用的技能目录里,因而不会塞进每一轮 agent 对话;需要查配置时,在技能面板里手动打开即可(输入框的 / 菜单里标记为 user-only)。如果希望 agent 能自动回答配置问题,安装后删掉那个 frontmatter 字段即可。
故障排查
dsh-auth: command not found
dsh plugin --profile web add dsh-auth-gate 会把包装进 profile 的 node_modules ($DSH_HOME/profiles/web/node_modules/dsh-auth-gate,默认 ~/.dsh/...),但不会往 shell 的 PATH 里加任何东西,所以不能直接用命令名调用 CLI。这只影响 CLI,插件本身运行正常。三种办法任选其一:
1. 经由 profile 调用(推荐)。 dsh plugin 本来就依赖 pnpm,这样 CLI 与插件从同一位置解析:
pnpm --dir "${DSH_HOME:-$HOME/.dsh}/profiles/web" exec dsh-auth user add admin --password-stdin
pnpm --dir "${DSH_HOME:-$HOME/.dsh}/profiles/web" exec dsh-auth user list
想省事的话,每个 shell 会话加一次别名:
alias dsh-auth='pnpm --dir "${DSH_HOME:-$HOME/.dsh}/profiles/web" exec dsh-auth'
2. 直接用 node 运行(运行时不需要 pnpm):
node "$DSH_HOME/profiles/web/node_modules/dsh-auth-gate/lib/cli.js" user add admin --password-stdin
3. 全局安装,dsh-auth 就会进入 PATH:
npm install -g dsh-auth-gate
dsh-auth user add admin --password-stdin
无论用哪种方式调用,CLI 读写的都是同一份共享用户列表($DSH_HOME/auth/users.yaml,找不到时回退到 ~/.dsh/auth/users.yaml),也就是插件读取的那份;全局安装的副本只是一个启动器。
从其他站点打开 dsh
跨站顶层导航(别的站点点链接、127.0.0.1 跳 localhost)只会带上 SameSite=Lax 的会话 cookie,不带 dsh web 自带的 SameSite=Strict cookie。对 gate 放行的请求,会先回一张很小的同源页面,让浏览器重新导航到同一 URL,第二次请求就同时带上两个 cookie。可能看到一次短暂的空白闪烁,无需操作;没有 JavaScript 时点 Continue 链接即可。
纯 HTTP 下会话 cookie 存不住
cookieSecure 默认是 true,浏览器被告知只在 HTTPS 下保存会话 cookie。纯 http:// 站点上登录会正常提交、服务端也正常应答,随后浏览器把 cookie 丢掉,于是你又回到登录页,等于没有会话。纯 http 的测试实例把 cookieSecure 设成 false;TLS 在 dsh 前面终结的部署则保持 true。同一个坑还会踩两次: $DSH_HOME/cordis.patch.yml 是所有 profile 共享的一层,它写 true、测试 profile 写 false 时以共享层为准,启动测试 profile 时加 --patch 覆盖。
配好之后启动链接进不来了
这是预期行为。启动令牌只用来打开首次配置向导,而向导在令牌或用户出现的那一刻就关掉了这个窗口;之后请求先到 /auth/bootstrap?token=...,端点判定实例已配置,再回 302 /auth/login?next=%2F,全程不下发 cookie,与向导出现之前完全一样。改用登录页登录即可。什么都没丢:要再打开向导,删掉已保存的令牌(或让 users.yaml 没有用户)再重启 dsh。
刚重启时启动链接停在登录页
dsh 打开启动链接时,credentials 服务可能还没就绪。在它应答之前,插件分不清「没有配置」和
「读不到配置」,于是按 fail-closed 停在登录页。等实例启动完成后刷新一次:真未配置就会进向导,已配置则登录页本来就是正确去处。
部署
- 反向代理部署指南:Caddy/nginx 配置、浏览器信任栅栏的坑(放在反代后面时设置页返回 403,以及为什么只加认证修不好),以及推荐的半外壳拓扑。
- docs/deployed/deployment_zh.md:运维清单、验收步骤(A–I)和故障诊断。
认证本地代理(可选)
⚠️ 已知限制(任何 auth-gate 版本都改变不了):dsh 的设置页(「设置 → 模型」等)只有在页面来源是回环地址(localhost/127.x)时才能编辑。这是 dsh 客户端自身的设计边界(isLoopback 检查),和认证无关:在域名页面上打开设置弹窗会显示 "settings are unavailable in this browser",无法编辑提供方和凭据,升级 dsh-auth-gate 也不会有任何变化。要编辑配置,请使用本节介绍的本地代理,或者直接在服务器上访问 http://127.0.0.1:3080。域名页面上的聊天和模型选择不受影响。
半外壳拓扑解决了服务端的 /api 栅栏之后,dsh 客户端仍然要求"页面来源必须是回环地址"; dsh-auth-proxy 在用户本机提供一个回环页面入口,与 auth-gate 配合使用,让远程编辑配置也全程需要认证,且不修改 dsh 源码。完整设计见 docs/deployed/local-proxy_zh.md。
- 零依赖的 Node 可执行文件(dsh-auth-proxy):只监听 127.0.0.1,无状态转发页面和 API,把 events.mux/events.host WebSocket 做隧道转发,并去掉 Set-Cookie 里的 Secure 属性以适配 Safari。
- 认证直接复用 auth-gate(密码模式和令牌模式都可以):登录页和会话 cookie 原样透传。
- 安全边界(deny-list,Phase 2.1):加上 --mark-proxy 后,带标记的请求命中 host.pickDirectory/host.openPath/settings.openDocument/llm.discoverModels 时,服务端 guard 会返回 403,避免远程认证用户触发宿主的原生能力;未加标记时,行为与没有部署代理时完全一致。
dsh-auth-proxy --listen 127.0.0.1:8443 --target https://your-domain.example --mark-proxy
在浏览器打开 http://127.0.0.1:8443 → 登录 →「设置 → 模型」即可编辑
systemd 示例:deploy/systemd/dsh-auth-proxy.service.example。
环境要求
- 服务器上需要 Node ≥ 22.19 和 pnpm。
- dsh 0.1.x、0.2.x 以及之后的每一条线(engines.dsh 声明为
^0.1.0-rc.6 || ^0.1.5-rc.2 || ^0.1.7-alpha.1 || >=0.2.0-rc.1)。前面三个 caret 替代项记录验过的宿主线;末尾的
=0.2.0-rc.1 下界把当前 next 线及其之后的所有宿主一并接住,未来的 0.3.x 与 1.x 也在内。
声明滞后于新宿主线的代价大于它带来的保护,因为不兼容的插件包会被静默跳过,登录门随之消失。
运行时验证过的版本是 0.1.5-rc.2 与 0.1.7-rc.2(生产,按此顺序),以及 0.1.7-alpha.1、0.2.0-rc.2(隔离实例);完整测试套件跑在 0.2.0-rc.2 的宿主包上;0.1.6- 预发布版没有列入枚举,因为没有针对它们的版本验证(稳定版 0.1.6 由 ^0.1.5-rc.2 覆盖)。插件使用的是宿主自带的 @deepseek-ai/dsh-storage-domain 和 @deepseek-ai/cordis(两者都是 peer 依赖,不会打进包),所以只要 profile 由 dsh 基础包启动,依赖就是齐的。dsh 0.2.0-rc.2(已在 next 线上)会拒绝安装、并在启动时静默跳过那些 @deepseek-ai/dsh peer 范围不覆盖当前宿主版本的插件;这条判定只读 peer,不读 engines.dsh,而完全没有这类 peer 的插件根本不会被检查。所以这一条下界在 engines.dsh 和 storage-domain peer 两处都声明(D28)。
- dsh 的 web profile 处于运行状态(dsh --profile web)。
- 如果 cookieSecure 为 true,站点必须通过 https 提供服务(浏览器会拒绝在纯 http 下使用安全 cookie)。
注意事项与局限
这里只列用户最需要知道的部分;完整清单(含机制和对应的 ADR)见 docs/deployed/known-limitations_zh.md。
- 禁用用户只阻止今后的登录;已签发的会话由插件周期扫描吊销(revokeSweepMs,默认 5 秒内生效;设为 0 则不清理,只能等 TTL 到期)。
- 登录限速和 TOTP 防重放记录会在服务重启后清零。
- 部署在反向代理后面时,必须配置 clientIpHeader(以及 trustedProxyCidrs),否则所有客户端会共用锁定桶;登录与自助改密的桶是分开的,因此两个功能都会受影响。
- 改密码时,即使"吊销旧会话"这一步失败,接口仍会按成功返回:失败会记入 error 日志,旧 cookie 到会话 TTL 到期前一直有效。
- Origin 校验只覆盖两个已认证的状态变更 POST:POST /auth/login 仍只有 SameSite=Lax 这一层跨站防护;重置若写盘成功但吊销会话失败,仍返回 200 + sessionsRevoked:false(并记 error 日志),旧 cookie 到会话 TTL 到期前一直有效。
- 重置不会改动目标的 TOTP 密钥;重置一个仍被禁用的账号也不会让它登得进来(登录路径恒拒禁用用户),需要先执行 dsh-auth user enable <name>。
- 管理员自己没启用 TOTP 时,管理端点是单因素认证;生产环境应给管理员启用 TOTP。
- 首次配置向导是一次性窗口:它的 bootstrap 会话最长 1 小时、只能访问 /auth/,令牌或用户一出现窗口就关闭。删掉那枚令牌(或最后一个用户)再重启 dsh,可以重新打开。
- 向导假设只有单个 dsh 进程,因为每个进程各自生成自己的启动令牌;多副本没有粘滞路由时,请求可能落到不认识这枚令牌的进程,回落到登录页。credentials 服务若缓存值,可能要在重启之后才认向导里保存的令牌;没有 connection.authenticatedUrl 的 dsh 版本则完全没有向导。
- 本插件只保护 dsh 的 Web 入口;操作系统账号和配置文件需要你自己保持私密。
开发
本仓库遵循 dsh-plugin-framework 的工程约定:跨 slice 只通过 barrel 引用(Feature-Sliced Design 分层,由 Steiger 检查),以 npm run verify 作为门禁链,并保留决策记录(ADR)。verify 依次运行 format / lint / no-emdash / slice / fsd / lock / decisions / docs / readme-parity / type-check / 覆盖率 80% / build / bundle / 宿主契约;测试、构建和发版流程见 docs/specs/development_zh.md。
许可证
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
TecFancy/dsh-auth-gate
给 DeepSeek Harnessdsh的网页版加一道登录关卡。把它放在公网上
相关插件 · 安全 / 权限
智能体逆向工程morluto/rea
用智能体逆向工程任何东西,从应用行为到原生二进制。
★ 426,451已汉化DSH
73.3
智能体集群框架ruvnet/ruflo
面向 Claude Code 与 Codex 的智能体元基座meta-harness。
★ 80,777已汉化MCP
71.8
WorkBuddy 模型接入corrinehu/dsh-workbuddy-connect
2026 年 10 月 20 日起,WorkBuddy…
★ 1,604已汉化DSH
71.7
主动编码智能体deepseek-ai/dsh-superagent-prototype
研究原型,仅供参考,不是 DeepSeek 官方产品。…
★ 15,535已汉化DSH
71.6
破甲一键通z91772524-ai/pojia-next
🌐 官网国内推荐从这里进:
★ 1,021已汉化DSH
71.6
Agent 操作层agentic-os-org/ANOLISA
ANOLISA(Agentic Nexus Operating Layer & Interface System Architecture)|智能体操作系统,带运行时、安全、可观测性,以及 Tokenless 响应压缩,降低 token 用量与成本。
★ 656已汉化DSH
70.7
这是你的仓库?认领条目