基于角色的访问控制(中文译文)
原始 DeepWiki 页面:https://deepwiki.com/langgenius/dify/8.3-role-based-access-control
翻译时间:2026-05-27T08:44:29.320Z
翻译模型:deepseek-chat
原文字符数:13983
项目:Dify (dify)
---
基于角色的访问控制
相关源文件
以下文件作为生成此 Wiki 页面的上下文:
api/controllers/console/__init__.pyapi/controllers/console/admin.pyapi/controllers/console/auth/data_source_oauth.pyapi/controllers/console/auth/email_register.pyapi/controllers/console/auth/error.pyapi/controllers/console/auth/forgot_password.pyapi/controllers/console/auth/login.pyapi/controllers/console/auth/oauth.pyapi/controllers/console/billing/billing.pyapi/controllers/console/billing/compliance.pyapi/controllers/console/error.pyapi/controllers/console/explore/installed_app.pyapi/controllers/console/workspace/account.pyapi/controllers/console/workspace/members.pyapi/controllers/console/workspace/model_providers.pyapi/controllers/console/workspace/models.pyapi/controllers/console/workspace/plugin.pyapi/controllers/console/workspace/workspace.pyapi/controllers/console/wraps.pyapi/controllers/service_api/wraps.pyapi/libs/oauth.pyapi/libs/oauth_data_source.pyapi/schedule/mail_clean_document_notify_task.pyapi/services/account_service.pyapi/services/billing_service.pyapi/services/feature_service.pyapi/templates/change_mail_confirm_old_template_zh-CN.htmlapi/templates/transfer_workspace_owner_confirm_template_en-US.htmlapi/templates/without-brand/transfer_workspace_owner_confirm_template_en-US.htmlapi/tests/test_containers_integration_tests/services/test_billing_service.pyapi/tests/unit_tests/controllers/console/workspace/test_workspace.pyapi/tests/unit_tests/libs/test_oauth_clients.pyapi/tests/unit_tests/services/test_account_service.pyapi/tests/unit_tests/services/test_billing_service.pyweb/app/components/header/account-setting/members-page/__tests__/index.spec.tsxweb/app/components/header/account-setting/members-page/index.tsxweb/app/components/header/account-setting/members-page/operation/__tests__/index.spec.tsxweb/app/components/header/account-setting/members-page/operation/index.tsx
目的与范围
本文档描述了 Dify 的基于角色的访问控制(RBAC)系统,该系统管理工作空间(租户)内的用户权限。系统实现了五层角色层级(OWNER、ADMIN、EDITOR、NORMAL、DATASET_OPERATOR),并为应用和数据集提供了资源级别的权限粒度。
关于认证方法和流程,请参阅认证方法与流程。关于租户隔离和资源作用域,请参阅租户模型与资源隔离。关于工作空间级别的设置和成员管理功能,请参阅工作空间与成员管理。
---
角色层级
Dify 在 TenantAccountRole 枚举中实现了五种不同的角色,每种角色都具备特定的能力和限制。
角色定义
graph TB
Owner["所有者<br/>完全控制工作空间<br/>可转移所有权"]
Admin["管理员<br/>管理成员<br/>不可转移所有权"]
Editor["编辑者<br/>创建内容<br/>编辑应用与工作流"]
Normal["普通用户<br/>只读访问<br/>查看资源"]
DatasetOp["数据集操作员<br/>管理知识库<br/>仅限数据集"]
Owner -->|包含所有权限| Admin
Admin -->|包含所有权限| Editor
Editor -->|包含所有权限| Normal
DatasetOp -.->|专门角色| Editor
Owner -->|可修改| Admin
Owner -->|可修改| Editor
Admin -->|可修改| Editor
Admin -->|可修改| DatasetOp
来源: api/models/account.py:19-77
| 角色 | 枚举值 | 关键能力 |
|---|---|---|
| 所有者 | owner | 完全控制工作空间、转移所有权、管理计费、拥有所有管理员能力。 |
| 管理员 | admin | 邀请/移除成员、分配角色(所有者除外)、拥有所有编辑者能力。 |
| 编辑者 | editor | 创建/编辑应用、工作流、数据集;运行工作流;发布变更。 |
| 普通用户 | normal | 对工作空间资源仅拥有查看权限。 |
| 数据集操作员 | dataset_operator | 创建/编辑数据集和文档,无应用/工作流权限。 |
角色校验方法
TenantAccountRole 枚举提供了静态校验方法,用于在代码库中通过编程方式确定访问级别。
graph LR
subgraph "角色检查方法"
isValid["is_valid_role(role)<br/>校验角色是否存在"]
isPrivileged["is_privileged_role(role)<br/>所有者或管理员"]
isEditing["is_editing_role(role)<br/>所有者、管理员或编辑者"]
isDatasetEdit["is_dataset_edit_role(role)<br/>所有者、管理员、编辑者或数据集操作员"]
end
Owner2["所有者"] --> isPrivileged
Admin2["管理员"] --> isPrivileged
Owner2 --> isEditing
Admin2 --> isEditing
Editor2["编辑者"] --> isEditing
Owner2 --> isDatasetEdit
Admin2 --> isDatasetEdit
Editor2 --> isDatasetEdit
DatasetOp2["数据集操作员"] --> isDatasetEdit
来源: api/models/account.py:26-77
---
租户-账户角色关联
TenantAccountJoin 模型
TenantAccountJoin 模型建立了 Account 和 Tenant 实体之间的多对多关系,并存储了用户在特定工作空间中被分配的特定 role。
erDiagram
Account ||--o{ TenantAccountJoin : "拥有"
Tenant ||--o{ TenantAccountJoin : "包含"
Account {
string id 主键
string name
string email
string role "仅运行时"
Tenant _current_tenant "仅运行时"
}
Tenant {
string id 主键
string name
string plan
string status
string custom_config
}
TenantAccountJoin {
string id 主键
string tenant_id 外键
string account_id 外键
bool current
string role "owner|admin|editor|normal|dataset_operator"
string invited_by 外键
datetime created_at
}
来源: api/models/account.py:279-302、api/models/account.py:242-277
角色加载与切换
当通过 AccountService.load_user 加载 Account 时,系统会确定当前活跃的工作空间。如果没有工作空间被标记为 current,则默认使用第一个可用的 TenantAccountJoin 记录 api/services/account_service.py:177-187。
sequenceDiagram
participant AS as AccountService
participant DB as db.session
participant Account as Account 实例
participant TAJ as TenantAccountJoin
AS->>DB: get(Account, user_id)
DB-->>AS: account 对象
AS->>DB: scalar(select(TAJ).where(account_id, current=True))
alt 找到当前租户
DB-->>AS: current_tenant
else 没有当前租户
AS->>DB: scalar(select(TAJ).where(account_id).order_by(asc))
DB-->>AS: available_ta
AS->>TAJ: 设置 current=True
AS->>DB: commit()
end
AS->>Account: set_tenant_id(tenant_id)
来源: api/services/account_service.py:161-188
---
资源的权限级别
除了全局工作空间角色外,像数据集这样的单个资源也支持内部权限设置。
DatasetPermissionEnum
Dataset 模型使用 permission 字段来控制工作空间内的访问权限 api/models/dataset.py:126:
ONLY_ME:仅创建者(所有者)可以查看和修改。ALL_TEAM:所有工作空间成员都可以访问。PARTIAL_TEAM:访问权限仅限于数据集权限映射中定义的特定成员。
来源: api/models/dataset.py:38-42、api/models/dataset.py:44-83
---
账户权限属性
Account 模型提供了计算属性,用于快速进行权限检查。这些属性在控制器中被广泛用于保护端点。
| 属性 | 实现逻辑 |
|---|---|
is_admin_or_owner | role in {OWNER, ADMIN} api/models/account.py:195-201 |
has_edit_permission | role in {OWNER, ADMIN, EDITOR} api/models/account.py:203-209 |
is_dataset_editor | role in {OWNER, ADMIN, EDITOR, DATASET_OPERATOR} api/models/account.py:211-217 |
is_dataset_operator | role == DATASET_OPERATOR api/models/account.py:219-225 |
来源: api/models/account.py:195-235
在控制器中的实现
API 端点使用装饰器或直接属性检查来实施基于角色的访问控制。例如,DefaultModelApi 要求使用 is_admin_or_owner_required 装饰器来修改工作空间范围的设置。
# api/controllers/console/workspace/models.py
@is_admin_or_owner_required
def post(self):
# 更新工作空间默认模型的逻辑
来源: api/controllers/console/workspace/models.py:148-150、api/controllers/console/workspace/models.py:194-196
---
成员管理操作
角色分配规则
角色分配受层级限制。例如,MemberInviteEmailApi 在继续操作之前会检查分配的角色是否为非所有者角色 api/controllers/console/workspace/members.py:115-116,因为所有权只能通过特定流程进行转移。
来源: api/controllers/console/workspace/members.py:109-119
成员管理的 API 端点
| 操作 | 端点 | 所需角色 | 描述 |
|---|---|---|---|
| 列出成员 | GET /workspaces/current/members | 需要登录 | 通过 TenantService.get_tenant_members 检索所有成员 api/controllers/console/workspace/members.py:93-96 |
| 邀请成员 | POST /workspaces/current/members/invite-email | 管理员/所有者 | 通过 RegisterService.invite_new_member 邀请 api/controllers/console/workspace/members.py:142-148 |
| 移除成员 | DELETE /workspaces/current/members/{member_id} | 管理员/所有者 | 通过 TenantService.remove_member_from_tenant 移除 api/controllers/console/workspace/members.py:187 |
来源: api/controllers/console/workspace/members.py:75-90、api/controllers/console/workspace/members.py:93-161、api/controllers/console/workspace/members.py:163-187
---
所有权转移
所有权转移是一项高安全性的操作,仅限于当前的 OWNER 执行。它涉及使用令牌和电子邮件验证码的多步骤验证流程。
sequenceDiagram
participant Owner as 当前所有者
participant API as MemberInviteEmailApi
participant TS as TenantService
participant Task as owner_transfer_task
Owner->>API: POST /members/send-owner-transfer-confirm-email
API->>Task: send_owner_transfer_confirm_task()
Task-->>Owner: 包含验证码的电子邮件
Owner->>API: POST /members/owner-transfer-check (验证码 + 令牌)
API-->>Owner: 新的会话绑定令牌
Owner->>API: POST /members/{member_id}/owner-transfer (令牌)
API->>TS: transfer_owner(tenant, new_owner)
来源: api/controllers/console/workspace/members.py:226-254、api/controllers/console/workspace/members.py:257-293、api/controllers/console/workspace/members.py:296-335
---
权限矩阵总结
| 操作 | 所有者 | 管理员 | 编辑者 | 普通用户 | 数据集操作员 |
|---|---|---|---|---|---|
| 工作空间管理 | |||||
| 转移所有权 | ✅ | ❌ | ❌ | ❌ | ❌ |
| 切换工作空间 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 成员管理 | |||||
| 邀请成员 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 分配/更新角色 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 移除成员 | ✅ | ✅ | ❌ | ❌ | ❌ |
| 资源管理 | |||||
| 创建应用 | ✅ | ✅ | ✅ | ❌ | ❌ |
| 编辑应用 | ✅ | ✅ | ✅ | ❌ | ❌ |
| 创建数据集 | ✅ | ✅ | ✅ | ❌ | ✅ |
| 编辑数据集 | ✅ | ✅ | ✅ | ❌ | ✅ |
| 管理模型提供商 | ✅ | ✅ | ❌ | ❌ | ❌ |
来源: api/models/account.py:19-77、api/models/account.py:195-235、api/controllers/console/workspace/members.py:109-119、api/controllers/console/workspace/models.py:148-150