oclaw/uds-auth/docs/skill-auth-standard.zh.md
oliver b60c626d41 Bundle uds-skill-auth inside the uds-auth plugin for single-package handoff.
Move the public auth helper skill under uds-auth/skills and update docs to point there instead of the repo-root skills tree.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-08 23:46:11 +08:00

122 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Skill 认证标准(uds-auth)
面向 DeepSeekHarness:现场安装 **uds-auth 插件**(内含 skill `uds-skill-auth`)后,第三方 / 自研 skill 按本标准取凭证或出站调用。
**转发给改造方时**:发整个 `uds-auth` 插件即可;公共 skill 在 [`skills/uds-skill-auth/`](../skills/uds-skill-auth/),说明见 [uds-skill-auth.zh.md](./uds-skill-auth.zh.md)。
## 现场形态
```text
安装 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 token
- `skillCredentialTtlSeconds`(默认 `604800` = 7 天)
- `outboundAllowedHosts`:出站白名单(逗号分隔)
管理员删除用户会同时清掉该用户的 skill 凭证。
## Agent 环境
Shell 已注入(非密钥):
- `DSH_SESSION_ID` — 当前 agent 会话
- `DSH_WEB_URL` — 可选,用于拼 Host 地址
Host 在 `session/created` 时会 `stampSessionOwner(sessionId, empNo)`。Cron 可按 `ownerEmpNo` 解析。
## 两种合法模式
### Mode Outbound(推荐新 skill)
```http
POST /uds-auth/outbound
X-DSH-Session-Id: <DSH_SESSION_ID>
{ "url": "https://icenterapi.zte.com.cn/...", "method": "POST", "headers": {...}, "body": {...} }
```
- 仅 **loopback**
- Host 注入 `X-Emp-No` / `X-Auth-Value`
- 剥离客户端自带鉴权头
- host 必须在白名单内
Python(先把 `uds-skill-auth/scripts` 加入 `sys.path`):
```python
from uds_skill_auth import request
out = request("POST", url, headers={...}, body={...})
# out["statusCode"], out["json"], out["body"]
```
### Mode Creds(必须自管 HTTP 时)
```http
POST /uds-auth/agent-credentials
X-DSH-Session-Id: <DSH_SESSION_ID>
```
返回 `{ empNo, token }`。可设进程内 `EMP_NO` / `AUTH_VALUE` 别名,**禁止**写进 SKILL.md 教模型 `printenv`。
```python
from uds_skill_auth import resolve
creds = resolve() # empNo + token;默认写入 EMP_NO/AUTH_VALUE
```
Helpers 来源:插件内 skill `uds-auth/skills/uds-skill-auth/scripts/`(装到 skills 路径后,或环境变量 `UDS_AUTH_HELPERS`)。
## 改造现有 Skill 清单
1. 现场确保已从插件安装 `uds-skill-auth`(`uds-auth/skills/uds-skill-auth`)
2. 业务脚本定位 sibling:`.../skills/uds-skill-auth/scripts` → `import uds_skill_auth`
3. 替换原来的 `coclaw_*` / `EMP_NO`/`AUTH_VALUE` 手工读环境:改用 `resolve()` 或 `request()`
4. SKILL.md 只写「需已 UDS 登录,并已安装 uds-skill-auth」,不写 token 变量名
5. JSON stdout;日志脱敏
定位示例:
```python
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-auth` skill)
## 验收
- UI 登录/退出与改前一致
- 默认配置下 UI 退出后 skill/cron 仍可用
- `retainSkillCredentialsOnLogout=false` 时退出后取证失败
- 未安装 `uds-skill-auth` 时业务 skill 报错清晰
- 两会话不串号;未登录错误可理解且无 token 泄露