MLflow Authentication Python API 深度指南:AuthServiceClient 与认证实体模型全解析
2026/9/10 20:16:10 网站建设 项目流程

MLflow Authentication Python API 深度指南:AuthServiceClient 与认证实体模型全解析

【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow

MLflow 作为面向 Agent、LLM 与机器学习模型的开源 AI 工程平台,其自带的 Basic Authentication 插件为追踪服务器提供了用户、角色(RBAC)与资源权限的一整套访问控制能力。本指南以官方 API 参考文档 docs/api_reference/source/auth/python-api.rst 为骨架,系统讲解mlflow.server.auth.client.AuthServiceClient的全部客户端方法与mlflow.server.auth.entities中的实体数据模型,并结合仓库源码剖析其底层 REST 调用链、权限等级设计与测试验证方式,帮助你用 Python 代码完整地管理 MLflow 认证体系。

一、认证插件与 Python API 的关系

MLflow 追踪服务器默认不启用身份认证,需要启动 Basic Authentication 插件(mlflow.server.auth)后才能使用认证能力。该插件在 mlflow/server/auth/ 目录下实现,核心模块包括:

  • client.py:面向用户的AuthServiceClient客户端类,即本文主角;
  • entities.py:用户、角色、权限等 REST 响应的数据模型;
  • routes.py:全部认证相关 REST 端点路径定义;
  • permissions.py:权限等级(READ/USE/EDIT/MANAGE)与资源类型常量;
  • config.pybasic_auth.ini:认证插件的配置读取与默认配置。

官方 API 文档正是通过 Sphinx 的autoclassautomodule指令,将client.pyentities.py中的公开 API 自动渲染成 python-api.rst 页面。因此,"Authentication Python API" 的完整内容就是客户端方法 + 实体模型两部分,下文逐一展开。

二、AuthServiceClient:认证服务的 Python 客户端

AuthServiceClient定义在 mlflow/server/auth/client.py#L35,官方文档对其定位的说明是:面向启用了默认基本认证插件的 MLflow 追踪服务器的客户端,并明确推荐使用mlflow.server.get_app_client()工厂函数来实例化,而非直接调用构造函数。

2.1 实例化方式

构造函数签名只有一个必填参数tracking_uri,即本地或远程追踪服务器的地址:

from mlflow.server.auth.client import AuthServiceClient # 直接构造(不推荐) client = AuthServiceClient("http://localhost:5000") # 推荐:通过应用客户端工厂构造 client = mlflow.server.get_app_client("basic-auth", "http://localhost:5000")

get_app_client实现在 mlflow/server/init.py#L245,它根据app_name(例如"basic-auth")从 Python 入口点mlflow.app.client中查找并加载对应的客户端类,找不到时抛出MlflowException。使用工厂方法的优势在于:未来认证插件实现变化时,调用方代码无需改动。

2.2 底层 REST 调用机制

