agentic_huge_data_base / wiki
页面 Dify · 8.1 租户模型与资源隔离·DeepWiki 中文全文译文

8.1 · 租户模型与资源隔离(Tenant Model and Resource Isolation)

应用编排与外部知识接入 · 聚焦本章的模块关系、源码依据与实现要点。

项目Dify 章节8.1 状态全文译文 模块测试、发布与运维、界面与交互、认证、权限与安全、文档对象与元数据
源码线索
  • api/controllers/console/auth/data_source_oauth.py
  • api/controllers/console/auth/email_register.py
  • api/controllers/console/auth/error.py
  • api/controllers/console/auth/forgot_password.py
  • api/controllers/console/auth/login.py
  • api/controllers/console/auth/oauth.py
  • api/controllers/console/explore/installed_app.py
  • api/controllers/console/workspace/account.py
  • api/controllers/console/workspace/members.py
  • api/controllers/console/workspace/model_providers.py
模块标签
  • 测试、发布与运维
  • 界面与交互
  • 认证、权限与安全
  • 文档对象与元数据
  • 系统架构

章节正文

租户模型与资源隔离

租户模型与资源隔离

相关源文件

本章引用的主要源码文件:

  • api/controllers/console/auth/data_source_oauth.py
  • api/controllers/console/auth/email_register.py
  • api/controllers/console/auth/error.py
  • api/controllers/console/auth/forgot_password.py
  • api/controllers/console/auth/login.py
  • api/controllers/console/auth/oauth.py
  • api/controllers/console/explore/installed_app.py
  • api/controllers/console/workspace/account.py
  • api/controllers/console/workspace/members.py
  • api/controllers/console/workspace/model_providers.py
  • api/controllers/console/workspace/models.py
  • api/controllers/console/workspace/plugin.py
  • api/controllers/console/workspace/workspace.py
  • api/libs/oauth.py
  • api/libs/oauth_data_source.py
  • api/models/account.py
  • api/models/api_based_extension.py
  • api/models/dataset.py
  • api/models/model.py
  • api/models/provider.py
  • api/models/source.py
  • api/models/task.py
  • api/models/tools.py
  • api/models/web.py
  • api/models/workflow.py
  • api/schedule/mail_clean_document_notify_task.py
  • api/services/account_service.py
  • api/templates/change_mail_confirm_old_template_zh-CN.html
  • api/templates/transfer_workspace_owner_confirm_template_en-US.html
  • api/templates/without-brand/transfer_workspace_owner_confirm_template_en-US.html
  • api/tests/unit_tests/libs/test_oauth_clients.py
  • api/tests/unit_tests/services/test_account_service.py
  • web/app/components/header/account-setting/members-page/__tests__/index.spec.tsx
  • web/app/components/header/account-setting/members-page/index.tsx
  • web/app/components/header/account-setting/members-page/operation/__tests__/index.spec.tsx
  • web/app/components/header/account-setting/members-page/operation/index.tsx

目的与范围

本文档描述了 Dify 的多租户架构,重点介绍了作为基本隔离边界的 Tenant 模型,以及所有资源如何通过 tenant_id 进行作用域限定。内容涵盖数据库模式设计、租户-账户关系、基于角色的访问控制,以及应用于应用、工作流、数据集和工具提供商的资源隔离模式。

关于认证方法(OAuth、SSO、API 密钥),请参见 8.2。关于基于角色的权限和访问控制详情,请参见 8.3。关于工作空间管理 API 和成员操作,请参见 8.4

核心租户实体

租户模型

Tenant 类代表一个工作空间,是 Dify 中的主要隔离边界。每个租户都是一个完全隔离的工作空间,拥有自己的资源、配置和成员列表。

数据库模式:

列名类型描述
idStringUUID主键,工作空间标识符(UUID v4)
nameString(255)工作空间名称
encrypt_public_keyLongText用于租户特定加密的 RSA 公钥
planString(255)订阅计划(基础版/专业版/团队版/企业版)
statusString(255)工作空间状态(正常/归档)
custom_configLongText自定义工作空间设置的 JSON 配置
created_atDateTime创建时间戳
updated_atDateTime最后更新时间戳

实现细节:

api/models/account.py 定义了 Tenant 类,该类使用 StringUUID 作为主键,并包含工作空间名称、状态和订阅计划等字段。

来源:api/models/account.py:242-277

租户-账户关系

多对多关联

Dify 通过 TenantAccountJoin 表实现了 TenantAccount 之间的多对多关系。每个账户可以属于多个租户(工作空间),每个租户可以有多个具有不同角色的账户。

图示:租户-账户-关联实体关系

Dify · 多对多关联 · 图 1
Dify · 多对多关联 · 图 1

来源:api/models/account.py:279-302

TenantAccountJoin 模式

关联表在成员级别强制执行租户隔离,并存储用户在该工作空间中的特定角色。

列名类型约束描述
idStringUUID主键关联记录标识符
tenant_idStringUUID外键,索引引用 tenants.id
account_idStringUUID外键,索引引用 accounts.id
currentBoolean默认值:false用户当前活动的工作空间
roleString(16)默认值:'normal'用户在此特定工作空间中的角色
invited_byStringUUID可为空发送邀请的账户 ID

