基于角色的访问控制 (RBAC)
在 MLflow 中,管理员通过分配角色来授予用户权限。角色是一个预先定义并可多次重复使用的权限分组。通过工作区功能(--enable-workspaces),角色的作用域被限定在工作区内。
前提条件
已启用身份验证 (mlflow server --app-name basic-auth)。
有关设置身份验证和管理用户(登录、注册、管理员状态、密码更新)的信息,请参阅用户名和密码;本页内容从用户已存在的情况开始。
概念
三个实体(用户、角色、资源)通过两个关系连接:角色分配和权限授予。当启用工作区时,角色(及其携带的授权)受限于工作区作用域;有关开启/关闭的区别,请参阅工作区隔离。
- 用户 - 希望访问资源的执行者。
- 资源 - MLflow 中权限管理的客体实体,例如实验、注册模型、提示词 (prompt)、评分器或 AI Gateway 资源(密钥、端点或模型定义)。
- 角色 - 资源权限的命名集合。
角色
角色是 (resource_type, resource_pattern, permission) 授权的命名列表。授权可以针对单个资源 (experiment:42) 或某种类型的所有资源 (experiment:*),因此一个角色既可以表示细粒度的访问,也可以表示广泛的访问。例如,editor(编辑者)角色可以携带 (experiment, *, EDIT),让其成员编辑所有实验,而更细化的角色可以结合 (experiment, 42, READ) 和 (prompt, 7, EDIT)。
权限级别
资源作用域权限的可授予级别包括:
| 权限 | 可读取 (Can read) | 可使用 (Can use) | 可更新 (Can update) | 可删除 (Can delete) | 可管理 (Can manage) |
|---|---|---|---|---|---|
READ | 是 | 否 | 否 | 否 | 否 |
USE | 是 | 是 | 否 | 否 | 否 |
EDIT | 是 | 是 | 是 | 否 | 否 |
MANAGE | 是 | 是 | 是 | 是 | 是 |
USE 用于在不修改资源的情况下消费资源(调用网关端点、引用模型定义、在工作区内创建新实验/注册模型)。
NO_PERMISSIONS 是解析器针对工作区边界情况的拒绝哨兵——例如,当 grant_default_workspace_access 关闭时,用户不属于任何工作区。它不能作为角色权限或直接授权授予;身份验证服务器会拒绝此类分配尝试。当没有角色授权匹配时,生效的权限是服务器的 default_permission(默认为 READ;请参阅权限解析)。
由于授权是通过取最大值来折叠的(请参阅权限解析),因此 RBAC 没有显式的“拒绝”覆盖。若要限制对特定资源的访问,请通过更细化的方式(按资源或资源类型通配符)授予访问权限,而不是持有一个广泛的工作区级授权再试图排除该资源。
权限解析
对于每次授权检查,MLflow 评估用户的有效权限如下:
- 平台管理员旁路:
is_admin = true直接短路并允许。 - 角色派生授权:请求工作区中用户的所有角色都会参与贡献。应用于该资源的授权通过取最大值折叠,优先级最高的权限胜出 (
MANAGE>EDIT>USE>READ)。(workspace, *, MANAGE)会折叠到每次资源检查中——它授予对工作区内所有资源的管理权。(workspace, *, USE)不会折叠到资源检查中;它仅赋予工作区成员资格和创建权限(请参阅工作区隔离)。 - 服务器
default_permission(默认为READ):作为解析结果的最大值基准线(floor)。当完全没有角色授权匹配时,该基准线为最终结果。该基准线不会解除NO_PERMISSIONS——当解析器因工作区边界原因(无工作区成员资格、缺少工作区、查找错误)返回该状态时,拒绝有效。有关多工作区模式下基准线的应用,请参阅工作区隔离。
工作区隔离
工作区是 MLflow 资源的隔离容器。工作区默认关闭。要启用它们,请使用 --enable-workspaces 启动服务器。一旦启用,每个实验、注册模型、提示词、评分器和 AI Gateway 资源都恰好属于一个工作区,且不会跨越边界。
角色和权限遵循相同的边界。工作区 foo 中名为 editor 的角色与 bar 中的 editor 是完全独立的行,在一个工作区中做出的授权在其他任何工作区中均无效。该边界的表现方式取决于是否启用了多工作区支持。
默认(未开启 --enable-workspaces)。 存在一个预留的 default 工作区。所有角色、所有分配、所有权限均在此处。服务器的 default_permission 配置(如果已设置)作为任意 (user, resource) 对的基准线。
多工作区 (--enable-workspaces)。 命名工作区成为一等公民。主页呈现工作区切换器;管理 UI 获得每个工作区的入口点 (/admin/ws?workspace=<name>);角色必须在特定工作区中创建。只有设置了 grant_default_workspace_access 时,服务器的 default_permission 才会在命名工作区中作为基准线;否则,每个命名工作区的有效基准线为拒绝。
特殊 (resource_type='workspace', resource_pattern='*') 插槽上的两个授权定义了整个工作区的访问权限:
USEon(workspace, *)- 工作区成员授权。- 赋予工作区成员资格:用户可以列出并进入该工作区。
- 允许在其中创建新资源(例如,实验、注册模型)。
- 其本身不授予资源级访问权限。单个资源的读取权限来自服务器
default_permission基准线(默认为READ);更高级别需要显式的资源级或资源类型通配符授权。
MANAGEon(workspace, *)- 工作区管理者授权。在工作区内拥有完全权限,包括创建角色、授予权限和管理角色分配。不能执行系统级操作,如删除用户。
预设的 admin 和 user 角色各携带其中一种授权;请参阅默认角色。
用户层级
管理 UI 使用平台管理员作为第一层级,工作区管理者作为第二层级;文档也使用相同的标签。
| 层级 | 表现形式 | 功能特性 |
|---|---|---|
| 平台管理员 | 用户行上的 is_admin = true | 不受系统范围的限制。用户删除和批量操作的唯一执行者。 |
| 工作区管理员 | 通过任何角色持有 (workspace, *, MANAGE) | 在这些工作区内拥有完全权限;可以管理角色、用户和授权。 |
| 普通用户 | 任何其他已认证身份 | 无管理 UI 访问权限;授权仅通过角色派生的权限流程进行。 |
无角色的直接授权
对于单用户单资源的情况,无需创建单用户角色。每个用户都有一个预留的个人角色,用于保存其直接授权;grant_user_permission / revoke_user_permission API 和管理 UI 的直接权限部分会直接写入该角色。从操作员的角度来看,这是一个调用或一个表单字段——预留角色是一个你无需接触的实现细节。
管理 UI: /admin → 用户 → 点击用户 → 编辑访问权限 → 在直接权限部分,添加 (resource, permission) 授权 → 审查 → 应用。
API
auth_client.grant_user_permission("alice", "experiment", "42", "EDIT")
grant_user_permission 受目标资源上的资源级 MANAGE 权限限制(与旧版 create_experiment_permission() 使用的权限检查相同),因此拥有 (experiment, 42, MANAGE) 的实验所有者无需拥有工作区级 MANAGE 即可授予访问权限。角色 API 本身需要工作区 MANAGE 或平台管理员权限,因为创建角色属于管理操作。
对于读取,同类 API 还包括 auth_client.get_user_permission(username, resource_type, resource_id)(通过运行时授权检查所使用的相同解析器返回解析后的有效权限)和 auth_client.list_user_permissions(username)(返回用户在其所有角色中持有的每项授权,并附带 role_id / role_name / workspace)。
常见场景
相较于旧权限模型的一大转变:以往每次“授予 X 对 Y 的访问权限”都是一次性的资源级 POST 请求。现在,你可以将权限集构建为角色,然后将用户分配给该角色。管理 UI 和 AuthServiceClient 都通过相同的基于角色的原语运行。
以下示例假设处于多工作区模式,且你已以平台管理员或 ml-research 的工作区管理者身份进行身份验证。
from mlflow.server import get_app_client
tracking_uri = "https://:5000"
auth_client = get_app_client("basic-auth", tracking_uri=tracking_uri)
1. 给 Alice 授予实验 42 的 EDIT 权限
- 管理 UI
- 角色 API
- 导航至
/admin→ 角色。 - 点击 创建角色。
- 在权限中,添加
experiment:42 → EDIT。 - 在已分配用户中,添加
alice。 - 点击 创建。
role = auth_client.create_role(name="exp-42-editor", workspace="ml-research")
auth_client.add_role_permission(
role_id=role.id,
resource_type="experiment",
resource_pattern="42",
permission="EDIT",
)
auth_client.assign_role(username="alice", role_id=role.id)
2. 给团队授予工作区内所有实验的 READ 权限
通配符模式允许角色应用于尚不存在的资源;添加新实验会自动继承该授权。
- 管理 UI
- 角色 API
- 导航至
/admin→ 角色。 - 点击 创建角色。
- 在权限中,添加资源类型
experiment,模式*(显示为“所有实验”),权限READ。 - 在已分配用户中,添加
alice,bob,carol。 - 点击 创建。
其结构与场景 1 相同,仅有两个区别:resource_pattern="*" 和对团队成员的循环处理。
role = auth_client.create_role(name="experiment-reader", workspace="ml-research")
auth_client.add_role_permission(
role_id=role.id,
resource_type="experiment",
resource_pattern="*",
permission="READ",
)
for member in ("alice", "bob", "carol"):
auth_client.assign_role(username=member, role_id=role.id)
3. 将用户设为工作区管理者
每个新创建的工作区都会预设一个默认的 admin 角色(以及一个 user 角色;请参阅默认角色)。提升用户意味着将该工作区的预设 admin 角色分配给他们。该角色显式携带 (workspace, *, MANAGE)。
- 管理 UI
- 角色 API
- 导航至
/admin→ 用户。 - 点击
alice。 - 点击 编辑访问权限。
- 在角色分配中,添加
ml-research/admin。 - 审查变更 → 应用。
# The seeded `admin` role lives in the workspace; look it up by name.
admin_role = next(r for r in auth_client.list_roles("ml-research") if r.name == "admin")
auth_client.assign_role(username="alice", role_id=admin_role.id)
4. 为 N 个用户组成的团队配置相同的访问权限
创建一个包含所需权限的角色,或复用预设的 <workspace>/user 角色。
- 管理 UI - 从角色出发
- 管理 UI - 从每个用户出发
- 角色 API
- 导航至
/admin→ 角色 → 点击该角色。 - 点击 编辑角色。
- 在已分配用户中,添加所有用户。
- 审查 → 应用。
- 导航至
/admin→ 用户 → 点击用户。 - 点击 编辑访问权限。
- 在角色分配中,添加角色 → 应用。
- 对每个用户重复操作。
每个用户端到端只需一次往返。选择符合操作员心智模型的任何一种方式;结果是一样的。
遍历团队,为每位成员调用一次 assign_role
user_role = next(r for r in auth_client.list_roles("ml-research") if r.name == "user")
for member in ("alice", "bob", "carol"):
auth_client.assign_role(username=member, role_id=user_role.id)
管理 UI
管理 UI 是上述所有功能的操作员交互界面。可通过两个入口点访问:
- 平台管理员 (
is_admin = true) 通过侧边栏的Manage入口导航至/admin。该页面呈现跨工作区视图:系统中的每个用户,每个工作区中的每个角色。 - 工作区管理者点击主页工作区表格中他们所管理的工作区旁边的齿轮图标。链接跳转至
/admin/ws?workspace=<name>,这是仅包含他们可见角色和用户的每个工作区视图。
两种视图共享相同的布局:用户选项卡和角色选项卡。
管理用户

