MLflow 身份验证
此功能仍处于实验阶段,未来版本可能会在不发出警告的情况下进行更改。
MLflow 支持基本 HTTP 身份验证,以便对实验和注册模型启用访问控制。启用后,任何访问者在查看追踪服务器上的任何资源之前都需要登录。
MLflow 身份验证提供了用于管理用户和权限的 Python 和 REST API。
概述
安装
首先,安装基本身份验证应用所需的所有依赖项
pip install mlflow[auth]
基本身份验证应用需要一个用于 CSRF 保护的密钥。请在运行 mlflow server
命令之前设置 MLFLOW_FLASK_SERVER_SECRET_KEY
环境变量。例如
export MLFLOW_FLASK_SERVER_SECRET_KEY="my-secret-key"
如果您的设置使用多个服务器,请确保此密钥在它们之间保持一致。否则,您可能会遇到意外的验证错误。
要启用 MLflow 身份验证,请使用以下命令启动 MLflow UI
mlflow server --app-name basic-auth
服务器管理员可以通过在不带 app-name
标志的情况下重启服务器来随时禁用此功能。创建的任何用户和权限都将持久化在 SQL 数据库中,并在重新启用该功能后恢复服务。
由于 HTTP 身份验证的特性,它仅在远程追踪服务器上受支持,用户通过 REST API 向服务器发送请求。
工作原理
权限
可用权限如下:
权限 | 可读取 | 可更新 | 可删除 | 可管理 |
---|---|---|---|---|
读取 | 是 | 否 | 否 | 否 |
编辑 | 是 | 是 | 否 | 否 |
管理 | 是 | 是 | 是 | 是 |
无权限 | 否 | 否 | 否 | 否 |
所有用户的默认权限是 READ
。可以在配置文件中更改。
可以为每个用户授予对单个资源的权限。支持的资源包括 Experiment
(实验)和 Registered Model
(注册模型)。要访问 API 端点,用户必须拥有所需的权限。否则,将返回 403 Forbidden
响应。
访问实验所需的权限
API | 端点 | 方法 | 所需权限 |
---|---|---|---|
创建实验 | 2.0/mlflow/experiments/create | POST | 无 |
获取实验 | 2.0/mlflow/experiments/get | GET | 可读取 |
按名称获取实验 | 2.0/mlflow/experiments/get-by-name | GET | 可读取 |
删除实验 | 2.0/mlflow/experiments/delete | POST | 可删除 |
恢复实验 | 2.0/mlflow/experiments/restore | POST | 可删除 |
更新实验 | 2.0/mlflow/experiments/update | POST | 可更新 |
搜索实验 | 2.0/mlflow/experiments/search | POST | 无 |
搜索实验 | 2.0/mlflow/experiments/search | GET | 无 |
设置实验标签 | 2.0/mlflow/experiments/set-experiment-tag | POST | 可更新 |
创建运行 | 2.0/mlflow/runs/create | POST | 可更新 |
获取运行 | 2.0/mlflow/runs/get | GET | 可读取 |
更新运行 | 2.0/mlflow/runs/update | POST | 可更新 |
删除运行 | 2.0/mlflow/runs/delete | POST | 可删除 |
恢复运行 | 2.0/mlflow/runs/restore | POST | 可删除 |
搜索运行 | 2.0/mlflow/runs/search | POST | 无 |
设置标签 | 2.0/mlflow/runs/set-tag | POST | 可更新 |
删除标签 | 2.0/mlflow/runs/delete-tag | POST | 可更新 |
记录指标 | 2.0/mlflow/runs/log-metric | POST | 可更新 |
记录参数 | 2.0/mlflow/runs/log-parameter | POST | 可更新 |
批量记录 | 2.0/mlflow/runs/log-batch | POST | 可更新 |
记录模型 | 2.0/mlflow/runs/log-model | POST | 可更新 |
列出工件 | 2.0/mlflow/artifacts/list | GET | 可读取 |
获取指标历史记录 | 2.0/mlflow/metrics/get-history | GET | 可读取 |
访问注册模型所需的权限
API | 端点 | 方法 | 所需权限 |
---|---|---|---|
创建注册模型 | 2.0/mlflow/registered-models/create | POST | 无 |
重命名注册模型 | 2.0/mlflow/registered-models/rename | POST | 可更新 |
更新注册模型 | 2.0/mlflow/registered-models/update | PATCH | 可更新 |
删除注册模型 | 2.0/mlflow/registered-models/delete | DELETE | 可删除 |
获取注册模型 | 2.0/mlflow/registered-models/get | GET | 可读取 |
搜索注册模型 | 2.0/mlflow/registered-models/search | GET | 无 |
获取最新版本 | 2.0/mlflow/registered-models/get-latest-versions | POST | 可读取 |
获取最新版本 | 2.0/mlflow/registered-models/get-latest-versions | GET | 可读取 |
设置注册模型标签 | 2.0/mlflow/registered-models/set-tag | POST | 可更新 |
删除注册模型标签 | 2.0/mlflow/registered-models/delete-tag | DELETE | 可更新 |
设置注册模型别名 | 2.0/mlflow/registered-models/alias | POST | 可更新 |
删除注册模型别名 | 2.0/mlflow/registered-models/alias | DELETE | 可删除 |
按别名获取模型版本 | 2.0/mlflow/registered-models/alias | GET | 可读取 |
创建模型版本 | 2.0/mlflow/model-versions/create | POST | 可更新 |
更新模型版本 | 2.0/mlflow/model-versions/update | PATCH | 可更新 |
转换模型版本阶段 | 2.0/mlflow/model-versions/transition-stage | POST | 可更新 |
删除模型版本 | 2.0/mlflow/model-versions/delete | DELETE | 可删除 |
获取模型版本 | 2.0/mlflow/model-versions/get | GET | 可读取 |
搜索模型版本 | 2.0/mlflow/model-versions/search | GET | 无 |
获取模型版本下载 Uri | 2.0/mlflow/model-versions/get-download-uri | GET | 可读取 |
设置模型版本标签 | 2.0/mlflow/model-versions/set-tag | POST | 可更新 |
删除模型版本标签 | 2.0/mlflow/model-versions/delete-tag | DELETE | 可删除 |
MLflow 身份验证引入了几个新的 API 端点来管理用户和权限。
API | 端点 | 方法 | 所需权限 |
---|---|---|---|
创建用户 | 2.0/mlflow/users/create | POST | 无 |
获取用户 | 2.0/mlflow/users/get | GET | 仅该用户可读 |
更新用户密码 | 2.0/mlflow/users/update-password | PATCH | 仅该用户可更新 |
更新用户管理员身份 | 2.0/mlflow/users/update-admin | PATCH | 仅管理员 |
删除用户 | 2.0/mlflow/users/delete | DELETE | 仅管理员 |
创建实验权限 | 2.0/mlflow/experiments/permissions/create | POST | 可管理 |
获取实验权限 | 2.0/mlflow/experiments/permissions/get | GET | 可管理 |
更新实验权限 | 2.0/mlflow/experiments/permissions/update | PATCH | 可管理 |
删除实验权限 | 2.0/mlflow/experiments/permissions/delete | DELETE | 可管理 |
创建注册模型权限 | 2.0/mlflow/registered-models/permissions/create | POST | 可管理 |
获取注册模型权限 | 2.0/mlflow/registered-models/permissions/get | GET | 可管理 |
更新注册模型权限 | 2.0/mlflow/registered-models/permissions/update | PATCH | 可管理 |
删除注册模型权限 | 2.0/mlflow/registered-models/permissions/delete | DELETE | 可管理 |
某些 API 的行为也会被修改。例如,实验的创建者将自动被授予对该实验的 MANAGE
(管理)权限,以便创建者可以授予或撤销其他用户对该实验的访问权限。
API | 端点 | 方法 | 效果 |
---|---|---|---|
创建实验 | 2.0/mlflow/experiments/create | POST | 自动授予创建者 MANAGE (管理)权限。 |
创建注册模型 | 2.0/mlflow/registered-models/create | POST | 自动授予创建者 MANAGE (管理)权限。 |
搜索实验 | 2.0/mlflow/experiments/search | POST | 仅返回用户拥有 READ (读取)权限的实验。 |
搜索实验 | 2.0/mlflow/experiments/search | GET | 仅返回用户拥有 READ (读取)权限的实验。 |
搜索运行 | 2.0/mlflow | POST | 仅返回用户拥有 READ (读取)权限的实验。 |
搜索注册模型 | 2.0/mlflow/registered-models/search | GET | 仅返回用户拥有 READ (读取)权限的注册模型。 |
搜索模型版本 | 2.0/mlflow/model-versions/search | GET | 仅返回用户拥有 READ (读取)权限的注册模型。 |
权限数据库
所有用户和权限都存储在 basic_auth.db
数据库中,该数据库相对于启动 MLflow 服务器的目录。可以在配置文件中更改位置。要运行迁移,请使用以下命令:
python -m mlflow.server.auth db upgrade --url <database_url>
管理员用户
管理员用户对所有 MLflow 资源具有无限制的访问权限,包括创建或删除用户、更新其他用户的密码和管理员状态、授予或撤销其他用户的权限,以及管理所有 MLflow 资源的权限,即使为该管理员账户明确设置了 NO_PERMISSIONS
(无权限)。
MLflow 有一个内置的管理员用户,该用户将在首次启用 MLflow 身份验证功能时创建。
建议您在创建后尽快更新默认管理员密码。
默认管理员用户凭据如下:
用户名 | 密码 |
---|---|
admin | password |
可以使用 2.0/mlflow/users/update-admin
端点将其他用户提升为管理员,从而存在多个管理员用户。
# authenticate as built-in admin user
export MLFLOW_TRACKING_USERNAME=admin
export MLFLOW_TRACKING_PASSWORD=password
from mlflow.server import get_app_client
tracking_uri = "http://localhost:5000/"
auth_client = get_app_client("basic-auth", tracking_uri=tracking_uri)
auth_client.create_user(username="user1", password="pw1")
auth_client.update_user_admin(username="user1", is_admin=True)
管理权限
MLflow 提供了REST API 和客户端类 AuthServiceClient
来管理用户和权限。要实例化 AuthServiceClient
,建议您使用 mlflow.server.get_app_client()
。
export MLFLOW_TRACKING_USERNAME=admin
export MLFLOW_TRACKING_PASSWORD=password
from mlflow import MlflowClient
from mlflow.server import get_app_client
tracking_uri = "http://localhost:5000/"
auth_client = get_app_client("basic-auth", tracking_uri=tracking_uri)
auth_client.create_user(username="user1", password="pw1")
auth_client.create_user(username="user2", password="pw2")
client = MlflowClient(tracking_uri=tracking_uri)
experiment_id = client.create_experiment(name="experiment")
auth_client.create_experiment_permission(
experiment_id=experiment_id, username="user2", permission="MANAGE"
)
在 MLflow 中进行身份验证
使用 MLflow UI
当用户首次在浏览器上访问 MLflow UI 时,系统将提示他们登录。登录尝试次数没有限制。
目前,MLflow UI 不显示有关当前用户的任何信息。用户登录后,唯一的退出方法是关闭浏览器。
使用环境变量
MLflow 提供了两个用于身份验证的环境变量:MLFLOW_TRACKING_USERNAME
和 MLFLOW_TRACKING_PASSWORD
。要使用基本身份验证,必须设置这两个环境变量。
export MLFLOW_TRACKING_USERNAME=username
export MLFLOW_TRACKING_PASSWORD=password
import mlflow
mlflow.set_tracking_uri("https://<mlflow_tracking_uri>/")
with mlflow.start_run():
...
使用凭据文件
您可以将凭据保存在文件中,从而无需每次都设置环境变量。凭据应使用 INI
格式保存在 ~/.mlflow/credentials
中。请注意,密码将以未加密的形式存储在磁盘上,仅受文件系统权限保护。
如果配置了环境变量 MLFLOW_TRACKING_USERNAME
和 MLFLOW_TRACKING_PASSWORD
,它们将覆盖凭据文件中提供的任何凭据。
[mlflow]
mlflow_tracking_username = username
mlflow_tracking_password = password
使用 REST API
用户可以使用 HTTP Authorization
请求头进行身份验证。有关更多信息,请参阅 https://mdn.org.cn/en-US/docs/Web/HTTP/Authentication。
在 Python 中,您可以使用 requests
库
import requests
response = requests.get(
"https://<mlflow_tracking_uri>/",
auth=("username", "password"),
)
创建新用户
要创建新用户,您需要使用管理员权限进行身份验证。
使用 MLflow UI
MLflow UI 在 <tracking_uri>/signup
处提供了一个创建新用户的简单页面。
使用 REST API
或者,您可以向追踪服务器端点 2.0/users/create
发送 POST
请求。
在 Python 中,您可以使用 requests
库
import requests
response = requests.post(
"https://<mlflow_tracking_uri>/api/2.0/mlflow/users/create",
json={
"username": "username",
"password": "password",
},
)
使用 MLflow AuthServiceClient
MLflow AuthServiceClient
提供了一个函数,可以轻松创建新用户。
import mlflow
auth_client = mlflow.server.get_app_client(
"basic-auth", tracking_uri="https://<mlflow_tracking_uri>/"
)
auth_client.create_user(username="username", password="password")
配置
身份验证配置文件位于 mlflow/server/auth/basic_auth.ini
变量 | 描述 |
---|---|
默认权限 | 对所有资源的默认权限 |
数据库 URI | 存储权限和用户数据的数据库位置 |
管理员用户名 | 如果管理员尚未创建,则使用此默认管理员用户名 |
管理员密码 | 如果管理员尚未创建,则使用此默认管理员密码 |
授权函数 | 用于验证请求的函数 |
或者,将环境变量 MLFLOW_AUTH_CONFIG_PATH
指向您的自定义配置文件。
authorization_function
设置支持可插拔的身份验证方法,如果您想使用 HTTP 基本身份验证以外的其他身份验证方法。该值指定 module_name:function_name
。该函数具有以下签名:
def authenticate_request() -> Union[Authorization, Response]:
...
如果请求已通过身份验证,该函数应返回一个 werkzeug.datastructures.Authorization
对象;如果请求未通过身份验证,则应返回一个 Response
对象(通常是 401: Unauthorized
)。有关如何实现自定义身份验证方法的示例,请参阅 tests/server/auth/jwt_auth.py
。注意:此示例不适用于生产环境。
连接到集中式数据库
默认情况下,MLflow 身份验证使用本地 SQLite 数据库存储用户和权限数据。在多节点部署的情况下,建议使用集中式数据库来存储此数据。
要连接到集中式数据库,可以将 database_uri
配置变量设置为数据库 URL。
[mlflow]
database_uri = postgresql://username:password@hostname:port/database
然后,设置环境变量 MLFLOW_AUTH_CONFIG_PATH
为您的配置文件路径,并启动 MLflow 服务器。
MLFLOW_AUTH_CONFIG_PATH=/path/to/my_auth_config.ini mlflow server --app-name basic-auth
在启动 MLflow 服务器之前必须创建数据库。服务器启动时将自动创建数据库模式。
自定义身份验证
MLflow 身份验证被设计为可扩展的。如果您的组织需要更高级的身份验证逻辑(例如,基于令牌的身份验证),可以安装第三方插件或创建自己的插件。
您的插件应该是一个可安装的 Python 包。它应该包含一个扩展 MLflow 应用的工厂函数,并且可以选择实现一个客户端来管理权限。应用工厂函数的名称将作为 --app
参数传递给 Flask CLI。有关更多信息,请参阅 https://flask.org.cn/en/latest/cli/#application-discovery。
from flask import Flask
from mlflow.server import app
def create_app(app: Flask = app):
app.add_url_rule(...)
return app
class MyAuthClient:
...
然后,应该在您的 Python 环境中安装该插件
pip install my_auth
然后,在 mlflow/setup.py
中注册您的插件
setup(
...,
entry_points="""
...
[mlflow.app]
my-auth=my_auth:create_app
[mlflow.app.client]
my-auth=my_auth:MyAuthClient
""",
)
然后,您可以启动 MLflow 服务器
mlflow server --app-name my-auth