Files
aiagent/docs/multi-tenant-rbac-guide.md
renjianbo 876789fac1 feat: multi-tenant workspace isolation, RBAC, sidebar nav, billing, and Android enhancements
- Backend: workspace_id isolation for 14 model tables + safe migration/backfill
- Backend: RBAC system with 4 roles and 23 permissions, seeded on startup
- Backend: workspace admin endpoints (list/manage all workspaces)
- Backend: admin user management API (CRUD, reset password)
- Backend: billing API with subscription plans, usage tracking, rate limiting
- Backend: fix system_logs.py UNION query and wrong column references
- Backend: WebSocket JWT auth and workspace enforcement
- Frontend: sidebar navigation replacing top dropdown menu
- Frontend: user management page (Users.vue) for admins
- Frontend: enhanced Workspaces.vue with admin table view
- Frontend: workspace RBAC computed properties in user store
- Android: agent marketplace, billing/subscription UI, onboarding wizard
- Android: phone login, analytics tracker, crash handler, network diagnostics
- Android: splash screen, encrypted token storage, app update enhancements
- Docs: multi-tenant RBAC guide with 8 sections and role-permission matrix

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-07-04 01:00:22 +08:00

571 lines
22 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.
# 多租户与 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+