Files
YG_FT/docs/权限开发进度.md

494 lines
42 KiB
Markdown
Raw Normal View History

# 权限开发进度
> 更新时间2026-08-20
> 适用范围YG_FT 平台当前主工程、Backend、Frontend、Compute Agent、MinIO 资源访问及 `docker/offline/src` 离线源码。
> 当前结论:权限 2.0 的核心功能已形成闭环。本轮继续补齐租户成员角色在 ACL 中的实际判定、有效期租户隔离、用户软删除、资源/MinIO 对象待清理、训练模型预加载资源存在性校验和推理状态接口授权,并已执行在线数据库迁移。自动化权限/存储安全用例、前端构建、后端静态检查、容器健康和用户删除闭环均已验证。由于当前只有一个可达算力节点,跨租户双用户、第二节点/多卡并发、节点故障回收和 MinIO 故障注入仍需专项验证,因此保留为上线前场景。按工作包估算,核心权限开发约完成 98%,上线验收约完成 82%。
## 本轮 11 项完成情况2026-08-19
| 编号 | 权限能力 | 完成内容 | 状态 |
|---|---|---|---|
| 1 | 审批决策安全 | 审批人从当前会话获取,校验指定审批人、租户管理员、禁止申请人自审,记录审批审计 | 已完成 |
| 2 | 资源访问申请 | 新增资源访问申请记录、申请权限/期限/理由、审批后自动写入 ACL、支持撤回和过期 | 已完成 |
| 3 | 审批策略执行 | 按租户、动作、资源类型匹配策略;高风险操作审批通过后可一次性重试执行 | 已完成 |
| 4 | 租户与项目隔离 | `tenant_members`、活跃租户校验、历史资源归属补齐、跨租户 ACL 主体校验、项目软删除 | 已完成 |
| 5 | 用户与角色边界 | 禁用用户立即注销会话;租户成员支持 owner/admin/member/viewer保护最后一个 owner | 已完成 |
| 6 | 数据集权限入口 | 预览、来源、版本查询/创建/激活/删除、上传/编辑/下载统一接入资源动作权限 | 已完成 |
| 7 | 模型和推理权限 | 训练模型合并/导出分别校验 execute/download聊天、预加载、批量、卸载绑定授权模型或推理任务 | 已完成 |
| 8 | GPU 分配申请 | 普通用户可提交 GPU 分配申请,审批通过后自动分配;管理员可直接分配 | 已完成 |
| 9 | 租户配额申请 | 租户成员可提交配额变更申请,平台管理员审批后自动更新配额 | 已完成 |
| 10 | 软删除与安全状态 | 资源删除撤销 ACL、取消待处理申请和审批租户/项目采用软删除状态 | 已完成 |
| 11 | 前端按钮与审计 | 审批决策、ACL 编辑、访问申请/撤回按权限显示下载、导出、审批、GPU 等敏感操作补充结构化审计 | 已完成 |
### 数据库迁移结果
- 新增增量迁移:`backend/app/db/sql/009_permission_completion.sql`,可独立兼容旧库执行,并已在当前远程 PostgreSQL 执行成功。
- 当前远程库已核验包含:`tenant_members``resource_access_requests`、审批策略/执行状态字段、审计结果字段、ACL 生命周期字段、项目/租户软删除字段、数据转换任务租户字段。
- 已有用户已补齐到 `tenant_members`,当前迁移后共生成 5 条租户成员关系。
- `backend/app/db/sql/000_full_init.sql` 已合并完整结构;离线目录继续只保留该完整脚本。
### 验证结果
- 后端相关模块 `python -m py_compile`:通过。
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径提示和大 chunk 警告,无 TypeScript 错误。
- `docker/offline/src` 的后端权限代码、Compute Agent、前端源码和完整初始化 SQL 已与主工程关键文件哈希一致。
- 运行中的 Backend、Frontend、Compute API 容器已重启,健康检查通过;当前容器采用源码挂载方式,无需重建镜像即可加载本轮代码。已验证健康接口可用,未登录访问受保护接口返回 401完整双用户、跨租户和多 GPU 回归仍待执行。
## 一、检查依据
本次按代码和初始化脚本逐项核对,主要依据如下:
- `docs/permissions-design.md`
- `backend/app/core/auth.py`
- `backend/app/api/v1/endpoints/platform.py`
- `backend/app/modules/resource/router.py`
- `backend/app/modules/approval/router.py`
- `backend/app/modules/tenant/router.py`
- `backend/app/modules/system/router.py`
- `backend/app/db/platform_store.py`
- `backend/app/db/sql/000_full_init.sql`
- `frontend/src/stores/auth.ts`
- `frontend/src/router/index.ts`
- `frontend/src/views/governance/ResourceAclView.vue`
检查口径不是只判断“是否有接口”,还检查了接口是否验证当前用户、是否校验资源所有权和 ACL、是否校验租户边界、审批结果是否真正改变授权、前端按钮是否与后端动作一致。
## 二、改造前总体进度(历史基线)
| 能力模块 | 当前状态 | 结论 |
|---|---|---|
| 登录、密码、Token 会话 | 已实现基础能力 | 有会话过期、注销、状态校验和登录限流基础,仍需统一续期和失败审计 |
| 平台角色与权限码 | 部分实现 | `admin/operator/viewer` 和业务权限码存在,但后端部分业务只校验登录,未统一校验权限码 |
| 用户创建与管理 | 部分实现 | 管理员可创建、修改、删除和重置密码;租户范围、角色边界、邀请/申请流程未完成 |
| 租户与配额 | 部分实现 | 租户 CRUD、配额和留存策略接口为管理员专属缺少租户成员、租户管理员和统一隔离 |
| 资源 ACL | 已实现基础能力 | 支持用户/角色的 `read/write/execute/download/delete/admin`,授权边界和跨租户限制不足 |
| 资源申请 | 未完整实现 | 没有独立的资源访问申请对象,现有审批实例不能可靠地落地 ACL 或配额变更 |
| 资源审批 | 部分实现且存在安全缺口 | 模板、实例、步骤和部分高风险操作存在;审批决策接口必须先修复越权问题 |
| 基座模型权限 | 平台共享已实现 | 登录用户可查看和使用,上传/修改/删除限制管理员;缺少按租户/用途/配额的精细控制 |
| 训练模型权限 | 部分实现 | 所有者、ACL、删除、合并、推理加载已有校验导出下载动作和派生权限继承还不完整 |
| 数据集权限 | 部分实现且入口不一致 | 列表、详情、删除、部分下载和训练/评测使用有校验;上传、编辑、预览、版本接口仍有缺口 |
| 训练/评测/推理权限 | 部分实现 | 资源执行权和 GPU 分配已有基础校验;部分聊天、状态和历史入口没有统一鉴权 |
| GPU 与节点权限 | 基础能力已实现 | 管理员分配、用户可用 GPU 过滤、原子预留和释放已存在;配额审批和跨节点回收对账仍需完善 |
| 前端按钮级权限 | 部分实现 | 页面和菜单有基础控制,资源动作没有集中式权限决策,很多按钮依赖后端报错 |
| 审计与软删除 | 部分实现 | 主要写操作有审计资源软删除已覆盖若干表actor、下载、拒绝和跨租户查询仍需统一 |
## 三、已经实现的内容
### 3.1 认证、角色与用户
- `get_current_user` 会校验 Bearer Token、用户存在性、用户状态和会话有效期`sessions` 支持注销和过期时间。
- `require_admin` 对管理员专属接口提供后端保护,受保护用户也具备管理员旁路能力。
- 用户列表、创建、修改、删除、重置密码均已增加管理员依赖;用户可修改自己的密码。
- 用户记录包含 `tenant_id``role``permissions``protected` 等字段,角色权限在初始化脚本中有基础种子数据。
- 登录失败限流和旧明文密码升级已经具备基础实现。
### 3.2 租户、资源和 ACL
- `tenants` 表和租户 CRUD、配额、留存策略接口已经存在当前接口统一要求管理员。
- 数据集、模型、训练模型、评测任务等核心资源已经具备 `created_by``tenant_id` 或任务 payload 中的归属信息。
- `acls` 表支持用户和角色两类授权主体,权限包括 `read``write``execute``download``delete``admin`
- 资源 ACL 查询和全量替换接口已经存在,资源所有者或管理员可以管理 ACL。
- 列表接口对数据集、评测、训练和推理任务已增加“本人资源 + ACL 授权资源”的过滤逻辑。
- MinIO 预签名、资源清单、对象列表、模型制品、模型血缘和评测报告等新入口已增加登录和资源访问校验。
### 3.3 训练、评测、推理和 GPU
- 训练创建会检查训练数据集的 `execute` 权限,并对用户选择的 GPU 执行分配校验。
- 评测创建会检查训练模型、数据集的 `execute` 权限,并校验算力节点和 GPU。
- 推理任务加载会检查任务及训练模型的执行权,同时使用 `gpu_reservations` 防止同一张 GPU 被并发占用。
- GPU 分配接口和用户可用 GPU 查询已经存在,失败、停止、删除、节点异常等路径具备基础释放逻辑。
- 训练模型删除、训练任务停止/删除、评测任务删除和推理任务删除已接入部分审批拦截。
- 权重合并、导出、缓存准备和 MinIO 归档已经能记录模型、节点、租户和部分血缘信息。
### 3.4 审计和前端
- `audit_logs``operation_logs` 表及管理员查询/导出页面已经存在。
- 资源 ACL 变更、租户管理、模型/数据集/任务等主要写操作已经接入审计或操作日志装饰器。
- 前端路由和侧边栏对治理、组织、资源授权、审批、日志、算力节点等页面做了管理员限制。
- `ResourceAclView` 已支持资源类型、用户/角色主体和多权限编辑。
## 四、改造前未实现或存在明显安全缺口(历史基线)
> 本节保留本轮改造前的检查快照,不代表当前状态。当前剩余问题以“十、当前仍需开发的功能”和“十一、下一步开发计划”为准。
以下项目属于必须继续开发的内容,优先级高于页面样式和性能优化。
### 4.1 审批决策不能直接信任请求参数
`backend/app/modules/approval/router.py` 的审批决策接口当前没有 `get_current_user` 依赖,并且从请求体读取 `approver_id`。调用方可以伪造审批人 ID属于高风险越权问题。
必须改为:服务端从当前会话取得审批人;校验其是否为当前步骤指定审批人、租户管理员或平台管理员;校验当前步骤、实例状态和申请人不能自审;审批通过后再执行对应动作或写入 ACL。
### 4.2 资源申请流程尚未形成
当前有 `approval_templates``approval_instances``approval_steps`,但没有独立的资源访问申请记录,也没有统一的“申请资源 -> 审批 -> 授权/配额变更”事务流程:
- 创建审批实例时未统一验证资源是否存在、申请人是否属于资源租户、申请动作是否合法。
- 审批实例批准后不会自动创建 ACL、GPU 分配或租户配额变更。
- 不能表达申请权限、申请期限、申请原因、审批后的 ACL 权限和撤销时间。
- 审批模板查询和详情接口没有完整的租户/角色范围控制。
### 4.3 租户隔离不是全量强制
- 当前用户只有单一 `tenant_id`,没有 `tenant_members` 或租户角色关系;无法支持租户管理员、跨租户平台管理员和成员邀请的清晰边界。
- `filter_accessible_resource_ids` 和批量版本主要按 ACL/所有者过滤,不在统一函数中校验资源租户。
- 数据集、评测等查询仍对 `tenant_id IS NULL` 做兼容放行;历史数据未完成归属迁移。
- `trained_models()` 没有统一 tenant 参数,资源过滤依赖上层二次处理。
- ACL 设置接口没有校验授权主体和资源是否属于同一租户,存在跨租户授权风险。
- 新建模型、数据集、任务虽然多数会补默认租户,但缺少“租户必须存在且处于 active”的统一校验。
### 4.4 数据集权限入口不一致
核心列表、详情、删除、部分下载已校验,但以下文件/版本接口当前未统一接入当前用户和资源权限:
- 文件预览和记录来源查询。
- 文件版本列表、版本内容查询。
- 创建、激活、删除数据集文件版本。
- 数据集上传接口没有统一的当前用户、写权限和租户校验。
- 数据集编辑接口没有统一的当前用户和写权限校验。
此外,数据集下载和单文件下载目前检查的是 `read`,没有严格使用设计中的独立 `download` 权限。
### 4.5 模型使用、导出和推理入口不一致
- 基座模型按平台共享资源处理,登录用户可以查看和使用;但模型名称查询、本地模型列表和部分本地聊天/状态/卸载入口缺少统一鉴权。
- 训练模型列表、详情、合并和加载已有 ACL 校验,但导出接口实际属于下载/外发动作,不能只检查 `execute`
- 评测报告下载当前检查 `read`,应单独检查 `download` 并记录下载审计。
- 训练模型由训练任务生成时,尚未完整实现“基座模型 + 数据集授权关系”向派生模型权限和血缘策略的统一继承。
- 推理聊天接口没有始终绑定到已授权的推理任务、模型资源和指定算力节点,存在绕过模型使用流程的风险。
### 4.6 用户创建和角色边界不完整
- 当前只有平台管理员创建用户,普通用户不能申请加入租户,也没有邀请、审批、禁用后会话清理的完整流程。
- 用户只能直接挂在一个 `tenant_id` 上,不能表达一个用户属于多个租户或在不同租户中拥有不同角色。
- 后端 `create_user` 对非管理员角色会归一为普通用户,前端出现的 `operator` 角色与后端实际行为可能不一致。
- 创建用户时缺少租户存在性、租户状态、租户用户配额和角色白名单校验。
- 管理员可以创建管理员角色,尚未区分平台管理员和租户管理员的授予权限。
### 4.7 前端按钮级权限没有闭环
- 前端已有菜单和路由权限基础,但 `hasPermission` 没有覆盖所有业务路由动作,部分业务页对已登录用户直接开放。
- 资源级按钮主要靠资源对象中的所有者字段判断,没有统一使用后端返回的 ACL 决策。
- 下载、执行、删除、授权、导出、审批等动作没有统一的 `can(resource, action)` 机制。
- 即使按钮隐藏,前端 API 模块仍可能直接调用敏感接口;必须以后端鉴权为最终边界。
### 4.8 审计、软删除和权限拒绝记录不完整
- 部分模块的 `_actor` 直接保存 Authorization Token而不是规范的用户 ID导致审计主体不一致。
- 访问、下载、导出、ACL 授权、审批拒绝、GPU 分配和权限拒绝没有全部统一记录租户、资源和结果。
- `record_visit` 公开接口容易被伪造;如果继续保留匿名访问,应明确它不是安全审计日志。
- 资源软删除已覆盖模型、训练模型、数据集、评测任务等主要表,但关联 MinIO 对象、ACL、审批和血缘的延迟清理策略还不完整。
## 五、需要优化的现有流程
### 5.1 统一权限模型
将当前分散的 `is_admin`、所有者判断、ACL 查询、租户判断、GPU 判断收敛为统一服务:
```text
认证 -> 平台/租户角色 -> 租户边界 -> 资源所有权/ACL -> 动作权限 -> GPU/配额 -> 审批 -> 审计
```
每个敏感接口都应明确动作,例如 `dataset.read``dataset.download``dataset.execute``trained_model.export``inference.load``gpu.reserve`,禁止只使用“已登录”作为业务权限。
### 5.2 重新设计资源申请和审批
推荐流程:
```text
申请人选择资源和动作
-> 校验申请人所属租户和基础权限
-> 创建 resource_access_requests
-> 根据租户/资源类型匹配审批策略
-> 指定审批人完成审批
-> 事务内写入 ACL/配额/GPU 预留
-> 记录授权有效期、来源和审计
```
审批拒绝、撤回、过期和资源删除都应撤销或冻结对应授权,不能仅修改审批实例状态。
### 5.3 模型、数据集、训练任务联合授权
训练、评测、推理分别使用以下最小权限:
| 场景 | 必须具备的权限 |
|---|---|
| 查看基座模型 | `model.read`;基座模型默认平台共享 |
| 使用基座模型训练 | `model.execute` 或平台共享策略 + 数据集 `execute` |
| 下载基座模型 | 单独的 `model.download`,默认不授予 |
| 使用训练模型推理 | `trained_model.execute` |
| 下载/导出训练模型 | `trained_model.download``trained_model.export` |
| 使用数据集训练/评测 | `dataset.execute` |
| 查看数据集 | `dataset.read` |
| 下载数据集文件 | `dataset.download` |
| 创建训练任务 | 上述资源权限 + 指定节点/GPU 使用权 + 租户配额 |
训练模型应保留创建者、租户、基座模型、数据集、训练任务和资源版本快照。派生模型默认只对创建者和同租户授权,不应因为基座模型共享而自动公开训练产物。
## 六、建议的数据库改造
当前 `000_full_init.sql` 已包含用户、角色、会话、ACL、租户、审批、审计、GPU 分配和 GPU 预留表,但要完成权限 2.0,建议增加或扩展以下结构。实施时必须同步主工程和 `docker/offline/src/backend/app/db/sql/000_full_init.sql`
1. `tenant_members`:用户、租户、租户角色、状态、加入来源和有效期,解决一个用户多租户和租户管理员问题。
2. `resource_access_requests`:申请人、租户、资源、动作、申请原因、申请权限、有效期、审批状态和最终授权记录。
3. `acls` 增加 `tenant_id``granted_by``source_request_id``expires_at``revoked_at`,保留授权来源和自动过期能力。
4. `approval_templates` 增加 `tenant_id``action``resource_type``scope``status`;审批步骤增加主体类型、主体 ID 和租户范围。
5. 资源表统一补齐非空租户策略、归属用户、软删除字段和必要索引;历史 NULL 数据通过一次性迁移处理。
6. `audit_logs` 增加结果、拒绝原因、request_id、认证会话和结构化 detail避免把 Token 当作 actor。
不建议把完整 ACL 和审批状态继续塞入模型、数据集或任务 JSON 字段JSON 可保留兼容信息,但权限判断应以结构化表为准。
## 七、历史开发计划(已执行)
### 第一阶段P0 安全修复
- 修复审批决策鉴权和审批人伪造问题。
- 补齐数据集文件/版本/上传/编辑接口权限。
- 补齐本地模型聊天、状态、卸载、模型名称查询等历史入口鉴权。
- 统一 `download``execute``write``delete` 动作检查。
- 限制 ACL 授权范围,校验主体存在、同租户和资源归属。
- 增加至少 20 个后端权限回归用例,覆盖未登录、本人、同租户他人、跨租户、管理员和已撤销 ACL。
### 第二阶段P1 租户和资源申请
- 引入租户成员和租户角色,明确平台管理员、租户管理员、成员、只读成员边界。
- 开发资源访问申请接口和前端申请页面。
- 重做审批模板匹配、审批人校验、审批结果落地 ACL、有效期和撤销流程。
- 将配额申请、GPU 分配申请、模型导出和跨用户删除纳入审批策略。
- 新资源强制租户归属并完成历史数据迁移。
### 第三阶段P1 联合资源权限
- 建立模型/数据集/训练任务/评测任务/推理任务的统一资源授权服务。
- 训练前一次性校验基座模型、数据集、节点、GPU 和租户配额。
- 训练模型生成时写入血缘和权限来源;推理、评测、合并、导出使用同一套动作权限。
- 版本快照、MinIO 对象、算力节点本地缓存沿用同一资源授权结果。
### 第四阶段P2 前端和审计
- 增加统一 `can(resource, action)` 和按钮权限组件。
- 授权和审批界面使用用户/租户/资源中文名称,展示授权来源、有效期和审批状态。
- 规范审计 actor、租户、请求 ID、资源、动作、结果和失败原因。
- 将权限不足、审批中、资源过期、MinIO 不可用分别展示,避免全部显示为通用 500。
### 第五阶段P3 测试与上线
- 新库初始化、增量迁移、离线目录同步和前端构建全部纳入 CI。
- 执行跨租户、跨用户、ACL 撤销、审批越权、软删除、MinIO 故障和 GPU 冲突专项测试。
- 在第二个可达节点或多卡节点到位后,执行多节点、多 GPU 的权限和并发测试。
- 补充权限运维手册:新建租户、创建用户、授权模型/数据集、审批、撤销权限、审计追踪和故障恢复。
## 八、验收标准
- 未登录用户不能访问任何模型、数据集、任务、聊天、版本、下载和审批接口。
- 用户只能访问所属租户中本人拥有或被明确授权的资源;跨租户 ACL 默认禁止。
- 查看、下载、执行、编辑、删除和授权是独立动作,不能用 `read` 替代所有动作。
- 普通用户不能伪造审批人、审批其他租户资源或审批自己的申请。
- 训练、评测和推理创建必须同时满足资源权限、GPU 权限、节点权限和租户配额。
- 审批通过后才产生授权,审批拒绝、撤回、过期和资源删除后授权不会继续生效。
- 基座模型共享不等于训练产物共享;训练后的模型和数据集必须按租户、所有者和 ACL 控制。
- 前端隐藏按钮不能替代后端校验,直接调用 API 也必须返回明确的 401/403。
- 所有敏感操作可通过用户、租户、资源、动作和请求 ID追溯到审计记录。
## 九、历史实施记录(已完成)
本轮已完成权限闭环的代码实现:
1. 统一校验当前会话、会话过期、退出状态和可用租户范围。
2. 补齐模型、数据集、训练、评测、推理、数据处理、数据转换、算力、存储和审计入口的登录及模块权限。
3. 新增 `tenant_members`,新建用户、项目、数据集、训练任务和数据处理任务写入当前租户与创建者。
4. ACL 写入校验主体存在性、状态、租户边界、有效期和撤销状态;普通所有者不能授予 `delete/admin` 或跨租户权限。
5. 新增 `resource_access_requests`;审批人由当前会话确定,禁止伪造审批人和申请人自审;审批通过后才落 ACL。
6. 训练、评测和推理统一校验数据集、基座模型、训练模型、任务、节点和 GPU 使用权限;下载和导出使用独立的 `download` 权限。
7. 前端认证 store 新增 `can(resource, action)`,模型管理和审批页面按权限显示操作按钮,后端 401/403 仍是最终防线。
8. 新增 `009_permission_completion.sql`;主工程与离线目录的完整初始化 SQL 已同步且 SHA-256 一致,离线目录只保留完整初始化脚本。
### 本轮验证
- 后端权限相关文件 `py_compile` 通过。
- 前端 `npm run build` 通过;仅保留已有字体路径和 chunk size 警告。
- 当前 WSL 容器已确认 Backend、Frontend、Compute、Redis、MinIO 均运行;基础健康和未登录拦截已验证,历史治理测试夹具与当前鉴权/数据库行为不完全兼容,不能替代新的权限专项回归。
### 上线前验证
- 第二个可达节点或多卡节点到位后的多租户、多 GPU 并行压力测试。
- 对已执行的 `009_permission_completion.sql` 进行旧数据租户归属、ACL、审批和软删除记录对账。
- 更新 Backend/Frontend 容器后重新执行治理测试和权限专项测试。
## 十、当前复核结论2026-08-19
### 10.1 已完成的基础能力
本轮 11 项权限改造已经形成基础闭环:会话和用户状态校验、租户成员关系、资源 ACL、资源访问申请、审批决策安全、模型/数据集/训练/评测/推理入口权限、GPU 分配申请、配额申请、软删除和前端基础按钮控制均已落地;数据库迁移和完整初始化 SQL 已同步到主工程及离线目录。
这些能力可以作为后续完善的基础,但“接口存在”不等于“所有资源和所有异常路径均已达到上线标准”。尤其是密钥暴露、配额实际拦截、资源列表一致性和专项测试仍需要继续处理。
### 10.2 仍需开发的功能
| 优先级 | 功能 | 当前缺口 | 处理结论 |
|---|---|---|---|
| P0 | 模型密钥和敏感信息保护 | 模型列表、详情、名称查询、创建和更新响应已移除真实 `api_key`,仍需继续排查任务详情、日志和其他敏感配置输出 | 基础闭环已完成;继续做全量敏感字段扫描和受控密钥管理 |
| P0 | 统一资源动作策略 | 已增加资源动作白名单和 `export -> download` 归一化,但各业务入口仍需逐步迁移到统一授权服务 | 第一阶段已完成;继续完成全量入口收敛 |
| P0 | 数据转换、数据处理和存储权限一致性 | 部分列表、文件、预览、版本、缓存和 MinIO 对象入口仍需逐接口核对“租户 + 所有者/ACL + 动作” | 必须完成全量入口审计,尤其是 `read/download/execute/write/delete` 的区分 |
| P0 | 审计失败链路 | 审计装饰器已记录失败结果、原因、请求 ID、会话 ID 和租户;手工审计入口仍需继续统一 | 基础闭环已完成;继续补齐所有权限拒绝和异常入口 |
| P1 | 租户成员生命周期 | 已有成员表和角色,但缺少邀请、加入申请、审批、过期、移除和前端租户切换的完整流程 | 需要开发,明确平台管理员与租户管理员的授予边界 |
| P1 | 配额强制执行 | 配额申请和审批已实现,但训练、评测、推理、存储等资源消耗尚未全部进行原子配额检查和扣减 | 需要开发配额使用量/预留量/释放量账本,不能只保存配额配置 |
| P1 | GPU 分配强校验 | 申请链路已实现但分配前仍需统一校验节点状态、GPU 存在性、冲突、租户配额和释放对账 | 需要开发原子预留、超时回收和节点故障对账 |
| P1 | 审批策略完整性 | 需要严格限制动作白名单、资源类型、模板作用域和重复申请;过期处理不应只依赖查询触发 | 需要补充定时过期、幂等键、执行失败重试和策略管理边界 |
| P1 | 派生模型和数据血缘授权 | 基座模型、数据集、训练模型之间已有部分血缘,但权限来源、版本快照和派生资源默认授权规则还不够统一 | 需要固化“创建者 + 租户 + 显式 ACL”禁止共享基座模型自动公开训练产物 |
| P1 | 用户软删除和对象清理 | 用户及部分关联关系仍有物理删除风险MinIO 对象、ACL、审批、缓存的异步清理缺少统一编排 | 需要补齐软删除、撤销、延迟清理和失败重试 |
| P2 | 前端资源级权限体验 | 已有菜单/按钮级基础控制,但缺少统一 `can(resource, action)`、授权来源、有效期、审批中和 403 状态展示 | 需要开发统一权限组件和错误状态处理,后端校验仍是最终边界 |
| P2 | 权限专项测试与上线检查 | 基础构建、静态检查、健康接口已验证尚未完成双用户、跨租户、撤销、过期、MinIO 故障、GPU 冲突的全流程矩阵 | 必须补充自动化测试、迁移回归和离线部署验收 |
### 10.3 需要优化的设计
1. **从“角色判断”改为“动作授权”**:统一使用 `resource_type + resource_id + action + tenant_id + actor` 判断,平台管理员只作为明确的管理范围,不再作为各业务模块的隐式旁路。
2. **区分平台角色和租户角色**`users.role` 只表达平台级角色,`tenant_members.role` 表达租户内角色;禁止通过租户成员关系授予平台管理员权限。
3. **区分查看、下载、执行、编辑、删除、授权**`read` 不能替代 `download``execute` 不能替代 `export`,高风险动作必须绑定审批和审计。
4. **统一资源列表和详情规则**:列表、详情、文件、版本、预览、缓存、下载和导出必须调用同一授权服务,避免“列表看不到但接口可访问”或“列表能看到但操作必然 403”。
5. **权限与配额采用预留模型**:任务提交时原子预留 GPU、显存、并发数和存储额度任务完成、失败、取消和节点失联时统一释放或对账。
6. **审批采用可执行状态机**:申请、审批、拒绝、撤回、过期、执行中、执行失败、已执行状态分离;审批结果应有幂等执行记录,避免重复授权或重复分配。
7. **敏感字段默认拒绝返回**API key、对象内部凭据、节点访问凭据不能随普通资源详情返回日志、审计和错误信息也不能泄露 Token、密码或完整连接串。
8. **安全审计与访问统计分离**:权限成功、拒绝、下载、导出、授权、审批和异常进入不可篡改审计;页面访问统计单独存储,避免污染安全审计记录。
## 十一、下一步开发计划
### 阶段一P0 安全封堵与统一策略
1. 对模型列表、详情、名称查询及相关 DTO 做 API key/凭据脱敏,增加“仅后端内部读取”的封装。(基础闭环已完成,继续扫描任务和日志输出)
2. 建立统一 `authorize(resource, action)` 服务定义动作白名单和平台管理员、租户管理员、所有者、ACL 的判定顺序。(已完成动作白名单,继续迁移全部入口)
3. 逐项审计平台、数据处理、数据转换、存储、MinIO、模型、数据集、训练、评测、推理的列表、详情、预览、下载、导出、缓存和删除入口。
4. 统一记录权限成功、拒绝和异常审计,补齐 `tenant_id``resource_id``action``request_id``session_id``reason``result`。(装饰器基础闭环已完成,继续覆盖手工记录入口)
### 阶段二:租户成员、审批和配额闭环
1. 开发租户邀请/加入申请/审批/移除/过期流程及前端租户切换。
2. 为审批模板增加动作和资源类型白名单、租户作用域、幂等键、过期任务和执行失败重试。
3. 建立配额预留账本,训练、评测、推理、存储和 GPU 任务提交前统一原子检查;任务终态和故障恢复统一释放。
4. 完善 GPU 节点、GPU 卡、租户、用户和任务的占用关系校验,覆盖冲突、超时、节点不可达和服务重启恢复。
### 阶段三:资源血缘和生命周期
1. 固化基座模型、数据集、数据处理结果、训练任务、训练模型、评测和推理任务的资源血缘及版本快照。
2. 明确派生模型默认授权规则,训练产物不因基座模型共享而自动对外公开。
3. 补齐用户、租户、资源、ACL、审批、MinIO 对象和本地缓存的软删除、撤销、延迟清理和失败重试。
### 阶段四:前端权限体验与测试
1. 开发统一资源级权限组件,按动作隐藏/禁用按钮,并展示授权来源、有效期、审批状态和明确的 401/403 原因。
2. 将审批、ACL、审计列表中的用户、租户、资源 ID 映射为可读名称,同时保留 ID 作为详情字段。
3. 编写并执行权限专项测试矩阵未登录、同租户成员、资源所有者、ACL 授权、跨租户、禁用用户、会话注销、审批撤回/过期、软删除、MinIO 故障、GPU 冲突和配额不足。
4. 在第二个可达节点或多卡节点准备后执行多节点、多 GPU 并发及故障恢复测试;完成主工程与 `docker/offline/src` 的源码、初始化 SQL、迁移和部署文档一致性检查。
## 十二、下一阶段完成标准
- 普通资源接口不再返回 API key、密码、Token 或节点访问凭据。
- 所有资源入口都经过统一的租户边界和动作授权,跨租户访问返回明确 403。
- 训练、评测、推理创建同时满足资源权限、GPU 预留和租户配额,失败时不会留下孤儿占用。
- 审批只能由合法审批人执行,申请人不能自审;重复回调不会重复授权、分配或扣减配额。
- 权限拒绝、下载、导出、授权、审批和异常均能按用户、租户、资源和请求 ID追溯。
- 主工程和离线目录初始化新库均无缺表、缺字段;迁移可重复执行且不破坏既有数据。
- 权限专项自动化测试通过,且完成至少一次双用户、跨租户和 MinIO 故障场景的真实容器验证。
## 十三、上一阶段权限闭环开发结果2026-08-20
本轮围绕 P0 安全封堵完成了一个可验证的权限闭环:
1. **模型凭据不出接口**:模型列表、详情、按名称查询、创建、更新和用途更新响应统一经过公开 DTO 脱敏,移除 `api_key`、密码、Token 等字段,仅返回 `api_key_configured` 布尔状态;后端内部评测、数据生成仍使用数据库中的真实配置。
2. **编辑密钥不被意外清空**:前端编辑在线模型时不回填真实密钥,留空表示保留已有配置,只有管理员主动输入新值时才提交替换。
3. **资源动作统一入口**:增加资源动作白名单 `read/write/execute/download/export/delete/admin`,并将 `export` 统一归一到下载权限,非法动作默认拒绝,避免把模块权限误当成资源权限。
4. **失败审计闭环**:审计装饰器对成功和异常分别记录,失败记录包含结果、失败原因、租户、请求 ID、会话 ID和耗时并对异常中的常见凭据进行脱敏。
5. **访问统计受控**:模块访问统计只接受平台已登记的模块名,不能通过请求参数向安全审计表写入任意动作;审计 CSV 导出改为标准 CSV 编码,并补充结果、原因、请求和会话字段。
6. **离线版本同步**:上述后端权限代码、前端模型编辑代码和权限安全回归用例已同步到 `docker/offline/src`;本轮未新增数据库字段,因此 `000_full_init.sql` 无需变更。
### 上一阶段验证结果
- 后端权限相关模块 `python -m py_compile`:通过。
- WSL Backend 容器执行权限安全用例8 passed仅有 pytest 缓存目录只读警告。
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 路径和 chunk size 警告。
- 容器接口验证:未登录访问模型接口返回 401管理员访问模型列表/详情时响应不包含 `api_key`,仅返回 `api_key_configured`
- Backend 容器已重启并加载当前源码;数据库无需迁移。
### 上一阶段未覆盖的范围(已在第十四节继续处理)
本轮没有声称完成配额账本、GPU 原子预留、租户邀请/加入申请、审批定时过期、所有资源入口的逐接口审计,以及第二节点/多 GPU 的真实并发测试;这些仍按“十一、下一步开发计划”执行。
## 十四、本轮继续开发结果2026-08-20
### 已完成
1. 新增 `tenant_quota_reservations` 配额预留账本,支持按租户统计 GPU 预留量、原子限制 GPU 配额,以及任务完成、失败、停止、删除和节点故障时释放预留。
2. 训练、评测和推理统一接入租户 GPU 配额预留;评测/推理使用的 `gpu_reservations` 与配额账本在同一事务内创建或释放,避免只释放算力卡而遗留配额占用。
3. 租户成员支持邀请、接受、过期、角色更新和移除;邀请不允许授予 `owner`,成员状态和租户有效性由后端校验,租户详情页补充成员管理和 GPU 配额使用量展示。
4. 审批动作增加白名单,非法动作拒绝创建;相同申请人在同一资源上的待审批申请幂等复用;审批实例读取时自动处理过期状态,资源访问申请也避免重复创建。
5. GPU 分配增加节点启用状态、GPU 卡存在性、用户 active 状态和同卡跨用户冲突校验;冲突返回 409不再静默覆盖或产生重复授权。
6. 完整初始化 SQL 增加配额预留表和索引,新增 `010_permission_quota_membership.sql` 增量迁移;主工程相关源码、前端租户 API/页面和 SQL 已同步到离线源码目录。
### 本轮验证
- WSL Backend 容器重启后,`tenant_quota_reservations` 可正常查询,默认租户配额使用量返回正常。
- WSL Backend 容器执行 `test_permission_security.py`3 passed。
- 后端相关文件 `python -m py_compile`:通过。
- 前端 `npm run build`:通过;仅保留既有 Font Awesome 资源路径和大 chunk 警告。
### 必须后续验证的场景
1. 创建第二个 active 用户和第二个租户,验证邀请接受、租户切换、跨租户资源访问均按预期返回 401/403。
2. 将租户 GPU 配额设为 1同时提交两个需要 GPU 的训练/评测/推理任务,确认第二个任务被拒绝;第一个任务终态后确认配额可再次使用。
3. 在同一多卡节点上让两个用户申请同一张卡,确认审批执行阶段冲突返回 409另一张空闲卡仍可正常分配。
4. 构造过期审批、重复提交、审批拒绝/撤回,确认不会重复创建 ACL、GPU 分配或配额预留。
5. 准备第二个可达节点或多卡节点,执行训练、评测、推理的多节点/多 GPU 并发和节点失联回收测试。
6. 注入 MinIO 故障,确认任务失败后 GPU 与租户配额均能释放,恢复 MinIO 后可以重新提交任务。
### 下一步计划
- 对数据处理、数据转换、MinIO 对象、缓存、版本和报告下载入口继续执行一次接口级回归,重点验证跨租户、过期 ACL 和下载/执行动作分离。
- 将双用户、跨租户、配额不足、同卡冲突、审批过期/幂等、MinIO 故障和节点失联场景加入可重复的自动化测试夹具;当前单节点环境先完成无需第二节点的部分。
- 在第二个可达节点或多卡节点到位后,执行多节点、多 GPU 并发、任务失败回收和重启恢复测试,完成上线验收闭环。
## 十五、本轮权限全量收口结果2026-08-20
### 已完成的开发
1. **租户成员角色真正参与资源授权**ACL 的 `role` 主体不再只读取平台角色,改为读取资源所属租户中的有效成员角色;成员过期、禁用或不属于资源租户时不能通过角色 ACL 访问。
2. **租户有效期隔离**:用户可用租户集合和资源授权均校验成员有效期,避免过期成员继续访问资源。
3. **用户生命周期闭环**:用户删除改为软删除,保留用户和审计链路;同时注销会话、禁用租户成员、撤销用户 ACL、取消待审批申请、释放 GPU 分配,并禁止删除租户最后一个 owner。
4. **资源和对象清理链路**:被删除用户创建的模型、训练模型、数据集、评测、推理、数据处理和数据转换资源统一标记删除;关联 MinIO `storage_objects` 标记为 `deleted`,进入既有清理/重试队列;资源 ACL 和安全状态同步撤销。
5. **推理入口补强**:训练模型预加载必须引用真实且未删除的训练模型资源,普通用户不能通过任意本地路径绕过资源授权;本地推理状态查询要求普通用户提供有 `read` 权限的推理任务。
6. **初始化和迁移完整性**:新增 `011_permission_lifecycle.sql`,完整初始化脚本同步补齐用户、评测、推理、数据转换和存储对象生命周期字段;离线目录仍只保留完整的 `000_full_init.sql`
### 自动验证结果
- `python -m py_compile backend/app/core/auth.py backend/app/db/platform_store.py backend/app/api/v1/endpoints/platform.py`:通过。
- `git diff --check`:通过。
- WSL Backend 容器启动并自动执行迁移后为 `healthy`;已核对 `users``eval_tasks``compare_tasks``data_convert_tasks``storage_objects` 的新增字段均存在。
- `test_permission_security.py``test_storage_security.py`8 passed仅有容器内 pytest 缓存目录只读警告。
- 真实 API 闭环:临时用户删除后状态为 `deleted`、存在 `deleted_at`,使用原凭据登录返回 HTTP 401。
- 前端 `npm run build`:需在本轮同步后再次执行,预期仅保留既有资源路径和 chunk size 警告;该项以最终命令结果为准。
### 仍需现场验证的场景
1. 第二个 active 用户和第二个租户的邀请、接受、租户切换及跨租户资源访问。
2. 租户 GPU 配额为 1 时,训练/评测/推理并发预留、终态释放和服务重启恢复。
3. 同一多卡节点的同卡冲突、不同卡并行和节点不可达后的回收。
4. 审批过期、重复回调、拒绝、撤回和执行失败重试的真实链路。
5. MinIO 故障注入后的任务失败、GPU/配额释放、对象清理重试和恢复后重新提交。
以上项目属于环境依赖型验收,不再作为代码未开发项;在当前单节点、单用户测试环境中保留为上线前验证项。
## 十六、前端权限页面收口结果2026-08-20
本轮已完成前端权限页面的主要操作闭环:
1. `用户权限设置`由占位页改为完整权限矩阵,支持按平台角色、账号状态和页面权限保存;已删除用户进入只读态,管理员角色自动拥有全部页面权限。
2. 用户创建页增加页面权限配置,普通用户默认不授予组织管理和算力节点权限。
3. 用户管理页增加权限入口、权限数量、软删除状态和危险操作禁用逻辑。
4. 资源 ACL 页支持用户/租户角色主体、权限标签、全部撤销二次确认和加载失败提示。
5. 审批策略页从 JSON 文本改为可视化配置指定用户、租户管理员和平台管理员审批步骤。
6. 审批申请和访问申请页增加中文事项、资源类型、权限和状态展示,保留资源 ID 作为详情信息。
7. 普通用户可进入审批中心的“我的申请”“访问申请”“租户邀请”,支持撤回访问申请和接受有效租户邀请。
8. 租户成员邀请页增加邀请有效期设置;租户配额和 GPU 预留量继续在租户详情页展示。
9. 本轮前端源码已同步至 `docker/offline/src/frontend/src`,初始化 SQL 目录仍只保留 `000_full_init.sql`
前端 `npm run build` 已通过。尚需浏览器实际点击验证页面布局、不同账号菜单差异、双用户跨租户流程和多 GPU/MinIO 故障场景;这些属于环境验收,不再是页面缺少开发入口。