diff --git a/docs/README.md b/docs/README.md index b68c930..ed4517a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,6 +6,7 @@ |------|------| | [`heicode.md`](./heicode.md) | Heicode 当前产品定位、系统边界和架构共识 | | [`plan.md`](./plan.md) | 按当前共识拆出的实施计划 | +| [`heicode-runtime-auth-newapi-secret-design.md`](./heicode-runtime-auth-newapi-secret-design.md) | 用户输入、登录用户复用、NewAPI 扣费映射、OpenBao 短期凭证注入边界 | | [`integration/Heicode-登录接口对接文档.md`](./integration/Heicode-登录接口对接文档.md) | 已上线登录接口对接文档 | | [`integration/agnet-platform-request-contract.md`](./integration/agnet-platform-request-contract.md) | Manager 请求 Agnet 平台时携带的部署、日志、监控、事件与审计接口参数 | | [`deployment/azure-production-deploy-guardrails.md`](./deployment/azure-production-deploy-guardrails.md) | Azure VM / PostgreSQL / Redis / Agnet / NewAPI 生产部署前的安全守卫、环境变量注入和验证计划 | diff --git a/docs/heicode-runtime-auth-newapi-secret-design.md b/docs/heicode-runtime-auth-newapi-secret-design.md new file mode 100644 index 0000000..6a96c13 --- /dev/null +++ b/docs/heicode-runtime-auth-newapi-secret-design.md @@ -0,0 +1,191 @@ +# 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 平台才可以执行对应动作。 + +密钥处理边界如下: + +```text +长期密钥 +-> 用户授权或绑定资源 +-> Manager 写入 OpenBao +-> Manager DB 只保存 secret_ref + +高危操作 +-> 客户端审批 +-> Manager/Agnet 平台按 secret_ref 从 OpenBao 获取或派生短期凭证 +-> 短期凭证可注入子 Agnet +-> 子 Agnet 完成任务后凭证过期或撤销 +``` + +允许注入子 Agnet 的只能是短期、最小权限、可审计的凭证。长期 Git token、云 access key、SSH 私钥、数据库密码、NewAPI key 原文不得进入 Git、Markdown、普通日志或长期 Agnet 状态。 + +短期凭证注入必须满足: + +- 有客户端审批记录。 +- 有 `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 平台。 diff --git a/docs/heicode.md b/docs/heicode.md index 8bccb8d..fa379a5 100644 --- a/docs/heicode.md +++ b/docs/heicode.md @@ -21,7 +21,7 @@ Heicode 的最终形态是一款覆盖软件生命周期的智能开发 Code 工 | 系统 | 定位 | 负责内容 | |------|------|----------| -| Heicode Manager | SaaS 用户控制台与编排中枢 | 用户、租户、项目、资源绑定、权限分配、Agnet 部署、审计、模型与余额展示 | +| Heicode Manager | SaaS 用户控制台与编排中枢 | 用户输入、资源绑定、权限分配、Agnet 部署、审计、模型与余额展示 | | Agnet 平台 | 执行与状态平台 | 在 AKS 上部署子 Agnet、运行任务、维护状态、事件、日志和执行元数据 | | NewAPI | 内部模型网关与计费服务 | 模型渠道、模型调用、额度、余额、调用日志;后台不对普通用户开放 | | Secret Store | 凭证保管库 | 保存 Git token、云密钥、SSH key、数据库密码等真实凭证 | @@ -33,13 +33,14 @@ Manager 是用户操作入口;Agnet 是运行时执行层;NewAPI 是模型 1. 在需求和边界没有想清楚前,不改代码。 2. NewAPI 保持独立服务,不继续改造成 Manager 的内嵌后台。 3. NewAPI 后台不开放给普通 SaaS 用户,模型管理由内部人员完成。 -4. Manager 只补 NewAPI 没有的后端能力:项目、资源、权限、Agnet 部署、审计和生命周期管理。 +4. Manager 只补 NewAPI 没有的后端能力:用户输入编排、资源绑定、权限、Agnet 部署、审计和生命周期管理。 5. 用户绑定的是 Agnet 可用资源,不只是 Git 来源。 6. 密钥不能进入 Git、Markdown、前端、部署摘要或日志。 7. Manager 负责资源绑定、权限分配和凭证托管能力;真实密钥放入 Secret Store。 8. 子 Agnet 不保存长期密钥,只接收角色、资源元数据、AGENT.md 和受控访问方式。 9. Agnet 平台在 AKS 上负责运行时身份、隔离、状态、事件和审计回传。 -10. 高危生产权限优先走平台代理或审批,不直接把长期密钥注入子 Agnet。 +10. 高危操作审批只在客户端完成;审批通过后可以把 OpenBao 派生的短期、最小权限凭证注入子 Agnet,但不能注入长期密钥。 +11. 子 Agnet 的运行模型是 Agnet 平台的部署配置,独立于 NewAPI 的用户、Token、Group 扣费映射。 ## 四、Manager 的核心功能 @@ -56,7 +57,7 @@ Manager 是用户操作入口;Agnet 是运行时执行层;NewAPI 是模型 ## 五、资源绑定与密钥托管 -绑定不是保存一串密钥,而是创建租户级 Resource Grant。 +绑定不是保存一串密钥,而是创建面向登录用户、绑定 Git/SK/云资源和子 Agnet 角色的 Resource Grant。 ```text 用户授权 Heicode 使用外部资源 @@ -86,7 +87,7 @@ Resource Binding 建议字段: | 字段 | 含义 | 约束 | |------|------|------| | `id` | 资源绑定 ID | Manager 内部生成 | -| `tenant_id` | 租户 ID | 必填,所有资源租户隔离 | +| `user_id` | 登录用户 ID | 来自 Heicode/Agnet 登录体系的 `user.id` 或 JWT `sub` | | `type` | 资源类型 | `git`、`sk`、`project_doc`、`cloud_account`、`cloud_resource` | | `name` | 用户可见名称 | 不包含密钥 | | `external_ref` | 外部资源定位 | repo URL、subscription ID、resource ID、文档引用等非密钥标识 | @@ -102,7 +103,7 @@ Resource Grant 建议字段: | 字段 | 含义 | 约束 | |------|------|------| | `id` | 授权 ID | Manager 内部生成 | -| `tenant_id` / `project_id` | 授权归属 | 必填 | +| `user_id` / `binding_scope` | 授权归属 | 来自登录用户、绑定 Git/SK/云资源和角色范围 | | `resource_id` | 被授权资源 | 指向 Resource Binding | | `role` | 子 Agnet 角色 | 例如 product、frontend、backend、reviewer、ops | | `agent_id` | 子 Agnet 标识 | 可为空;为空表示授予该项目角色下的下一次部署 | @@ -116,8 +117,8 @@ P1 permission manifest 示例: ```json { - "tenant_id": "tenant_demo", - "project_id": "project_demo", + "user_id": "user_demo", + "binding_scope": "repo_demo:main", "agent_role": "backend", "resource_grants": [ { @@ -129,7 +130,7 @@ P1 permission manifest 示例: "ref": "main", "paths": ["services/api/**"] }, - "secret_ref": "secret://tenant_demo/git/repo_demo" + "secret_ref": "vault://secret/resources/repo_demo" } ] } @@ -146,13 +147,13 @@ SaaS 场景下,凭证不能转嫁给用户手工管理。用户负责授权, | 方案 | 判断 | |------|------| | HashiCorp Vault | 优先选择。Kubernetes Auth、Policy、TTL、动态密钥、审计能力成熟,适合 AKS 中的子 Agnet 运行时授权 | -| Infisical | 可选方案。产品体验较好,但需要验证多租户策略和运行时授权能力 | +| Infisical | 可选方案。产品体验较好,但需要验证 SaaS 多用户隔离策略和运行时授权能力 | | Azure Key Vault | 适合 Azure 优先部署,也可以作为 Secret Provider 的一种实现 | Secret Broker 负责: - 接收 OAuth、GitHub App、云授权回调后的凭证。 -- 生成租户隔离的 secret path。 +- 生成按用户、资源和角色隔离的 secret path。 - 写入 Vault、Infisical 或 Azure Key Vault。 - 创建或更新 policy。 - 保存 `secret_ref` 到 Manager DB。 @@ -182,9 +183,9 @@ Agnet 平台底层是 AKS,因此运行时权限应和 Kubernetes 身份绑定 | 模式 | 适用 | |------|------| | 受控注入 | Git clone、开发/测试环境、低风险资源 | -| 平台代理 | 生产部署、数据库写入、高危云操作、需要审批的动作 | +| 短期凭证注入 | 已经客户端审批的生产部署、数据库写入、高危云操作 | -普通开发资源可受控注入,生产云资源和高危操作走平台代理或审批。 +普通开发资源可受控注入;生产云资源和高危操作也只在客户端审批通过后,注入 OpenBao 派生的短期、最小权限凭证。 ## 八、NewAPI 边界 @@ -193,7 +194,7 @@ NewAPI 不作为普通用户后台开放。Manager 后端通过服务凭据调 Manager 可展示: - 可用模型。 -- 当前租户或项目额度。 +- 当前用户、Token 或 Group 额度。 - 余额。 - 调用量。 - 调用日志。 @@ -208,7 +209,7 @@ Manager 不展示: - 系统管理员用户管理。 - NewAPI 原生管理后台入口。 -用户登录 Manager,不直接登录 NewAPI。Manager 需要维护用户、租户、项目到 NewAPI 用户、key 或 quota 的映射。 +用户登录 Manager,不直接登录 NewAPI。Manager User 复用 Heicode/Agnet 登录体系,并维护 `user.id`、`channelId` 到 NewAPI 用户、Token、Group、quota 或 usage 的映射。当前不要把 Manager tenant/project 作为扣费和团队开发控制主轴;团队开发控制优先由绑定 Git、路径范围、资源授权和 Agnet 角色表达。子 Agnet 的模型选择、模型 profile 和实例数属于 Agnet 平台部署配置,不放进 NewAPI 扣费对象里。 ## 九、Markdown 与权限清单 diff --git a/docs/plan.md b/docs/plan.md index 26554ee..d682b6e 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -29,7 +29,7 @@ - 将当前 Git 来源抽象为资源绑定模型。 - 增加资源类型:Git、SK、项目文档、云账号、单项云资源。 -- 增加 Resource Grant,用于把资源分配给项目、角色和子 Agnet。 +- 增加 Resource Grant,用于把资源分配给登录用户、绑定 Git/SK/云资源范围、角色和子 Agnet。 - 定义资源元数据、权限范围、约束、状态和审计字段。 - 前端从单点功能页逐步走向“绑定资源 -> 分配角色 -> 部署确认”的主流程。 @@ -38,21 +38,21 @@ 最小可验证实现: 1. 后端先落库资源绑定和 Resource Grant 两类记录,不在本阶段实现 Secret Broker 的真实写入。 -2. Resource Binding 表达租户级资源元数据:资源类型、名称、外部标识、可见元数据、权限范围、约束、状态、`secret_ref` 和审计字段。 -3. Resource Grant 表达项目级授权关系:tenant、project、resource、role、子 Agnet 标识、允许动作、限制条件、状态、过期时间和审计字段。 +2. Resource Binding 表达登录用户绑定的资源元数据:资源类型、名称、外部标识、可见元数据、权限范围、约束、状态、`secret_ref` 和审计字段。 +3. Resource Grant 表达授权关系:user、resource、binding scope、role、子 Agnet 标识、允许动作、限制条件、状态、过期时间和审计字段。 4. 提供只返回元数据和 `secret_ref` 的列表、详情、创建、授权、撤销接口;任何接口响应、日志和 Markdown 产物都不得包含真实密钥。 -5. 生成一份 permission manifest 示例,用结构化数据证明“某租户的某项目,把某资源授予某个子 Agnet 角色使用”。 +5. 生成一份 permission manifest 示例,用结构化数据证明“某登录用户把某个绑定资源授予某个子 Agnet 角色使用”。 验收: -- Manager 能表达“某租户的某项目,把某资源授予某个子 Agnet 角色使用”。 +- Manager 能表达“某登录用户把某个绑定资源授予某个子 Agnet 角色使用”。 - 数据库不保存明文密钥,只保存 `secret_ref`。 - P1 测试样例能覆盖 Git、SK、项目文档、云账号和单项云资源五类资源的元数据建模。 - 撤销 Resource Grant 后,对应 permission manifest 不再包含该授权。 ## P2:Secret Broker 与 Secret Store -目标:建立 SaaS 多租户凭证托管能力。 +目标:建立 SaaS 多用户凭证托管能力。 任务: @@ -76,10 +76,10 @@ - Agnet 平台支持 deployment / role 到 Kubernetes ServiceAccount 的映射。 - 支持 Vault Kubernetes Auth 或等价 Workload Identity。 -- 支持按 tenant / project / role 生成 Vault policy。 +- 支持按 user / resource binding / role 生成 OpenBao policy。 - 子 Agnet 运行时只能访问被授权的 secret。 - 普通开发资源支持受控注入。 -- 生产云资源和高危操作走平台代理或审批。 +- 高危操作审批只在客户端完成;审批通过后允许向子 Agnet 注入 OpenBao 派生的短期、最小权限凭证。 验收: @@ -98,7 +98,8 @@ - Manager 通过服务凭据调用 NewAPI。 - Manager 展示普通用户需要的模型、余额、额度、调用日志。 - 隐藏渠道管理、价格配置、模型供应商后台配置和 NewAPI 管理员能力。 -- 建立 Manager tenant / user / project 与 NewAPI user / key / quota / usage 的映射。 +- 建立 Heicode/Agnet 登录用户 `user.id`、`channelId` 与 NewAPI user / token / group / quota / usage 的映射。 +- 子 Agnet 的运行模型、模型 profile 和实例数归 Agnet 平台部署配置管理,不和 NewAPI 扣费映射混用。 验收: