# 多租户与 RBAC 权限管理指南 > **Multi-Tenant & RBAC Guide** — 工作区隔离、角色权限、用户管理完整说明 本文档涵盖天工智能体平台 v1.2+ 的多租户架构、RBAC 权限体系、工作区管理和平台管理员功能。 --- ## 一、多租户架构概览 ### 1.1 什么是多租户 天工平台采用 **工作区 (Workspace)** 作为租户隔离的基本单元: ``` ┌────────────────────────────────────────────────────┐ │ 天工平台 │ │ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │ │ │ 工作区 A │ │ 工作区 B │ │ 工作区 C │ │ │ │ (研发团队) │ │ (市场团队) │ │ (个人空间) │ │ │ │ │ │ │ │ │ │ │ │ Agent: 5 个 │ │ Agent: 3 个 │ │ Agent: 2 │ │ │ │ 工作流: 8 个 │ │ 工作流: 4 个 │ │ 工作流: 3 │ │ │ │ 知识库: 3 个 │ │ 知识库: 1 个 │ │ 知识库: 1 │ │ │ │ 成员: 12 人 │ │ 成员: 5 人 │ │ 成员: 1 │ │ │ └──────────────┘ └──────────────┘ └───────────┘ │ └────────────────────────────────────────────────────┘ ``` ### 1.2 核心隔离原则 | 隔离维度 | 说明 | |----------|------| | **数据隔离** | 每个工作区的 Agent、工作流、知识库、执行记录等数据完全隔离 | | **成员隔离** | 工作区 A 的成员默认无法访问工作区 B 的任何资源 | | **API 隔离** | 所有资源 API 自动按工作区过滤,返回结果仅限当前工作区 | | **WebSocket 隔离** | 实时推送按工作区频道隔离,不会跨工作区串消息 | ### 1.3 JWT Token 中的工作区标识 登录或切换工作区后,JWT Token 中会携带 `ws` 字段: ```json { "sub": "user-uuid-xxx", "ws": "workspace-uuid-xxx", "exp": 1712345678 } ``` 所有后续 API 请求自动按此工作区范围过滤数据。 --- ## 二、工作区管理 ### 2.1 工作区列表 进入「工作区管理」页面,查看你有权限访问的所有工作区: ``` ┌──────────────────────────────────────────────────────┐ │ 工作区管理 [+ 创建工作区] │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 研发团队 │ │ 个人空间 │ │ AI实验室 │ │ │ │ [默认] [管理员]│ │ [成员] │ │ [管理员] │ │ │ │ 描述... │ │ 描述... │ │ 描述... │ │ │ │ 状态: 启用 │ │ 状态: 启用 │ │ 状态: 停用 │ │ │ │ [进入] [管理]│ │ [进入] │ │ [进入] [管理]│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └──────────────────────────────────────────────────────┘ ``` ### 2.2 创建工作区 1. 点击「创建工作区」按钮 2. 填写工作区信息: | 字段 | 说明 | 限制 | |------|------|------| | 名称 | 工作区唯一标识 | 1-100 字符 | | 描述 | 可选说明信息 | 最多 1000 字符 | | 最大成员数 | 工作区成员上限 | 1-500,默认 50 | 3. 创建者自动成为该工作区的 **管理员 (admin)** ### 2.3 切换工作区 - 在工作区列表中点击「进入」自动切换 - 或通过顶部导航栏的工作区下拉选择器切换 - 切换后 JWT Token 刷新,后续所有操作在新工作区上下文中执行 ### 2.4 管理工作区 点击「管理」进入工作区详情页,包含三个标签页: **基本信息** - 修改名称、描述、最大成员数 - 启用/停用工作区(停用后成员无法访问) **成员管理** - 查看当前成员列表(用户名、邮箱、角色) - 添加新成员(按用户名查找) - 修改成员角色(管理员 / 成员) - 移除成员 **危险操作** - 删除工作区(软删除,状态标记为 deleted) ### 2.5 角色说明 | 角色 | 权限范围 | |------|----------| | **admin** (工作区管理员) | 管理成员、修改设置、删除工作区、创建/编辑/删除所有资源 | | **member** (成员) | 查看和创建资源,编辑自己创建的资源 | > **注意**: 工作区管理员 ≠ 平台管理员。工作区管理员仅管理当前工作区,平台管理员拥有全局权限。 --- ## 三、RBAC 权限体系 ### 3.1 系统角色 天工平台定义了 4 个系统级角色: | 角色 | 说明 | 典型用户 | |------|------|----------| | **admin** (平台管理员) | 全局管理权限,绕过所有工作区限制 | 平台运维 | | **developer** (开发者) | 创建和管理 Agent、工作流、知识库 | 核心开发 | | **viewer** (只读用户) | 仅查看,无创建/编辑/删除权限 | 审计、管理层 | | **operator** (操作员) | 管理执行、监控告警,但不创建新 Agent | 运维 | ### 3.2 权限列表 (23 项) 所有权限按资源类型分组: | 权限码 | 说明 | developer | viewer | operator | |--------|------|:---------:|:------:|:--------:| | **workflow:create** | 创建工作流 | ✅ | ❌ | ❌ | | **workflow:read** | 查看工作流 | ✅ | ✅ | ✅ | | **workflow:update** | 编辑工作流 | ✅ | ❌ | ❌ | | **workflow:delete** | 删除工作流 | ✅ | ❌ | ❌ | | **workflow:execute** | 执行工作流 | ✅ | ❌ | ✅ | | **workflow:publish** | 发布工作流 | ✅ | ❌ | ❌ | | **agent:create** | 创建 Agent | ✅ | ❌ | ❌ | | **agent:read** | 查看 Agent | ✅ | ✅ | ✅ | | **agent:update** | 编辑 Agent | ✅ | ❌ | ❌ | | **agent:delete** | 删除 Agent | ✅ | ❌ | ❌ | | **agent:deploy** | 部署 Agent | ✅ | ❌ | ✅ | | **agent:stop** | 停止 Agent | ✅ | ❌ | ✅ | | **execution:read** | 查看执行记录 | ✅ | ✅ | ✅ | | **execution:stop** | 中止执行 | ✅ | ❌ | ✅ | | **data_source:create** | 创建数据源 | ✅ | ❌ | ❌ | | **data_source:read** | 查看数据源 | ✅ | ✅ | ✅ | | **data_source:update** | 编辑数据源 | ✅ | ❌ | ❌ | | **data_source:delete** | 删除数据源 | ✅ | ❌ | ❌ | | **model_config:create** | 创建模型配置 | ✅ | ❌ | ❌ | | **model_config:read** | 查看模型配置 | ✅ | ✅ | ✅ | | **model_config:update** | 编辑模型配置 | ✅ | ❌ | ❌ | | **model_config:delete** | 删除模型配置 | ✅ | ❌ | ❌ | | **permission:manage** | 管理权限 | ❌ | ❌ | ❌ | > **admin 角色拥有所有 23 项权限(通配符 `*`),且绕过所有工作区成员资格检查。** ### 3.3 权限检查流程 ``` API 请求 │ ├─ 1. JWT 认证 (get_current_user) │ └─ 失败 → 401 Unauthorized │ ├─ 2. 工作区成员资格检查 (get_workspace_membership) │ ├─ 平台管理员 → 直接放行 │ ├─ 非成员 → 403 Forbidden │ └─ 成员 → 继续 │ ├─ 3. 细粒度权限检查 (WorkspacePermission) │ ├─ 无该权限 → 403 Forbidden │ └─ 有权限 → 继续 │ └─ 4. 执行请求 ``` ### 3.4 敏感操作保护 以下操作需要 **工作区管理员** 权限: | 操作 | 端点 | 要求 | |------|------|------| | 删除 Agent | DELETE /agents/{id} | 工作区管理员 | | 删除工作流 | DELETE /workflows/{id} | 工作区管理员 | | 删除数据源 | DELETE /data-sources/{id} | 工作区管理员 | | 删除模型配置 | DELETE /model-configs/{id} | 工作区管理员 | | 删除定时任务 | DELETE /agent-schedules/{id} | 工作区管理员 | | 部署 Agent | POST /agents/{id}/deploy | 工作区管理员 | | 停止 Agent | POST /agents/{id}/stop | 工作区管理员 | | 发布工作流 | POST /workflows/{id}/publish | 工作区管理员 | | 重载工具 | POST /tools/reload | 工作区管理员 | --- ## 四、平台管理员功能 > 仅 `role=admin` 的用户可访问以下功能。 ### 4.1 用户管理 进入「运维管理 → 用户管理」: **用户列表** ``` ┌──────────────────────────────────────────────────────────────────┐ │ 搜索: [________] 状态: [全部▾] 角色: [全部▾] │ ├──────┬──────────┬──────┬──────┬──────┬────────┬──────┬──────────┤ │ 用户名 │ 邮箱 │ 角色 │ 状态 │ 订阅 │ 工作区数 │ 创建 │ 操作 │ ├──────┼──────────┼──────┼──────┼──────┼────────┼──────┼──────────┤ │ admin │admin@.. │ 管理员│ 启用 │ 免费 │ 2 │06-01 │编辑 重置 │ │ 张三 │zhang@.. │ 开发者│ 启用 │ 专业 │ 1 │06-15 │编辑 重置 │ │ 李四 │li@.. │ 观察者│ 停用 │ 免费 │ 0 │06-20 │编辑 重置 │ └──────┴──────────┴──────┴──────┴──────┴────────┴──────┴──────────┘ ``` **功能操作:** - **创建用户**: 填写用户名、邮箱、密码(6 位以上)、角色 - **编辑用户**: 修改用户名、邮箱、角色、手机号、状态、订阅等级 - **重置密码**: 为用户设置新密码 - **禁用/删除**: 软删除用户(设置 status=deleted),平台管理员不可被删除 ### 4.2 工作区全局管理 平台管理员在工作区管理页面看到全局视图: ``` ┌── 所有工作区(平台管理员视图)──────────────────────────────────────┐ │ 搜索: [________] 状态: [全部▾] │ ├──────────┬────────┬────────┬──────┬──────┬──────────┬────────────┤ │ 名称 │ 所有者 │ 成员数 │ 上限 │ 状态 │ 创建时间 │ 操作 │ ├──────────┼────────┼────────┼──────┼──────┼──────────┼────────────┤ │ 研发团队 │ admin │ 12 │ 50 │ 启用 │ 2026-06 │ [进入][管理]│ │ AI实验室 │ 张三 │ 3 │ 20 │ 停用 │ 2026-07 │ [进入][管理]│ └──────────┴────────┴────────┴──────┴──────┴──────────┴────────────┘ ``` **管理操作:** - 点击「管理」可编辑任意工作区的名称和状态 - 可强制删除任意工作区(包括默认工作区) - 所有操作记录在审计日志中 ### 4.3 审计日志 进入「系统日志 → 审计日志」查看所有管理员操作记录: - 操作人、操作类型(CREATE/UPDATE/DELETE/LOGIN) - 资源类型、IP 地址 - 操作时间、操作结果 --- ## 五、API 使用指南 ### 5.1 认证与工作区切换 ```bash # 1. 登录获取 Token curl -X POST http://localhost:8037/api/v1/auth/login \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin&password=123456" # 响应: { "access_token": "eyJ...", "token_type": "bearer" } # 2. 查看当前用户信息(含工作区列表) curl http://localhost:8037/api/v1/auth/me \ -H "Authorization: Bearer $TOKEN" # 响应包含: # { # "id": "...", "username": "admin", "role": "admin", # "workspaces": [ # {"id": "ws-1", "name": "研发团队", "role": "admin"}, # {"id": "ws-2", "name": "个人空间", "role": "member"} # ], # "current_workspace_id": "ws-1" # } # 3. 切换工作区 curl -X POST http://localhost:8037/api/v1/auth/switch-workspace/ws-2 \ -H "Authorization: Bearer $TOKEN" # 响应包含新的 Token(携带新工作区 ID) ``` ### 5.2 工作区管理 API ```bash # 创建工作区 curl -X POST http://localhost:8037/api/v1/workspaces \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name": "新项目", "description": "项目协作空间", "max_members": 50}' # 查看成员 curl http://localhost:8037/api/v1/workspaces/{ws_id}/members \ -H "Authorization: Bearer $TOKEN" # 添加成员 curl -X POST http://localhost:8037/api/v1/workspaces/{ws_id}/members \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"username": "zhangsan", "role": "member"}' # 修改成员角色 curl -X PUT http://localhost:8037/api/v1/workspaces/{ws_id}/members/{user_id} \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"role": "admin"}' # 移除成员 curl -X DELETE http://localhost:8037/api/v1/workspaces/{ws_id}/members/{user_id} \ -H "Authorization: Bearer $TOKEN" ``` ### 5.3 管理员 API ```bash # 用户列表(分页、搜索、过滤) curl "http://localhost:8037/api/v1/admin/users?page=1&page_size=20&search=admin&role=admin" \ -H "Authorization: Bearer $ADMIN_TOKEN" # 创建用户 curl -X POST http://localhost:8037/api/v1/admin/users \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"username":"newuser","email":"new@test.com","password":"123456","role":"developer"}' # 编辑用户 curl -X PUT http://localhost:8037/api/v1/admin/users/{user_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"role":"viewer","status":"disabled"}' # 重置密码 curl -X POST http://localhost:8037/api/v1/admin/users/{user_id}/reset-password \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"new_password":"newpass123"}' # 删除用户(软删除) curl -X DELETE http://localhost:8037/api/v1/admin/users/{user_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" # 查看所有工作区 curl "http://localhost:8037/api/v1/admin/workspaces?page=1&page_size=20" \ -H "Authorization: Bearer $ADMIN_TOKEN" # 查看任意工作区详情 curl http://localhost:8037/api/v1/admin/workspaces/{ws_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" # 编辑任意工作区 curl -X PUT http://localhost:8037/api/v1/admin/workspaces/{ws_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"status":"disabled"}' # 强制删除工作区 curl -X DELETE http://localhost:8037/api/v1/admin/workspaces/{ws_id} \ -H "Authorization: Bearer $ADMIN_TOKEN" ``` ### 5.4 WebSocket 连接 WebSocket 连接需要传递 Token 作为 query 参数: ```javascript // 执行状态实时推送 const ws = new WebSocket( `ws://localhost:8037/api/v1/ws/executions/${executionId}?token=${jwtToken}` ); ws.onmessage = (event) => { const data = JSON.parse(event.data); // data.type: "status" | "progress" | "error" | "pong" console.log(data); }; // 协作编辑 const collabWs = new WebSocket( `ws://localhost:8037/api/v1/collaboration/ws/workflows/${workflowId}?token=${jwtToken}` ); // 发送操作 collabWs.send(JSON.stringify({ type: "operation", operation: { type: "node_add", node: { id: "...", type: "llm", position: { x: 100, y: 200 } } } })); ``` WebSocket 认证验证: - JWT Token 有效性 - 用户存在且未被删除 - 工作区成员资格 - 资源归属当前工作区 ### 5.5 错误码说明 | HTTP 状态码 | WebSocket 关闭码 | 说明 | |:-----------:|:----------------:|------| | 401 | 4001 | Token 无效或已过期 | | 403 | 4003 | 无权访问(非工作区成员 / 无所需权限) | | 403 | 4008 | 违反策略(如缺少 Token) | --- ## 六、数据隔离详解 ### 6.1 已隔离的资源 以下资源通过 `workspace_id` 字段实现完全隔离: | 资源 | 表 | 隔离方式 | |------|-----|----------| | Agent | agents | 查询时自动按 workspace_id 过滤 | | 工作流 | workflows | 查询时自动按 workspace_id 过滤 | | 执行记录 | executions | 查询时自动按 workspace_id 过滤 | | 数据源 | data_sources | 查询时自动按 workspace_id 过滤 | | 模型配置 | model_configs | 查询时自动按 workspace_id 过滤 | | 定时任务 | agent_schedules | 查询时自动按 workspace_id 过滤 | | 知识库 | knowledge_bases | 查询时自动按 workspace_id 过滤 | | 聊天消息 | chat_messages | 查询时自动按 workspace_id 过滤 | | Agent 会话 | agent_sessions | 查询时自动按 workspace_id 过滤 | | 告警规则 | alert_rules | 查询时自动按 workspace_id 过滤 | | 节点模板 | node_templates | 查询时自动按 workspace_id 过滤 | | 插件 | plugins | 查询时自动按 workspace_id 过滤 | | 目标/任务 | goals / tasks | 查询时自动按 workspace_id 过滤 | | 编排模板 | orchestration_templates | 查询时自动按 workspace_id 过滤 | | 场景契约 | scene_contracts | 查询时自动按 workspace_id 过滤 | | 团队 | teams | 查询时自动按 workspace_id 过滤 | | 对话分支 | conversation_branches | 查询时自动按 workspace_id 过滤 | | LLM 日志 | agent_llm_logs | 查询时自动按 workspace_id 过滤 | | 知识条目 | knowledge_entries | 查询时自动按 workspace_id 过滤 | | 告警日志 | alert_logs | 查询时自动按 workspace_id 过滤 | ### 6.2 创建时自动标记 所有新建资源自动 stamp 当前工作区 ID,确保数据归属正确: ```python # 后端自动处理(以 Agent 为例) agent = Agent( ... user_id=current_user.id, workspace_id=workspace_id, # 从 JWT ws 字段自动提取 ) ``` --- ## 七、常见场景 ### 7.1 企业新员工入职 1. **管理员创建用户账号** — 进入「用户管理」→ 创建用户,设置角色为 `developer` 2. **将用户加入工作区** — 进入目标工作区「成员管理」→ 添加成员 3. **用户登录** — 使用分配的账号密码登录 4. **用户切换工作区** — 在工作区列表选择目标工作区进入 5. **开始工作** — 创建 Agent、工作流等 ### 7.2 创建新团队协作空间 1. **创建工作区** — 点击「创建工作区」,命名为"XX 项目" 2. **添加团队成员** — 逐个添加成员账号 3. **设置成员角色** — 核心成员设为 `admin`(可管理成员),普通成员设为 `member` 4. **团队开始协作** — 所有成员在该工作区中创建的 Agent、工作流自动共享 ### 7.3 权限审查 1. **平台管理员**进入「用户管理」查看所有用户及其角色 2. 检查是否有用户拥有不当权限(如普通用户被设为 `admin`) 3. 通过「编辑用户」调整角色 4. 停用离职员工的账号(设置 status=disabled) ### 7.4 审计追溯 1. 进入「系统日志 → 审计日志」 2. 按时间、用户、操作类型筛选 3. 查看关键操作:用户创建/删除、权限变更、工作区删除等 4. 所有敏感操作有完整审计轨迹 --- ## 八、安全注意事项 ### 8.1 密码安全 - 默认管理员密码 `123456` 应在首次部署后立即修改 - 通过个人设置或管理员强制重置修改密码 - 密码至少 6 位,建议使用强密码策略 ### 8.2 权限最小化 - 给用户分配其工作需要的最低权限角色 - 默认使用 `developer` 角色,而非 `admin` - 定期审查工作区成员列表,移除不再需要访问的用户 ### 8.3 工作区删除 - 删除工作区是软删除(status=deleted),数据不会物理删除 - 需要彻底清理数据请联系平台管理员 - 默认工作区建议保留不删除 ### 8.4 Token 安全 - JWT Token 包含工作区上下文,请妥善保管 - Token 过期后需重新登录 - WebSocket 连接的 Token 通过 query 参数传递,注意日志中不要泄露 --- ## 附录 A: 角色权限矩阵速查 | 操作 | platform admin | workspace admin | developer | viewer | operator | |------|:---:|:---:|:---:|:---:|:---:| | 查看所有工作区 | ✅ | ❌ | ❌ | ❌ | ❌ | | 管理所有工作区 | ✅ | ❌ | ❌ | ❌ | ❌ | | 管理所有用户 | ✅ | ❌ | ❌ | ❌ | ❌ | | 管理本工作区成员 | ✅ | ✅ | ❌ | ❌ | ❌ | | 修改工作区设置 | ✅ | ✅ | ❌ | ❌ | ❌ | | 创建 Agent/工作流 | ✅ | ✅ | ✅ | ❌ | ❌ | | 编辑自己的资源 | ✅ | ✅ | ✅ | ❌ | ❌ | | 删除自己的资源 | ✅ | ✅ | ✅ | ❌ | ❌ | | 编辑他人的资源 | ✅ | ✅ | ❌ | ❌ | ❌ | | 删除他人的资源 | ✅ | ✅ | ❌ | ❌ | ❌ | | 部署/停止 Agent | ✅ | ✅ | ✅ | ❌ | ✅ | | 执行工作流 | ✅ | ✅ | ✅ | ❌ | ✅ | | 查看资源 | ✅ | ✅ | ✅ | ✅ | ✅ | | 查看执行记录 | ✅ | ✅ | ✅ | ✅ | ✅ | | 查看审计日志 | ✅ | ❌ | ❌ | ❌ | ❌ | ## 附录 B: 数据库表 workspace_id 标记 所有支持多租户隔离的数据表均包含 `workspace_id` 列: ``` agents agent_schedules alert_rules alert_logs agent_execution_logs agent_llm_logs agent_sessions chat_messages conversation_branches data_sources executions goals knowledge_bases knowledge_entries model_configs node_templates plugins scene_contracts orchestration_templates tasks teams templates workflows tools ``` ## 附录 C: 技术架构要点 - **后端框架**: FastAPI + SQLAlchemy ORM - **认证**: JWT (python-jose) + bcrypt 密码哈希 - **依赖注入**: FastAPI `Depends()` 链式调用实现认证→授权→执行 - **数据隔离**: 所有查询通过 SQLAlchemy `filter(workspace_id=...)` 实现 - **WebSocket**: 连接注册表按 workspace_id 标记,防止跨工作区消息泄露 - **平台管理员绕过**: `user.role == "admin"` 跳过所有 workspace 成员资格检查 --- > 最后更新:2026-07-04 | 适用版本 v1.2+