docs(agent): lock client↔agent auth to option ① (agent-local token compare)
Per the chosen design, the agent authorizes callers by comparing the request header X-Agent-Access-Token against its env AGENT_ACCESS_TOKEN (constant-time), no HM round-trip. AM contract §3.1 now states ① as the agreed integration with Python pseudo-code; the /agent-access/verify endpoint is demoted to an optional fallback. Client API §6 spells out the client's job: send X-Agent-Access-Token on every direct-connect request. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -112,20 +112,32 @@ HM 把用户绑定的资源按**资源类型 + provider**解成固定 env 名(
|
||||
|
||||
客户端从 HM 拿到 `subdomain` 后**直连 agent**,走你们的 **A2A 协议**(`POST {subdomain}/message/send` 同步、`POST {subdomain}/message/stream` 流式、`GET {subdomain}/.well-known/agent.json`、`GET {subdomain}/health`)。HM 不在回路。HM 已据此写好客户端文档 `heicode-desktop-client-api.md` §6。
|
||||
|
||||
### 3.1 客户端↔agent 访问鉴权(HM 已提供,AM 可选接)
|
||||
### 3.1 客户端↔agent 访问鉴权(HM 已提供;接入方式 = ① 本地校验)
|
||||
|
||||
> 解决「agent 公网可达、谁有有效 sk 都能驱动别人的 agent、读走其挂载的 git token / db 密码 / blob key」的按用户隔离问题。**HM 侧已落地,AM 可选择接或自己另搞一套。**
|
||||
> 解决「agent 公网可达、谁有有效 sk 都能驱动别人的 agent、读走其挂载的 git token / db 密码 / blob key」的按用户隔离问题。**HM 侧已落地;双方约定 AM 用 ① 本地校验接入(见下,一行字符串比较)。**
|
||||
|
||||
- 部署 agent 时,**HM 给每个 agent 现签一把随机访问令牌**(per-agent access token,UUID),并:
|
||||
1. **注入进 agent 的 env**:`AGENT_ACCESS_TOKEN`(令牌本身)、`HEICODE_AGENT_ID`(该 agent 的 `agent_id`,即 `dep-xxx`)。
|
||||
2. **返回给客户端**:HM 的 agent 列表/详情里 `access_token` 字段就是这把令牌(只有部署它的那个用户拿得到)。
|
||||
- 客户端直连 agent 时,把这把令牌一起带上(建议放请求头 `X-Agent-Access-Token`,或 A2A `params` 里约定字段)。
|
||||
- **agent 鉴权该令牌,二选一:**
|
||||
- ① **本地校验(零额外依赖,推荐)**:比较 `调用方令牌 == 自己 env 里的 AGENT_ACCESS_TOKEN`。两者是 HM 启动时注入的同一把密钥,相等即放行。**不用回 HM。**
|
||||
- ② **HM 权威校验**:`POST {HM}/api/heicode/agent-access/verify`,body `{"agent_id":"<HEICODE_AGENT_ID>","access_token":"<调用方令牌>"}` → 返回 `{"success":true,"data":{"valid":true,"user_id":22,"template_id":"..."}}`。令牌不符只回 `{"valid":false}`(不泄露任何用户信息)。这样 AM 还能拿到「该 agent 属于哪个 HM 用户」。常量时间比较、公开端点(agent 无 HM 会话,令牌本身即凭据)。
|
||||
- 客户端直连 agent 时,把这把令牌放进**请求头 `X-Agent-Access-Token`**。
|
||||
- **agent 鉴权方式 = ① 本地校验(已选定)**:
|
||||
- 比较 `请求头 X-Agent-Access-Token == 自己 env 里的 AGENT_ACCESS_TOKEN`(常量时间比较,建议 `hmac.compare`/`secrets.compare_digest`)。两者是 HM 启动时注入的同一把密钥,**相等即放行,不等返回 401/403**。
|
||||
- **不用回 HM、零额外依赖、零网络往返**。这是双方约定的正式接入方式。
|
||||
- 缺失或为空(老 agent / 未注入)时如何处理由 AM 决定(建议:env 里有 `AGENT_ACCESS_TOKEN` 就强制校验,没有则放行以兼容)。
|
||||
- **可选兜底:HM 权威校验端点**(AM 不需要、默认不用;仅当 AM 想让 HM 当权威、或想顺带拿 `user_id` 时):`POST {HM}/api/heicode/agent-access/verify`,body `{"agent_id":"<HEICODE_AGENT_ID>","access_token":"<X-Agent-Access-Token>"}` → `{"success":true,"data":{"valid":true,"user_id":22,"template_id":"..."}}`;不符只回 `{"valid":false}`。公开端点、常量时间比较。
|
||||
- **只有部署该 agent 的用户拿到令牌 ⇒ 只有他能调** = 「这个 agent 这个用户能调」。
|
||||
- **通道加密 = TLS**:agent 子域名请走 **HTTPS**,令牌与对话内容由 TLS 加密;HM 不在回路,无需 HM 中转解密。
|
||||
|
||||
**AM 侧伪代码(本地校验):**
|
||||
```python
|
||||
# coding_a2a_agent 收到 A2A 请求时
|
||||
expected = os.environ.get("AGENT_ACCESS_TOKEN", "")
|
||||
got = request.headers.get("X-Agent-Access-Token", "")
|
||||
if expected and not secrets.compare_digest(expected, got):
|
||||
raise HTTPException(401, "agent access denied")
|
||||
# 通过 → 正常处理(api_key 仍用于打 HM /v1 计费)
|
||||
```
|
||||
|
||||
模型鉴权(打 HM `/v1/*`)仍是 A2A 请求里的 `api_key`(模型 sk-),与上面的访问令牌**职责分离**:`api_key` 管「用谁的额度跑模型」,`AGENT_ACCESS_TOKEN` 管「谁有权调这个 agent」。
|
||||
|
||||
> 若 AM 完全不接:退化为旧状态——任一有效 sk 都能驱动任一 agent,存在跨用户读资源风险。HM 已把机制备好,接入成本极低(本地校验仅一行字符串比较)。
|
||||
@@ -167,7 +179,7 @@ HM 这些路径都可用环境变量覆盖(默认值见 §1),AM 若用别的路
|
||||
|
||||
- [ ] `POST /agents/start` 收到 `agent_definition`+`env`+`callback_url`,起 agent、注入 env、返回 `{runtime_id, subdomain, access_token, status}`。
|
||||
- [ ] agent 用模型打到 HM `/v1/*`(带用户身份),计费正常。
|
||||
- [ ] agent 子域名按 §3.1 校验 `AGENT_ACCESS_TOKEN`(本地比较或回 HM `/api/heicode/agent-access/verify`);非该 agent 所有者的调用被拒。
|
||||
- [ ] agent 子域名按 §3.1 ① **本地比对** `X-Agent-Access-Token == env AGENT_ACCESS_TOKEN`(常量时间);不符返回 401/403,非该 agent 所有者的调用被拒。
|
||||
- [ ] `GET /agents/{id}` 返回真实 status;`stop`/`delete` 生效。
|
||||
- [ ] agent 不泄露 env/密钥;启动接口 HTTPS/私网。
|
||||
- [ ] 把 §3 的 SSE 直连契约回给 HM 补进客户端文档。
|
||||
|
||||
@@ -223,12 +223,12 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
```
|
||||
|
||||
**两层鉴权,职责分离:**
|
||||
- **访问鉴权 = `access_token`**(`X-Agent-Access-Token` 头,§5 列表里那把 per-agent 令牌):证明「你是这个 agent 的所有者,有权调它」。agent 本地比对自己 env 里的 `AGENT_ACCESS_TOKEN`,或回 HM `POST /api/heicode/agent-access/verify` 校验。
|
||||
- **访问鉴权 = `access_token`**(放 `X-Agent-Access-Token` 头,值取 §5 列表里那把 per-agent 令牌):证明「你是这个 agent 的所有者,有权调它」。**每个直连请求都要带**(`message/send`、`message/stream` 都带)。agent 端把它和自己 env 里的 `AGENT_ACCESS_TOKEN` 做常量时间比对,不符返回 401/403。
|
||||
- **模型鉴权 = `params.api_key`**(模型 sk-,客户端自带的网关 key):agent 凭它调 HM `/v1/*`,计费到你账上。
|
||||
- agent 用 `.env` 里注入的资源(git/mysql/postgres/azure-blob)自行干活;工具:`read_file/write_file/edit_file/run_command/git_*/run_database_query/list_blob_objects` 等。缺配置的资源工具调用会返回 `resource not configured`,不阻塞。
|
||||
- 可在 `params.configuration.resources` 里按需覆盖资源(请求级覆盖启动级)。
|
||||
|
||||
> ℹ️ 安全:HM 已为「客户端↔agent」提供按用户隔离机制 —— per-agent 访问令牌(`access_token`,部署时现签、注入 agent env、随列表下发),只有部署该 agent 的你拿得到 ⇒ 只有你能调。**AM 是否启用由 AM 决定**(可本地比对或回 HM verify,也可自行另搞一套);若 AM 不启用,则退化为「任一有效 api_key 可驱动任一 agent」。通道加密走 agent 子域名的 HTTPS/TLS。详见 AM 契约 §3.1。
|
||||
> ℹ️ 安全:HM 为「客户端↔agent」提供按用户隔离 —— per-agent 访问令牌(`access_token`,部署时现签、注入 agent env、随列表下发),只有部署该 agent 的你拿得到 ⇒ 只有你能调。**接入方式 = agent 本地比对**(`X-Agent-Access-Token` == env `AGENT_ACCESS_TOKEN`),不回 HM、零往返。客户端职责很简单:**直连每个请求都带上 `X-Agent-Access-Token` 头**。通道加密走 agent 子域名的 HTTPS/TLS。详见 AM 契约 §3.1。
|
||||
|
||||
---
|
||||
|
||||
@@ -291,7 +291,7 @@ signature = base64( ed25519_sign( device_priv, sha256(canonical) ) )
|
||||
| `POST /api/heicode/agents` | 会话/设备 | 🟢(调 AM,AM 接口 🔴) |
|
||||
| `POST /api/heicode/agents/{id}/stop`、`DELETE /{id}` | 会话/设备 | 🟢(调 AM 🔴) |
|
||||
| 模型 `/v1/*` | 同模型调用 | 🟢 |
|
||||
| `POST /api/heicode/agent-access/verify` | 公开(令牌即凭据) | 🟢(供 agent 服务端校验,见 §6) |
|
||||
| 直连 agent SSE(subdomain + X-Agent-Access-Token) | agent 校验(本地比对/回 HM verify) | 🔴(待 AM agent 端) |
|
||||
| `POST /api/heicode/agent-access/verify` | 公开(令牌即凭据) | 🟢(可选兜底;接入用 ① 本地比对,默认不用此端点) |
|
||||
| 直连 agent SSE(subdomain + X-Agent-Access-Token) | agent 本地比对令牌 | 🔴(待 AM agent 端) |
|
||||
|
||||
> 🔴 项不阻塞客户端集成:HM 侧字段/接口已定型并生产验证,等 AM 实现 agent 启动/状态/直连即全线打通。AM 契约见 `heicode-hm-template-agent-model.md` §7 与代码 `controller/agent_template_runtime.go`(隔离层)。
|
||||
|
||||
Reference in New Issue
Block a user