AuthServiceClient的所有方法都收敛到私有方法_request(client.py#L49):

def _request(self, endpoint, method, *, expected_status: int = 200, **kwargs): host_creds = get_default_host_creds(self.tracking_uri) resp = http_request(host_creds, endpoint, method, **kwargs) resp = verify_rest_response(resp, endpoint, expected_status=expected_status) if resp.status_code == 204 or not resp.content: return {} return resp.json()

其工作流程为:

  1. 通过get_default_host_creds(tracking_uri)解析主机凭据——这也是为什么所有需要鉴权的操作都要求先配置MLFLOW_TRACKING_USERNAMEMLFLOW_TRACKING_PASSWORD环境变量;
  2. http_request发起 HTTP 请求(端点路径来自routes.py中的常量);
  3. verify_rest_response校验响应状态码(默认期望 200);
  4. 204 No Content或空响应体统一返回{},否则解析 JSON。

端点路径集中在 mlflow/server/auth/routes.py,例如用户管理端点CREATE_USER = /api/2.0/mlflow/users/createGET_USER = /api/2.0/mlflow/users/get,角色管理端点(RBAC 部分)则统一走/api/2.0/mlflow/roles/*(version=3)路径。每个端点同时暴露 REST 与 AJAX 两个变体,分别供 Python 客户端与 MLflow 前端 UI 使用。

三、用户管理 API

AuthServiceClient提供 5 个用户管理方法,覆盖用户的创建、查询、改密、管理员授权与删除全生命周期。

3.1 create_user 创建用户

client = AuthServiceClient("tracking_uri") user = client.create_user("newuser", "newpassword") print(f"user_id: {user.id}") print(f"username: {user.username}") print(f"password_hash: {user.password_hash}") print(f"is_admin: {user.is_admin}")

输出示例(来自官方 docstring):

user_id: 3 username: newuser password_hash: REDACTED is_admin: False

要点:

  • 参数usernamepassword,其中 password 不允许为空字符串;
  • 若用户名已存在,抛出mlflow.exceptions.RestException
  • 返回User实体对象,其password_hash属性恒为"REDACTED"——这是 entities.py#L51 中User.from_json的刻意设计:哈希值只允许在服务端存储,绝不通过 REST API 回传明文哈希
  • 新建用户默认is_admin=False

3.2 get_user 查询用户

export MLFLOW_TRACKING_USERNAME=admin export MLFLOW_TRACKING_PASSWORD=password
client = AuthServiceClient("tracking_uri") client.create_user("newuser", "newpassword") user = client.get_user("newuser")

用户不存在时抛出RestException。注意调用前必须先设置管理员凭据环境变量,因为用户管理端点要求认证。

3.3 update_user_password 修改密码

# 管理员路径 —— 无需 current_password client.update_user_password("newuser", "anotherpassword") # 自助服务路径 —— 必须提供 current_password client.update_user_password("newuser", "thirdpassword", current_password="anotherpassword")

方法签名(client.py#L145):

def update_user_password(self, username: str, password: str, current_password: str | None = None)

设计规则:

  • current_password为可选项,但用户修改自己的密码(自助服务)时必填,否则服务端拒绝请求;
  • 管理员修改他人密码时可省略该参数;
  • 底层发送PATCH /api/2.0/mlflow/users/update-password
  • 若用户不存在、或 current_password 缺失/错误,抛出RestException

3.4 update_user_admin 设置管理员

client.update_user_admin("newuser", True)

is_admin更新为True/False,发送PATCH /api/2.0/mlflow/users/update-admin,用户不存在时抛出RestException

3.5 delete_user 删除用户

client.delete_user("newuser")

发送DELETE /api/2.0/mlflow/users/delete。删除操作同样受管理员权限约束。

3.6 用户管理 API 一览

方法HTTP端点(REST 路径)关键行为
create_userPOST/mlflow/users/create重名抛异常,password 不可为空
get_userGET/mlflow/users/get不存在抛异常
update_user_passwordPATCH/mlflow/users/update-password自助改密需current_password
update_user_adminPATCH/mlflow/users/update-admin设置/取消管理员
delete_userDELETE/mlflow/users/delete删除指定用户

测试用例位于 tests/server/auth/test_client.py,例如test_create_usertest_get_user分别验证了"未认证访问抛UNAUTHENTICATED(You are not authenticated.)"与"非管理员调用抛PERMISSION_DENIED(Permission denied.)"的异常路径,可作为调用方错误处理的参照。

四、角色管理 API(RBAC)

角色管理是AuthServiceClient# ---- Role management (RBAC) ----注释(client.py#L256)之后集中提供的能力,让管理员把一组权限打包成角色,再批量授予用户。

4.1 角色的创建、查询与列表

# 创建角色(指定 workspace 与名称,description 可选) role = client.create_role(workspace="default", name="data-scientist", description="ML training access") print(role.id, role.name, role.workspace, role.description) # 按 ID 查询角色 role = client.get_role(role_id=1) # 列出某 workspace 下的全部角色 roles = client.list_roles(workspace="default") # 跨 workspace 列出全部角色(admin-only,服务端强制校验) all_roles = client.list_all_roles()

签名说明:

  • create_role(workspace, name, description=None) -> Role
  • get_role(role_id) -> Rolerole_id会被转为字符串作为查询参数;
  • list_roles(workspace) -> list[Role]
  • list_all_roles()list_roles共用LIST_ROLES端点,但省略workspace参数后返回跨 workspace 的全量列表(仅管理员可用,服务端强制校验),见 client.py#L339-L343。

4.2 角色的更新与删除

# 更新角色名称与描述(均可选) role = client.update_role(role_id=1, name="ml-engineer", description="Updated") # 删除角色 client.delete_role(role_id=1)

update_role只把非 None 字段放入请求体,发送PATCH /api/2.0/mlflow/roles/update

4.3 角色权限(RolePermission)管理

角色本身不携带权限,需要向角色添加"资源级权限条目":

# 给角色添加一条权限:对实验资源类型、匹配模式 "42" 的实验授予 EDIT rp = client.add_role_permission( role_id=1, resource_type="experiment", resource_pattern="42", permission="EDIT", ) print(rp.id, rp.role_id, rp.resource_type, rp.resource_pattern, rp.permission) # 列出角色全部权限条目 perms = client.list_role_permissions(role_id=1) # 修改某条权限条目的权限等级 rp = client.update_role_permission(role_permission_id=1, permission="MANAGE") # 移除权限条目 client.remove_role_permission(role_permission_id=1)

resource_pattern是资源匹配模式,可用于匹配单个资源 ID 或一组资源(结合 workspace 与资源类型共同定位目标)。权限等级取值必须是READ/USE/EDIT/MANAGE之一(详见下文权限模型一节)。

4.4 用户与角色的绑定

# 把角色分配给用户 assignment = client.assign_role(username="alice", role_id=1) print(assignment.id, assignment.user_id, assignment.role_id) # 解除角色 client.unassign_role(username="alice", role_id=1) # 查看某用户拥有的角色 roles = client.list_user_roles(username="alice") # 查看某角色下的全部用户-角色绑定 assignments = client.list_role_users(role_id=1)

角色相关方法的端点路径集中在 routes.py#L53-L78,全部为/api/2.0/mlflow/roles/*(version=3)与/api/2.0/mlflow/users/roles/*系列,并成对提供 AJAX 路径供前端使用。

五、统一用户权限便捷 API

# ---- Unified per-user permission convenience APIs ----注释(client.py#L345)之后,AuthServiceClient提供了一组面向单个用户的"统一授权/撤销/检查"便捷方法,用统一的(resource_type, resource_id)形态覆盖资源授权,并保留传统按资源 MANAGE 委托的语义。

# 授予用户对某资源的权限 client.grant_user_permission( username="alice", resource_type="experiment", resource_id="42", permission="EDIT", ) # 撤销用户对某资源的权限 client.revoke_user_permission(username="alice", resource_type="experiment", resource_id="42") # 查询用户对某资源的有效权限 result = client.get_user_permission( username="alice", resource_type="experiment", resource_id="42" ) print(result.allowed) # 是否允许访问(对应 Permission.can_use) print(result.permission) # 解析后的有效权限名,如 "EDIT"

从 routes.py 的注释可知(routes.py#L16-L26),grant/revoke会写入用户在活动 workspace 下的合成角色__user_<id>__,而get_user_permission(对应GET /mlflow/users/permissions/get)按照与运行时鉴权相同的方式解析用户的有效权限,因此调用方看到的检查结果与实际请求的鉴权结果完全一致。返回的GetUserPermissionResult中,allowed镜像Permission.can_use(常规访问层),permission为解析后的有效权限名,见 entities.py#L502-L525。

六、entities 实体数据模型

mlflow/server/auth/entities.py 定义了认证 API 的所有数据载体。它们普遍具备三个特征:只读@property访问、to_json()序列化、from_json()反序列化。下文按功能分组说明。

6.1 用户实体 User

class User: id # 用户 ID username # 用户名 password_hash # 恒为 "REDACTED"(from_json 强制脱敏) is_admin # 是否为管理员(可写属性)

User.to_json()输出{id, username, is_admin}不含密码哈希),from_json将哈希固定为"REDACTED"(entities.py#L46-L53),从根源上杜绝哈希泄露。

6.2 角色相关实体

  • Role(entities.py#L353):idname(可写)、workspacedescription(可写)、permissionsRolePermission列表)。from_json在缺少 workspace 字段时回退到DEFAULT_WORKSPACE_NAME
  • RolePermission(entities.py#L416):idrole_idresource_typeresource_patternpermission(可写)。
  • UserRoleAssignment(entities.py#L468):iduser_idrole_id,表示用户-角色绑定关系。

6.3 资源权限实体

针对不同类型的资源,认证系统各自定义了权限实体,字段模式统一为(<资源标识>, user_id, permission)

实体资源标识字段适用资源
ExperimentPermissionexperiment_id实验
RegisteredModelPermissionname(+workspace注册模型
ScorerPermissionexperiment_id,scorer_name在线评分器
GatewaySecretPermissionsecret_idGateway 密钥
GatewayEndpointPermissionendpoint_idGateway 端点
GatewayModelDefinitionPermissionmodel_definition_idGateway 模型定义
MCPServerPermissionnameMCP 服务器

RegisteredModelPermissionScorerPermission拥有两个资源标识字段,分别用resolve_entity_workspace_name解析 workspace。这些实体的存在说明认证粒度不仅覆盖传统 ML 资源(实验、模型),也延伸到 Gateway、MCP 等新一代 Agent/LLM 能力面。

6.4 查询结果与工作区权限

  • GetUserPermissionResult(entities.py#L502):allowed: bool+permission: strget_user_permission的返回类型。
  • WorkspacePermission(entities.py#L528):workspaceuser_idpermission,构造时强制校验三者非空,缺失即抛MlflowException.invalid_parameter_value;额外暴露只读属性can_use,即get_permission(permission).can_usefrom_json同样对缺失字段做显式校验。

七、权限等级模型与资源类型(底层支撑)

理解AuthServiceClient的权限参数取值,必须回到 mlflow/server/auth/permissions.py 中的权限模型。

7.1 五种权限等级

Permission是一个 dataclass,拥有can_read / can_use / can_update / can_delete / can_manage五个能力位(permissions.py#L7-L14)。系统预定义了五个等级(permissions.py#L17-L60):

权限名can_readcan_usecan_updatecan_deletecan_manage语义
READ只读
USE可使用
EDIT可编辑
MANAGE完全管理
NO_PERMISSIONS无权限

权限之间有优先级排序PERMISSION_PRIORITY(NO_PERMISSIONS < READ < USE < EDIT < MANAGE),max_permission(a, b)据此合并取较高者。

7.2 资源类型与可授权限约束

  • 具体资源类型(RESOURCE_TYPE_EXPERIMENTRESOURCE_TYPE_REGISTERED_MODELRESOURCE_TYPE_PROMPTRESOURCE_TYPE_SCORERRESOURCE_TYPE_GATEWAY_SECRETRESOURCE_TYPE_GATEWAY_ENDPOINTRESOURCE_TYPE_GATEWAY_MODEL_DEFINITIONRESOURCE_TYPE_MCP_SERVER)只接受READ/USE/EDIT/MANAGE,显式NO_PERMISSIONS被拒绝——因为"缺失授权 + 配置的 default_permission"已经足以表达无访问权;
  • 工作区级资源类型(RESOURCE_TYPE_WORKSPACEresource_pattern必须为"*")只接受USE(工作区成员:访问 + 创建资源 + 继承 default_permission)与MANAGE(额外获得角色/用户管理工作区管理权),READ/EDIT被有意排除(permissions.py#L96-L134)。

所有非法的权限名、资源类型或不匹配的组合都会抛出MlflowExceptionINVALID_PARAMETER_VALUE),在调用add_role_permission等 API 前即可被服务端校验拦截。

八、配置与认证前提

要使用上述 Python API,需要先以 Basic Authentication 插件模式启动追踪服务器,并配置认证参数。

8.1 配置文件 basic_auth.ini

默认配置位于 mlflow/server/auth/basic_auth.ini:

[mlflow] default_permission = READ database_uri = sqlite:///basic_auth.db admin_username = admin admin_password = password1234 authorization_function = mlflow.server.auth:authenticate_request_basic_auth # 为 true 时,用户继承 reserved 'default' workspace 的 default_permission grant_default_workspace_access = false # workspace_cache_max_size = 10000 # workspace_cache_ttl_seconds = 3600 # auth_cache_max_size = 10000 # auth_cache_ttl_seconds = 0

8.2 配置项语义(来自 config.py)

read_auth_config()(mlflow/server/auth/config.py#L30)读取该文件并解析为AuthConfigNamedTuple:

  • default_permission:资源无显式授权时用户的默认权限(默认READ);
  • database_uri:认证数据的存储后端(默认 SQLite);
  • admin_username/admin_password:初始管理员凭据;
  • authorization_function:鉴权函数入口(默认mlflow.server.auth:authenticate_request_basic_auth),可通过 mlflow/environment_variables.py 中的MLFLOW_AUTH_CONFIG_PATH指定自定义配置文件路径;
  • grant_default_workspace_access:用户是否继承 default workspace 的默认权限(默认 false);
  • workspace_cache_max_size/workspace_cache_ttl_seconds:资源到工作区查询缓存(默认 10000 / 3600 秒);
  • auth_cache_max_size/auth_cache_ttl_seconds:用户名/密码校验缓存,默认关闭(TTL=0);开启后 PBKDF2 哈希比对在同一 (user, password) 上每个 TTL 窗口内最多执行一次,文档注释称请求密集型鉴权工作负载可带来约 3 倍吞吐提升,但缓存位于各 worker 进程内,会引入最长一个 TTL 的陈旧窗口,多 worker 部署与带外变更(直接 SQL、外部 IdP 同步)需要自行权衡;
  • read_database_uri:可选的只读数据库 URI。

8.3 客户端凭据

所有需要鉴权的 API 调用都要通过环境变量携带凭据:

export MLFLOW_TRACKING_USERNAME=admin export MLFLOW_TRACKING_PASSWORD=password

未认证调用将抛出RestExceptionUNAUTHENTICATED,"You are not authenticated."),已认证但权限不足则抛出PERMISSION_DENIED("Permission denied."),这与测试文件 tests/server/auth/test_client.py 中assert_unauthenticated/assert_unauthorized两个辅助上下文管理器断言的行为完全一致。

九、测试验证与最佳实践

仓库在 tests/server/auth/ 下对客户端 API 提供了成体系的测试覆盖:

  • test_client.py:用户管理全流程(创建、查询、改密、管理员、删除)、当前用户查询,以及未认证/越权异常路径;
  • test_client_rbac.py:角色 CRUD、角色权限条目、用户-角色绑定的行为验证;
  • test_client_workspace.py:workspace 相关授权行为验证。

测试通过_init_server(app="mlflow.server.auth:create_app", ...)以隔离的 SQLite 后端启动真实 Flask 服务器(test_client.py#L43-L59),因此是端到端的 REST 验证。

实际集成时的建议:

  1. 一律通过get_app_client("basic-auth", tracking_uri)获取客户端,避免直接依赖AuthServiceClient的实现细节;
  2. 密码哈希只读不看User.password_hash恒为"REDACTED",不要依赖它做任何校验逻辑;
  3. 区分管理员路径与自助服务路径:改密时,用户改自己的密码必须传current_password,管理员改他人密码可省略;
  4. 角色权限条目的permission只能取READ/USE/EDIT/MANAGE,workspace 级授权只接受USE/MANAGE,非法取值会在服务端被拒绝;
  5. get_user_permission做授权预检:它按运行时鉴权同样的逻辑解析有效权限,返回的allowedpermission即真实请求会看到的结果;
  6. 生产环境务必修改basic_auth.ini中的默认管理员密码,并按需开启auth_cache_ttl_seconds(注意多 worker 的陈旧窗口)。

十、结语

MLflow Authentication Python API 以AuthServiceClient为统一入口,向上提供用户、角色(RBAC)、角色权限与按用户便捷授权四层操作能力,向下以entities实体模型承载所有 REST 响应,并由permissions.py的 READ/USE/EDIT/MANAGE 权限模型与多类资源类型构成授权语义的底层支撑。配合 python-api.rst 自动生成的 API 参考、routes.py 的端点清单以及 tests/server/auth/ 的端到端测试,你可以据此在团队中落地一套"按角色授权、按资源管控、按用户审计"的完整访问控制体系。

【免费下载链接】mlflowThe open source AI engineering platform for agents, LLMs, and ML models. MLflow enables teams of all sizes to debug, evaluate, monitor, and optimize production-quality AI applications while controlling costs and managing access to models and data.项目地址: https://gitcode.com/GitHub_Trending/ml/mlflow

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询