Emergency (fallback / sealed-box) admins lost the workspace sidebar and saw "sign-in failed / add API key" on DSH Desktop because the remote.mux opens anonymously at boot and every early call was rejected terminally. - gateway: anonymous workspace/follow reaches dsh-acl's empty baseline; anonymous streams are parked until the carrier aborts instead of failing; anonymous workspace/initializeDefault answers "nothing created" - request-auth: a dead UDS_SESSION cookie no longer shadows a valid WS ticket or bridge (sync + async variants used by all callers) - dsh-acl: /api/* waits (bounded 15s) for the gateway ACL during Host startup instead of 403, so the Desktop welcome read no longer fails - desktop-bootstrap: key/account projection is best-effort per reference - client: emit connection/reset after login so boot-time caches (settings describe mirror -> Settings > Models) re-read under the real principal - sessions: absolute lifetime fixed at 7 days (was min(ttl, 7d) = 30 min); bridge expiry slides with its session; MemoryStore persisted to sessions.json (bearer hash only, userData AES-256-GCM sealed) - README: session lifetime/persistence and DSH compatibility notes Also includes previously uncommitted uds-auth 0.3.x work in this tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
4.8 KiB
Skill 认证标准(uds-auth)
面向 DeepSeekHarness:现场安装 uds-auth 插件(内含 skill uds-skill-auth)后,第三方 / 自研 skill 按本标准取凭证或出站调用。
转发给改造方时:发整个 uds-auth 插件即可;公共 skill 在 skills/uds-skill-auth/,说明见 uds-skill-auth.zh.md。
现场形态
安装 uds-auth 插件(内含 skills/uds-skill-auth)
→ 将 uds-skill-auth 加入 skills 路径(或复制到工作区 skills/)
→ 用户扫码登录
→ 安装/加载业务 skill
→ 可用
无需再配全局 coclaw_token / AUTH_VALUE。
认证公共库随插件分发:路径 uds-auth/skills/uds-skill-auth/。
双轨模型
| 轨道 | 用途 | 行为 |
|---|---|---|
| UI | Cookie + sessionStore + /api/me |
保持原样;logout 仍清 cookie 并 sessionStore.delete |
| Skill | skillCredentialCache(skill-credentials.json) |
登录成功时写入/刷新;供 agent / cron |
配置项:
retainSkillCredentialsOnLogout(默认true):UI 退出时是否保留 skill tokenskillCredentialTtlSeconds(默认604800= 7 天)outboundAllowedHosts:出站白名单(逗号分隔)
管理员删除用户会同时清掉该用户的 skill 凭证。
Agent 环境
Shell / 任务 env(非密钥除非 Host 显式注入 capability):
DSH_SESSION_ID— 当前 agent 会话DSH_WEB_URL— 可选,用于拼 Host 地址UDS_TASK_CAPABILITY— 推荐:Host/mintTaskCapability签发的短期令牌(scopes:outbound和/或credentials)
Host 在 session/created 时会 stampSessionOwner(sessionId, empNo)。Cron 可按 ownerEmpNo 解析并 mint capability;不要依赖浏览器 Cookie。
账号停用/删除会撤销该用户全部 task capability。
两种合法模式
Mode Outbound(推荐新 skill)
POST /uds-auth/outbound
X-DSH-Session-Id: <DSH_SESSION_ID>
X-UDS-Task-Capability: <UDS_TASK_CAPABILITY> # scope 须含 outbound
{ "url": "https://icenterapi.zte.com.cn/...", "method": "POST", "headers": {...}, "body": {...} }
- 仅 loopback
- Host 注入
X-Emp-No/X-Auth-Value - 剥离客户端自带鉴权头
- host 必须在白名单内;URL 必须 HTTPS
- capability 仅
credentialsscope 时 不能 调 outbound
Python(先把 uds-skill-auth/scripts 加入 sys.path):
from uds_skill_auth import request
out = request("POST", url, headers={...}, body={...})
# out["statusCode"], out["json"], out["body"]
Mode Creds(必须自管 HTTP 时)
默认 allowRawAgentToken=false。开启后:
POST /uds-auth/agent-credentials
X-DSH-Session-Id: <DSH_SESSION_ID>
X-UDS-Task-Capability: <UDS_TASK_CAPABILITY> # scope 须含 credentials
返回 { empNo, token }。可设进程内 EMP_NO / AUTH_VALUE 别名,禁止写进 SKILL.md 教模型 printenv。仅 outbound scope 的 capability 不能取 raw token。
from uds_skill_auth import resolve
# 优先用 request()/outbound;仅在 allowRawAgentToken=true 时使用 resolve
creds = resolve(apply_env_aliases=False)
Helpers 来源:插件内 skill uds-auth/skills/uds-skill-auth/scripts/(装到 skills 路径后,或环境变量 UDS_AUTH_HELPERS)。
改造现有 Skill 清单
- 现场确保已从插件安装
uds-skill-auth(uds-auth/skills/uds-skill-auth) - 业务脚本定位 sibling:
.../skills/uds-skill-auth/scripts→import uds_skill_auth - 替换原来的
coclaw_*/EMP_NO/AUTH_VALUE手工读环境:改用resolve()或request() - SKILL.md 只写「需已 UDS 登录,并已安装 uds-skill-auth」,不写 token 变量名
- JSON stdout;日志脱敏
定位示例:
from pathlib import Path
import sys
def load_uds_skill_auth():
here = Path(__file__).resolve().parent
candidate = here.parents[1] / "uds-skill-auth" / "scripts"
if not (candidate / "uds_skill_auth.py").is_file():
raise RuntimeError("请先安装 uds-skill-auth skill")
sys.path.insert(0, str(candidate))
import uds_skill_auth
return uds_skill_auth
禁止项
- 全局共享 token / 把 token 注入
shellEnv - SKILL 教打印环境变量中的密钥
- 无白名单的开放代理
- 用 UI
sessionStore的 30min TTL 冒充 skill 长凭证 - 业务 skill 硬编码插件源码路径(应用
uds-skill-authskill)
验收
- UI 登录/退出与改前一致
- 默认配置下 UI 退出后 skill/cron 仍可用
retainSkillCredentialsOnLogout=false时退出后取证失败- 未安装
uds-skill-auth时业务 skill 报错清晰 - 两会话不串号;未登录错误可理解且无 token 泄露