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

42 KiB
Raw Permalink Blame 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_membersresource_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_idrolepermissionsprotected 等字段,角色权限在初始化脚本中有基础种子数据。
  • 登录失败限流和旧明文密码升级已经具备基础实现。

3.2 租户、资源和 ACL

  • tenants 表和租户 CRUD、配额、留存策略接口已经存在当前接口统一要求管理员。
  • 数据集、模型、训练模型、评测任务等核心资源已经具备 created_bytenant_id 或任务 payload 中的归属信息。
  • acls 表支持用户和角色两类授权主体,权限包括 readwriteexecutedownloaddeleteadmin
  • 资源 ACL 查询和全量替换接口已经存在,资源所有者或管理员可以管理 ACL。
  • 列表接口对数据集、评测、训练和推理任务已增加“本人资源 + ACL 授权资源”的过滤逻辑。
  • MinIO 预签名、资源清单、对象列表、模型制品、模型血缘和评测报告等新入口已增加登录和资源访问校验。

3.3 训练、评测、推理和 GPU

  • 训练创建会检查训练数据集的 execute 权限,并对用户选择的 GPU 执行分配校验。
  • 评测创建会检查训练模型、数据集的 execute 权限,并校验算力节点和 GPU。
  • 推理任务加载会检查任务及训练模型的执行权,同时使用 gpu_reservations 防止同一张 GPU 被并发占用。
  • GPU 分配接口和用户可用 GPU 查询已经存在,失败、停止、删除、节点异常等路径具备基础释放逻辑。
  • 训练模型删除、训练任务停止/删除、评测任务删除和推理任务删除已接入部分审批拦截。
  • 权重合并、导出、缓存准备和 MinIO 归档已经能记录模型、节点、租户和部分血缘信息。

3.4 审计和前端

  • audit_logsoperation_logs 表及管理员查询/导出页面已经存在。
  • 资源 ACL 变更、租户管理、模型/数据集/任务等主要写操作已经接入审计或操作日志装饰器。
  • 前端路由和侧边栏对治理、组织、资源授权、审批、日志、算力节点等页面做了管理员限制。
  • ResourceAclView 已支持资源类型、用户/角色主体和多权限编辑。

四、改造前未实现或存在明显安全缺口(历史基线)

本节保留本轮改造前的检查快照,不代表当前状态。当前剩余问题以“十、当前仍需开发的功能”和“十一、下一步开发计划”为准。

以下项目属于必须继续开发的内容,优先级高于页面样式和性能优化。

4.1 审批决策不能直接信任请求参数

backend/app/modules/approval/router.py 的审批决策接口当前没有 get_current_user 依赖,并且从请求体读取 approver_id。调用方可以伪造审批人 ID属于高风险越权问题。

必须改为:服务端从当前会话取得审批人;校验其是否为当前步骤指定审批人、租户管理员或平台管理员;校验当前步骤、实例状态和申请人不能自审;审批通过后再执行对应动作或写入 ACL。

4.2 资源申请流程尚未形成

当前有 approval_templatesapproval_instancesapproval_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 判断收敛为统一服务:

认证 -> 平台/租户角色 -> 租户边界 -> 资源所有权/ACL -> 动作权限 -> GPU/配额 -> 审批 -> 审计

每个敏感接口都应明确动作,例如 dataset.readdataset.downloaddataset.executetrained_model.exportinference.loadgpu.reserve,禁止只使用“已登录”作为业务权限。

5.2 重新设计资源申请和审批

推荐流程:

申请人选择资源和动作
  -> 校验申请人所属租户和基础权限
  -> 创建 resource_access_requests
  -> 根据租户/资源类型匹配审批策略
  -> 指定审批人完成审批
  -> 事务内写入 ACL/配额/GPU 预留
  -> 记录授权有效期、来源和审计

审批拒绝、撤回、过期和资源删除都应撤销或冻结对应授权,不能仅修改审批实例状态。

5.3 模型、数据集、训练任务联合授权

训练、评测、推理分别使用以下最小权限:

场景 必须具备的权限
查看基座模型 model.read;基座模型默认平台共享
使用基座模型训练 model.execute 或平台共享策略 + 数据集 execute
下载基座模型 单独的 model.download,默认不授予
使用训练模型推理 trained_model.execute
下载/导出训练模型 trained_model.downloadtrained_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_idgranted_bysource_request_idexpires_atrevoked_at,保留授权来源和自动过期能力。
  4. approval_templates 增加 tenant_idactionresource_typescopestatus;审批步骤增加主体类型、主体 ID 和租户范围。
  5. 资源表统一补齐非空租户策略、归属用户、软删除字段和必要索引;历史 NULL 数据通过一次性迁移处理。
  6. audit_logs 增加结果、拒绝原因、request_id、认证会话和结构化 detail避免把 Token 当作 actor。

不建议把完整 ACL 和审批状态继续塞入模型、数据集或任务 JSON 字段JSON 可保留兼容信息,但权限判断应以结构化表为准。

七、历史开发计划(已执行)

第一阶段P0 安全修复

  • 修复审批决策鉴权和审批人伪造问题。
  • 补齐数据集文件/版本/上传/编辑接口权限。
  • 补齐本地模型聊天、状态、卸载、模型名称查询等历史入口鉴权。
  • 统一 downloadexecutewritedelete 动作检查。
  • 限制 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 不能替代 downloadexecute 不能替代 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_idresource_idactionrequest_idsession_idreasonresult。(装饰器基础闭环已完成,继续覆盖手工记录入口)

阶段二:租户成员、审批和配额闭环

  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.py3 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;已核对 userseval_taskscompare_tasksdata_convert_tasksstorage_objects 的新增字段均存在。
  • test_permission_security.pytest_storage_security.py8 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 故障场景;这些属于环境验收,不再是页面缺少开发入口。