docs: update desktop sub encrypted request flow

This commit is contained in:
gongzhiyong
2026-05-27 18:46:32 +08:00
parent 9f5b4ba777
commit 741cc0d254
@@ -18,13 +18,13 @@ Manager 负责辅助控制面:任务草稿桥接、资源/权限、Agnet deplo
| API 前缀 | 用途 | 认证 |
|---|---|---|
| `/api/heicode-auth/api/user/tasks/*` | HeicodeTask 任务编排代理,创建任务、追问、查询任务 | `Authorization: Bearer <heicode_access_token>` |
| `/api/agnet/user/*` | Manager 用户态 Agnet 控制面,deployment、timeline、artifact、审批 | Manager 登录 session cookie + `New-Api-User: <user_id>` |
| `/api/heicode-auth/api/user/tasks/*` | HeicodeTask 任务编排代理,创建任务、追问、查询任务 | V2 加密 body + `Authorization: Bearer <heicode_access_token>` |
| `/api/agnet/user/*` | Manager 用户态 Agnet 控制面,deployment、timeline、artifact、审批 | V2 加密 body;未加密 Web 控制台请求继续使用 Manager session + `New-Api-User` |
| `/api/user/self` | 查询当前 Manager 用户 | Manager 登录 session cookie |
### 2.2 桌面端请求 body 加密
桌面客户端调用 Manager 的 sub 流程接口时,应优先使用与模型调用一致的 V2 加密请求协议。
桌面客户端调用 Manager 的 sub 流程接口时,应使用与模型调用一致的 V2 加密请求协议。生产 Manager 自 `1.4.7` 起已支持该能力。
适用接口:
@@ -74,9 +74,17 @@ Authorization: Bearer <heicode_access_token>
原因:该 token 是上游 HeicodeTask 服务认证用;V2 设备签名只证明请求来自已配对的 Manager 桌面设备。
客户端实现要求:
1. sub 流程调用不要新增一套加密协议,直接复用模型调用的 `encryptedFetch` / V2 设备签名实现。
2. `aad` 和 `canonical` 中的 `path_with_query` 必须是 Manager 实际收到的 path,例如 `/api/agnet/user/tasks/task-1/deployment-draft`,不能把 origin 写进去。
3. 加密前的 plaintext 必须是最终 JSON body;签名里的 `sha256_hex(plaintext_body)` 必须和该 JSON 字节完全一致。
4. 每次请求必须使用新的 `X-Heicode-Nonce` 和新的 X25519 ephemeral key。
5. V2 请求失败时优先读取 `X-Heicode-Auth-Error` 和 `X-Heicode-Server-Time`,用于提示设备未配对、时间漂移、nonce 重放、签名错误或解密失败。
### 2.3 Manager 用户态 Header
调用 `/api/agnet/user/*` 时必须带:
未加密 Web 控制台请求调用 `/api/agnet/user/*` 时必须带:
```http
Cookie: session=<manager-session>
@@ -87,7 +95,7 @@ Accept: application/json
`New-Api-User` 必须等于当前登录用户 ID,否则会返回未授权。
使用 V2 加密 body 时,`/api/agnet/user/*` 可以不依赖浏览器 session cookie;Manager 会从设备绑定 token 中解析用户身份。为兼容当前 Web 控制台,未加密请求仍按 session cookie + `New-Api-User` 处理。
使用 V2 加密 body 时,`/api/agnet/user/*` 不依赖浏览器 session cookie,也不需要 `New-Api-User`;Manager 会从设备绑定 token 中解析用户身份。为兼容当前 Web 控制台,未加密请求仍按 session cookie + `New-Api-User` 处理。
### 2.4 统一响应 Envelope
@@ -1116,31 +1124,61 @@ Runtime callback / timeline 中可使用:
## 14. 桌面端最小伪代码
```ts
type Json = Record<string, unknown>
// 复用模型调用已经使用的 V2 加密 fetch:
// - 自动拉取 /api/server-pubkey
// - 每次请求生成 nonce + X25519 ephemeral key
// - 用 ChaCha20-Poly1305 加密 body
// - 用设备 Ed25519 私钥签名 canonical
// - 设置 Content-Encoding: heicode-aead-v1 和所有 X-Heicode-* 头
async function encryptedManagerRequest<T>(
method: 'POST',
path: string,
body?: Json,
extraHeaders: Record<string, string> = {}
): Promise<T> {
return encryptedFetch<T>(`${managerBaseUrl}${path}`, {
method,
plaintextJson: body,
headers: {
Accept: 'application/json',
...extraHeaders,
},
})
}
const self = await manager.get('/api/user/self')
const userId = self.data.id
const task = await mcp.post('/api/heicode-auth/api/user/tasks/intent', {
intent: userInput,
}, {
headers: {
const task = await encryptedManagerRequest<Envelope<TaskSnapshot>>(
'POST',
'/api/heicode-auth/api/user/tasks/intent',
{ intent: userInput },
{
Authorization: `Bearer ${heicodeAccessToken}`,
},
})
}
)
let current = task.data
while (current.status === 'configuring') {
const followup = findNextFollowup(current)
const answer = await askUser(followup)
current = await mcp.post(
current = await encryptedManagerRequest<Envelope<TaskSnapshot>>(
'POST',
`/api/heicode-auth/api/user/tasks/${current.id}/answer`,
{
question_id: followup.id,
option_id: answer.id,
},
{
Authorization: `Bearer ${heicodeAccessToken}`,
}
).then((r) => r.data)
}
const draft = await manager.post(
const draft = await encryptedManagerRequest<Envelope<DeploymentDraft>>(
'POST',
`/api/agnet/user/tasks/${current.id}/deployment-draft`,
{
task: current,
@@ -1148,26 +1186,25 @@ const draft = await manager.post(
binding_scope: `task-${current.id}`,
role_templates: ['backend', 'frontend', 'reviewer'],
default_model_id: 'agnet-model-builder',
},
{ headers: { 'New-Api-User': String(userId) } }
}
)
const deployment = await manager.post(
const deployment = await encryptedManagerRequest<Envelope<Deployment>>(
'POST',
'/api/agnet/user/deployments',
{ orchestration_plan: draft.data.orchestration_plan },
{ headers: { 'New-Api-User': String(userId) } }
{ orchestration_plan: draft.data.orchestration_plan }
)
const deploymentId = deployment.data.deployment_id
setInterval(async () => {
const timeline = await manager.get(
const timeline = await manager.get<Envelope<DeploymentTimeline>>(
`/api/agnet/user/deployments/${deploymentId}/timeline`,
{ headers: { 'New-Api-User': String(userId) } }
)
renderTimeline(timeline.data.timeline)
const approvals = await manager.get(
const approvals = await manager.get<Envelope<ApprovalList>>(
`/api/agnet/approvals?status=pending&deployment_id=${deploymentId}`,
{ headers: { 'New-Api-User': String(userId) } }
)
@@ -1175,11 +1212,21 @@ setInterval(async () => {
}, 5000)
```
兼容说明:
- 桌面客户端对 `POST` 等有 body 的 sub 请求走 V2 加密时,`/api/agnet/user/*` 不需要 `New-Api-User`,也不依赖浏览器 cookie。
- `GET` 查询接口本身没有请求 body,当前生产兼容路径仍使用 Manager session cookie + `New-Api-User`。如果桌面本地服务后续要完全脱离 session cookie 查询 timeline / artifact / approval,需要再补“无 body 的 V2 设备签名 GET”协议。
- `/api/heicode-auth/*` 仍必须带 `Authorization: Bearer <heicode_access_token>`,该 token 只用于上游 HeicodeTask 认证。
- 如果客户端临时还没有接入 V2 加密,只能作为调试兼容路径使用 Manager session + `New-Api-User` 调 `/api/agnet/user/*`;正式桌面流程不要依赖该路径。
## 15. 当前生产注意事项
1. `https://code.xinghanlab.com` 的 Manager 用户态接口已上线。
1. `https://code.xinghanlab.com` 的 Manager 用户态接口已上线,当前生产版本为 `1.4.7`。
2. Manager 本地控制面可创建 `sub_mode=agile/waterfall` deployment。
3. 生产 Manager 已配置 Agent Manager Runtime,当前直接走 `http://20.212.121.126`;域名和 HTTPS 后续单独处理,不作为客户端当前接入阻塞项。
4. `deployment-draft -> create -> detail -> stop` 已在生产验证通过,客户端可按本文参数形状接入。
4. V2 加密 `deployment-draft` 已在生产验证通过:真实构造 `Content-Encoding: heicode-aead-v1` 请求返回 200,`sub_mode=agile`,`user_id=22`。
5. `events/logs/artifacts/sk-snapshots/timeline` 查询接口已验证不报错;真实阶段事件、产物、SK 调用结果需要 Agent Manager 执行任务并回调后才会出现。
6. `POST /api/heicode-auth/api/user/tasks/intent` 需要桌面客户端提供 `heicode_access_token`;没有该 token 会返回 401。
6. `deployment-draft -> create -> detail -> stop` 已在生产验证通过,客户端可按本文参数形状接入。
7. `POST /api/heicode-auth/api/user/tasks/intent` 需要桌面客户端提供 `heicode_access_token`;没有该 token 会返回 401。
8. malformed V2 请求已在生产验证会返回 `X-Heicode-Auth-Error`,客户端应把该头转成可读错误提示。
9. 当前 `GET` 查询接口没有请求 body,仍按 session + `New-Api-User` 验证;这不影响 body 加密要求,但客户端若要全链路无 cookie,需要后续补无 body 签名 GET。