“用户”选项卡列出所有用户及其可见角色。点击用户名打开用户详细信息页面,然后选择编辑访问权限来管理该用户的角色、直接权限和管理员状态(仅限平台管理员)。更改会在应用前通过审查步骤进行预览。

管理角色
“角色”选项卡列出当前作用域内的角色(平台管理员为所有角色;工作区管理者为当前工作区角色)。创建角色打开一个单页表单,包含三个部分(角色详情、权限、已分配用户),并一次性提交。角色详情页面上的编辑角色功能具有相同的结构。


默认角色
当 MLFLOW_RBAC_SEED_DEFAULT_ROLES 开启(默认开启)时,MLflow 会向每个新创建的工作区预设两个角色:
| 角色 | 权限 | 用途 |
|---|---|---|
admin | (workspace, *, MANAGE) | 工作区管理者。在工作区内拥有完全权限。 |
user | (workspace, *, USE) | 工作区成员。读取工作区中的所有资源;可以创建实验和注册模型。 |
创建工作区的用户会自动被分配该工作区的预设 admin 角色。
禁用预设(适用于希望手动定义角色的安装):
export MLFLOW_RBAC_SEED_DEFAULT_ROLES=false
从旧权限模型迁移
如果你是从 MLflow 3.13 之前的版本升级,且使用了资源级权限端点,则 auth-store 回填迁移会将旧的权限表转换为 role_permissions 行。现有授权会在升级后保留——仅 API 层面发生了变化。
通信接口和 AuthServiceClient 的结构变化如下:
| RBAC 前的接口 | 状态 | 替换方案 |
|---|---|---|
资源级权限 REST 端点 + AuthServiceClient 方法 (create_experiment_permission() 等) | 已移除 | grant_user_permission / revoke_user_permission 用于一次性直接授权,或使用角色 API 用于共享集合。 |
工作区权限 REST 端点 + AuthServiceClient 方法 (set_workspace_permission() 等) | 已移除 | 角色 API:分配预设的 admin / user 角色,或创建携带 (workspace, *, ...) 的角色。 |
在网络层,约 24 个旧版资源级 REST 端点合并为 /mlflow/users/permissions/* 下的四个:grant, revoke, get, list。
没有弃用警告窗口:因为 basic-auth 原本就标记为实验性,因此维护数十个产生弃用警告的方法所带来的负担超过了平滑过渡的收益。升级后,单用户单资源工作流为:
# Replace this:
# auth_client.create_experiment_permission(experiment_id, username, "EDIT")
auth_client.grant_user_permission(username, "experiment", experiment_id, "EDIT")
资源级 MANAGE 保留委派。 拥有 (experiment, 42, MANAGE) 的用户仍然可以授予其他用户对实验 42 的访问权限——新的 grant_user_permission / revoke_user_permission 受旧端点使用的相同资源级 MANAGE 检查限制。
回滚
旧版权限表(experiment_permissions、registered_model_permissions、四个 gateway_*_permissions、scorer_permissions、workspace_permissions)会保留在磁盘上,以确保至少一个完整的发布周期内可以回滚。若要恢复 auth-store 架构:
mlflow db downgrade <previous-revision> --backend-store-uri <auth-db-uri>
降级会保留旧表,并删除回填生成的 role_permissions 行。重新运行升级将重新应用回填。旧表将在一个完整发布周期后的后续迁移中删除,因此请相应规划升级时间。
API 参考
完整的角色/权限/用户分配方法列表及其签名位于自动生成的 API 文档中: