207 lines
8.7 KiB
Markdown
207 lines
8.7 KiB
Markdown
# Heicode 运行时认证、扣费与密钥设计
|
||
|
||
日期:2026-05-04
|
||
|
||
本文修正 Manager、Agnet 平台、NewAPI 与 OpenBao 之间的运行时边界。若本文与旧文档中 `tenant`、`project` 或平台侧批准描述冲突,以本文为准。
|
||
|
||
## 一、用户输入在哪里
|
||
|
||
用户输入发生在 Heicode 的用户侧入口,也就是 Manager/客户端的“想法输入”主流程。
|
||
|
||
用户登录后输入目标、需求、约束、绑定的 Git/SK/云资源选择,以及是否批准高危操作。Manager 负责把这些输入整理成 Agnet 平台可执行的 work request:
|
||
|
||
- 用户想法和自然语言需求。
|
||
- 绑定的 Git 仓库、分支、路径范围和写入权限。
|
||
- 绑定的 SK 仓库或技能包。
|
||
- 绑定的云资源元数据和允许动作。
|
||
- 子 Agnet 角色、数量、运行模型和预算限制。
|
||
- 客户端已经确认的高危操作审批结果。
|
||
|
||
Manager 不应为了团队开发控制额外发明 `tenant/project` 产品概念。当前团队开发边界优先来自绑定的 Git 仓库、允许路径、分支策略、Agnet 角色和资源授权。
|
||
|
||
## 二、Manager 用户复用 Agnet 登录体系
|
||
|
||
Manager User 应复用 Heicode/Agnet 已上线登录体系,不再另建一套独立身份。
|
||
|
||
参考 [`integration/Heicode-登录接口对接文档.md`](./integration/Heicode-登录接口对接文档.md),登录流程已经提供:
|
||
|
||
- `POST /api/auth/login`
|
||
- `GET /api/auth/me`
|
||
- `POST /api/auth/refresh`
|
||
- `POST /api/auth/logout`
|
||
|
||
登录返回的用户对象包含:
|
||
|
||
- `id`
|
||
- `name`
|
||
- `email`
|
||
- `role`
|
||
- `channelId`
|
||
|
||
JWT 中也包含:
|
||
|
||
- `sub`
|
||
- `email`
|
||
- `role`
|
||
- `channelId`
|
||
- `type`
|
||
- `iat`
|
||
- `exp`
|
||
|
||
因此 Manager 的认证设计应是:
|
||
|
||
```text
|
||
用户登录 Heicode/Agnet 认证体系
|
||
-> Manager 校验 token 并读取 /api/auth/me
|
||
-> Manager 使用 user.id / sub 作为业务用户 ID
|
||
-> Manager 使用 channelId 关联 NewAPI 余额、用量和扣费查询
|
||
-> Manager 本地只保存必要的用户会话、资源绑定和审计数据
|
||
```
|
||
|
||
Manager 可以有本地 user cache,但 canonical user identity 应来自登录接口返回的用户信息。除非未来产品明确引入企业组织、空间或项目账本,否则不要把 tenant/project 作为认证和扣费主轴。
|
||
|
||
## 三、高危操作审批与 OpenBao 密钥注入
|
||
|
||
高危操作审批只在客户端完成。用户在客户端明确批准后,Manager/Agnet 平台才可以执行对应动作。Agnet 平台不是审批主体,不发起额外审批;它只校验 `approval_id`、审批主体、审批范围、TTL、`risk_level` 和策略是否匹配。
|
||
|
||
密钥处理边界如下:
|
||
|
||
```text
|
||
长期密钥
|
||
-> 用户授权或绑定资源
|
||
-> Manager 写入 OpenBao
|
||
-> Manager DB 只保存 secret_ref
|
||
-> OpenBao 只允许 Manager/Agnet 受控网络访问,不对公网暴露
|
||
|
||
高危操作
|
||
-> 客户端审批
|
||
-> Manager/Agnet 平台按 secret_ref 从 OpenBao 获取或派生短期凭证
|
||
-> 短期凭证可注入子 Agnet
|
||
-> 子 Agnet 完成任务后凭证过期或撤销
|
||
```
|
||
|
||
允许注入子 Agnet 的只能是短期、最小权限、可审计的凭证。长期 Git token、云 access key、SSH 私钥、数据库密码、NewAPI key 原文不得进入 Git、Markdown、普通日志或长期 Agnet 状态。
|
||
|
||
公网入口边界:
|
||
|
||
- `heicode.xinghanlab.com` 是 Manager、NewAPI 与内部服务的统一公网域名入口。
|
||
- Nginx 可以为 Manager 和 NewAPI 制定路由,例如 Manager 主站与 NewAPI 受控 API 路由。
|
||
- OpenBao 不应作为普通公网路由开放;如果 Manager 已经提供客户端验证、资源绑定、审批和 `secret_ref` 管理接口,客户端不需要直连 OpenBao。
|
||
- OpenBao 访问应限制在容器网络、VM loopback、AKS 内网、Workload Identity 或其它受保护服务间通道。
|
||
|
||
OpenBao 不暴露公网的检查口径:
|
||
|
||
- 公网 DNS、Nginx `server_name`、Ingress、LoadBalancer 和安全组规则不得直接指向 OpenBao 服务端口。
|
||
- 外部客户端只能通过 Manager 的认证、资源绑定、审批和 `secret_ref` 管理接口间接操作密钥引用。
|
||
- Manager、Agnet 平台和子 Agnet 访问 OpenBao 时必须走内网地址、loopback、容器网络、AKS private endpoint 或 Workload Identity 绑定。
|
||
- 健康检查和联调报告只能证明内网访问可用;不得把公网可访问的 OpenBao health endpoint 作为验收口径。
|
||
|
||
短期凭证注入必须满足:
|
||
|
||
- 有客户端审批记录。
|
||
- 有 `secret_ref` 来源。
|
||
- 有 TTL 或明确撤销机制。
|
||
- 有资源范围、路径范围、云资源范围或 API 范围限制。
|
||
- 有 Agnet deployment、agent role、user id、操作类型的审计记录。
|
||
|
||
## 四、NewAPI 额度与扣费能力
|
||
|
||
公开 NewAPI 文档当前体现的是用户、Token、Group、余额和用量视角,而不是 Manager `tenant/project` 视角。
|
||
|
||
NewAPI 官方 skill 文档明确支持:
|
||
|
||
- 查询模型。
|
||
- 查询用户 Group。
|
||
- 查询账号余额。
|
||
- 管理 API Token。
|
||
- 创建 Token 并指定 Group。
|
||
- 切换 Token Group。
|
||
- Token 安全复制和注入。
|
||
|
||
因此当前结论是:
|
||
|
||
1. NewAPI 可以承担模型网关和用户/Token/Group 维度的额度、余额、用量、日志能力。
|
||
2. Manager 不应假设 NewAPI 已有 Heicode tenant/project 额度。
|
||
3. Manager 普通用户侧展示应围绕当前登录用户的模型可用性、余额、额度、调用量和调用日志。
|
||
4. 扣费映射应优先使用 `channelId`、NewAPI user、NewAPI token 或 NewAPI group。
|
||
5. 若未来需要团队、组织、项目维度账本,应作为独立产品决策重新设计,而不是在当前 Manager 里暗自添加。
|
||
6. 子 Agnet 的运行模型是 Agnet 平台的部署配置,独立于 NewAPI 的用户、Token、Group 扣费映射;NewAPI 不负责决定子 Agnet 使用哪个模型。
|
||
|
||
推荐映射:
|
||
|
||
| Heicode/Agnet 字段 | NewAPI 映射 | 用途 |
|
||
|------|------|------|
|
||
| `user.id` / JWT `sub` | NewAPI user ref | 标识调用归属用户 |
|
||
| `channelId` | NewAPI channel/user/group 绑定 | 关联模型渠道、额度或扣费策略 |
|
||
| 绑定 Git 仓库 | request metadata | 审计某次开发任务来源 |
|
||
| 预算或用量限制 | token quota 或 group policy | 限制本次任务可消耗额度 |
|
||
|
||
子 Agnet 角色、运行模型和实例数量应放在 Agnet 平台 deployment/runtime 配置里,不放进 NewAPI 扣费对象里。
|
||
|
||
## 五、传给 Agnet 平台的用户与扣费上下文
|
||
|
||
Manager 请求 Agnet 平台部署或执行任务时,应携带登录用户上下文,但不携带真实密钥。
|
||
|
||
建议传递结构:
|
||
|
||
```json
|
||
{
|
||
"request_id": "req_20260504_demo",
|
||
"user_context": {
|
||
"user_id": "123",
|
||
"email": "user@example.com",
|
||
"role": "user",
|
||
"channel_id": "channel_abc",
|
||
"subscription_tier": "pro"
|
||
},
|
||
"billing_context": {
|
||
"provider": "newapi",
|
||
"newapi_user_ref": "newapi_user_123",
|
||
"newapi_group": "development",
|
||
"quota_ref": "newapi_token_or_group_quota_ref"
|
||
},
|
||
"agent_runtime": {
|
||
"platform": "agnet",
|
||
"agents": [
|
||
{
|
||
"role": "backend",
|
||
"model_ref": "agnet_model_profile_backend",
|
||
"instance_count": 1
|
||
}
|
||
]
|
||
},
|
||
"work_context": {
|
||
"input": "用户输入的产品想法或任务目标",
|
||
"git_bindings": [
|
||
{
|
||
"resource_id": "res_git_1",
|
||
"repo_url": "https://example.com/org/repo.git",
|
||
"ref": "main",
|
||
"allowed_paths": ["services/**"],
|
||
"allowed_actions": ["read", "write"]
|
||
}
|
||
]
|
||
},
|
||
"secret_context": {
|
||
"secret_refs": ["vault://secret/resources/res_git_1"],
|
||
"inject_short_lived_credentials": true,
|
||
"approval_id": "approval_123"
|
||
}
|
||
}
|
||
```
|
||
|
||
这里的 `user_context` 用于确认身份,`billing_context` 用于 NewAPI 余额、用量和扣费映射,`agent_runtime` 用于 Agnet 平台独立选择子 Agnet 模型和实例数量,`work_context` 用于团队开发控制,`secret_context` 只传 `secret_ref` 和审批结果。
|
||
|
||
Agnet 平台执行时,应把用户、角色、Git 绑定、deployment、Agnet model profile 和 NewAPI 映射写入 metadata 或审计日志。真实 NewAPI key 和 OpenBao 凭证由平台安全通道读取,不进入 Markdown。
|
||
|
||
## 六、当前主线结论
|
||
|
||
- 用户输入在 Manager/客户端,不在 NewAPI 后台。
|
||
- Manager User 复用 Heicode/Agnet 登录体系。
|
||
- Manager 不自行发明 tenant/project 作为当前团队或扣费边界。
|
||
- 团队开发控制优先由绑定 Git、允许路径、Agnet 角色、资源授权表达。
|
||
- 子 Agnet 的运行模型由 Agnet 平台独立配置,不和 NewAPI 扣费对象混在一起。
|
||
- NewAPI 负责模型网关、用户/Token/Group 额度、余额、日志和扣费。
|
||
- OpenBao 负责长期密钥托管,子 Agnet 只拿短期、最小权限、可审计凭证。
|
||
- 高危操作审批发生在客户端,审批结果随任务上下文传给 Manager/Agnet 平台。
|