Files
YG_FT/docs/权限开发进度.md
wuyongtao 6f0e82f351 feat: 平台治理与权限体系完善,存储进度/GPU预留/审批中心与日志整合
- 平台治理: 租户用户权限层次、资源ACL、审批中心与审批模板、访问申请
- 存储: MinIO 存储进度迁移、对象存储安全加固与测试
- 计算: GPU 资源预留、compute 轮询与同步增强
- 权限: permission v2 迁移、权限安全验收测试
- 日志: 后端运行日志中文说明、操作日志整合
- 数据处理/评测: 数据转换与模型评测优化

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-21 09:49:48 +08:00

494 lines
42 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 权限开发进度
> 更新时间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 故障场景;这些属于环境验收,不再是页面缺少开发入口。