来源:api/models/account.py:279-302

角色系统

TenantAccountRole 枚举定义了层级角色,用于管理租户内的权限。

图示:角色层级与代码实体

Dify · 角色系统 · 图 2
Dify · 角色系统 · 图 2

来源:api/models/account.py:19-77

资源作用域模式

通用 tenant_id 隔离

Dify 中的所有主要资源都包含一个 tenant_id 字段。这确保了每个查询都可以严格限定在当前工作空间上下文中。

图示:通过 tenant_id 进行资源作用域限定

Dify · 通用 tenant_id 隔离 · 图 3
Dify · 通用 tenant_id 隔离 · 图 3

来源:api/models/model.py:72, api/models/workflow.py:187, api/models/dataset.py:180, api/models/provider.py:54, api/models/tools.py:94

包含 tenant_id 的资源模型
模型类别代码实体tenant_id 位置索引/约束
应用Appapi/models/model.py:72Index("app_tenant_id_idx", "tenant_id")
工作流Workflowapi/models/workflow.py:187Index("workflow_version_idx", "tenant_id", "app_id", "version")
知识库Datasetapi/models/dataset.py:180Index("dataset_tenant_idx", "tenant_id")
大语言模型(LLM)提供商Providerapi/models/provider.py:54UniqueConstraint("tenant_id", "provider_name", "provider_type", "quota_type")
工具BuiltinToolProviderapi/models/tools.py:94UniqueConstraint("tenant_id", "provider", "name")
API 工具ApiToolProviderapi/models/tools.py:158UniqueConstraint("name", "tenant_id")

租户上下文管理

账户租户关联

Account 模型在请求生命周期内维护当前活动租户上下文。current_tenant 设置器使用 TenantAccountJoin 解析用户在请求工作空间中的角色和成员身份。AccountService.load_user 函数根据 TenantAccountJoin.current 标志或第一个可用工作空间自动解析并设置 current_tenant

图示:AccountService 中的租户上下文解析

Dify · 账户租户关联 · 图 4
Dify · 账户租户关联 · 图 4

来源:api/models/account.py:129-150, api/services/account_service.py:162-190

租户解析函数

代码库使用辅助函数,在只有资源 ID(如 app_id)可用时解析正确的 tenant_id,确保操作不会跨工作空间边界泄漏。

  • _resolve_app_tenant_id(app_id)api/models/model.py:71-75
  • _resolve_workflow_app_tenant_id(app_id)api/models/workflow.py:82-88

工具与提供商隔离

工具提供商多租户

工具配置(API 密钥、OAuth 令牌)严格按租户隔离。即使是内置工具,如果需要凭证,每个租户也需要一个 BuiltinToolProvider 记录。

图示:工具提供商隔离架构

Dify · 工具提供商多租户 · 图 5
Dify · 工具提供商多租户 · 图 5

来源:api/models/tools.py:73-120, api/models/tools.py:128-180

模型提供商隔离

大语言模型(LLM)提供商通过 tenant_id 进行作用域限定。这包括 Provider 配置、ProviderModel 定义和 TenantDefaultModel 选择。

# api/models/provider.py:33-45
class Provider(TypeBase):
    # ...
    __table_args__ = (
        sa.PrimaryKeyConstraint("id", name="provider_pkey"),
        sa.Index("provider_tenant_id_provider_idx", "tenant_id", "provider_name"),
        sa.UniqueConstraint(
            "tenant_id", "provider_name", "provider_type", "quota_type", name="unique_provider_name_type_quota"
        ),
    )
    tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)

来源:api/models/provider.py:33-68, api/models/provider.py:163-180

安全与数据完整性

复合唯一约束

为防止跨租户的名称冲突,同时允许全局范围内存在重复名称,Dify 使用了包含 tenant_id 的复合唯一约束。

约束目的
providersunique_provider_name_type_quota每个租户/提供商的唯一配置
tool_builtin_providersunique_builtin_tool_provider每个租户的唯一凭证实例
tool_api_providersunique_api_tool_provider每个工作空间的唯一 API 工具名称
provider_modelsunique_provider_model_name每个租户的唯一模型配置
tenant_default_modelsunique_tenant_default_model_type每个租户每种类型一个默认模型

来源:api/models/provider.py:42-44, api/models/tools.py:81, api/models/tools.py:136, api/models/provider.py:124-126, api/models/provider.py:168

数据库索引策略

索引设计用于优化租户作用域的查询,通常将 tenant_id 作为复合索引的第一列。

  • Index("dataset_tenant_idx", "tenant_id")api/models/dataset.py:171
  • Index("workflow_version_idx", "tenant_id", "app_id", "version")api/models/workflow.py:183-184
  • Index("provider_tenant_id_provider_idx", "tenant_id", "provider_name")api/models/provider.py:41

来源:api/models/dataset.py:171, api/models/workflow.py:183-184, api/models/provider.py:41