如何为 MLflow 接入 OIDC 身份提供商实现 SSO 单点登录?
【免费下载链接】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 Tracking Server,希望用户不再使用 MLflow 自己的账号体系登录,而是通过现有的 OIDC 身份提供商(IdP)完成单点登录,那么 MLflow 提供了两条路径:安装社区的 mlflow-oidc-auth 认证插件,或者在 MLflow 前面放一层处理 SSO 的反向代理。本文走第一条主路径:配置 OIDC 提供商、部署带 OIDC 插件的 MLflow Server、配置 MLflow 客户端,完成后用户访问http://localhost:8080/会跳转到 IdP 登录页,登录成功后再回到 MLflow 主界面。文档中给出的示例 IdP 包括 Okta Auth0、Google Identity Platform、AWS Cognito 和 Azure Entra ID,下文以 Okta Auth0 为主路径示例,其余提供商作为可选分支给出。
需要说明:mlflow-oidc-auth 插件由社区维护,而非 MLflow 官方维护。插件支持 MLflow UI 与 API 的 OIDC 认证、基于用户和分组的访问控制、基于正则表达式的权限管理,并支持 session、JWT 与 basic authentication 三种认证方式。
整体流程与前置条件
文档将整个接入过程拆成三步:
- 配置 OIDC 提供商(在 IdP 侧注册应用、配置回调地址和分组);
- 部署 MLflow Server 并启用 OIDC 插件(安装插件、设置环境变量、启动 server);
- 配置 MLflow 客户端(通过 basic auth 协议连接 server)。
开始之前你需要准备:
- 一个支持 OIDC 协议的 IdP 账号(Okta Auth0、Google Identity Platform、AWS Cognito 或 Azure Entra ID 均可);
- 一台可以运行
mlflow server的机器; - 明确 MLflow Server 的访问地址,下文示例统一使用
http://localhost:8080,对应的回调地址(callback URL / redirect URI)为http://localhost:8080/callback。
插件依赖两个默认分组的语义,理解它们是后续配置的基础:
- 管理员组(默认组名
mlflow-admin):被分配到该组的用户自动拥有所有实体访问权限,并可以为其他用户授权; - 普通组(默认组名
mlflow):该组用户在对端没有被管理员授权之前,对 MLflow 实体没有任何权限。
因此无论你使用哪个 IdP,都必须保证每个登录用户至少被分配到一个组。
配置 OIDC 身份提供商
Okta Auth0(主路径)
注册 Okta Auth0 账号并登录,为 MLflow 创建一个应用,应用类型选择 "Regular Web Application"。在应用基本信息页记下三个值:
Domain、Client ID、Client Secret,部署 MLflow Server 时会用到。为该 Okta 应用配置允许的回调地址:假设 MLflow Server 部署在
http://localhost:8080,则回调 URL 配置为http://localhost:8080/callback。配置一个 "post-login" 触发放置用户分组。Okta 中任意账号的用户名都可以用来登录带 OIDC 插件的 MLflow Server,但必须给每个用户分配组。文档示例是把某个指定用户分配进
mlflow-admin,其余用户分配进mlflow:在 Okta 侧边栏菜单 Actions -> Library -> Create Actions -> Create Custom Action 中填入如下代码(
somebody@gmail.com是文档示例邮箱,替换为你希望成为管理员的账号):exports.onExecutePostLogin = async (event, api) => { const email = event.user.email; if (email == "somebody@gmail.com") { var group = "mlflow-admin" } else { var group = "mlflow" } api.idToken.setCustomClaim( 'urn:mlflow:groups', [group] ); };然后点击 "Deploy"。
在 Actions -> Triggers -> Sign up & Login: post-login 中安装这个 trigger,使其在用户登录时执行上面的自定义动作。
Google Identity Platform(可选分支)
在 Google Cloud 控制台中,进入APIs & Services→Credentials→Create credentials→OAuth client ID,应用类型选择Web application,并在Authorized redirect URIs中加入回调地址(例如
http://localhost:8080/callback)。在 Google Identity Platform 控制台中添加一个类型为 "OpenID Connect" 的 provider。
Google Identity Platform 不支持 post-login trigger,无法在 IdP 侧配置用户分组,需要改用一个分组检测插件。在启动 MLflow Server 的工作目录下创建
google_oidc_auth_plugin.py(示例把某个指定邮箱分进管理员组,其余用户分进普通组,somebody@gmail.com为文档示例,需替换):import requests def get_user_groups(access_token): resp = requests.get( "https://www.googleapis.com/oauth2/v3/userinfo", headers={"Authorization": f"Bearer {access_token}"}, timeout=10, ) resp.raise_for_status() userinfo = resp.json() # userinfo contains: email, name, picture, sub, etc. email = userinfo.get("email") if email == "somebody@gmail.com": return ["mlflow-admin"] return ["mlflow"]这个文件由下文启动阶段的
OIDC_GROUP_DETECTION_PLUGIN环境变量指向。
AWS Cognito(可选分支)
- 在 AWS 控制台进入 Amazon Cognito -> User pools -> Create user pool,注意 "Required attributes for sign-up" 必须包含
name,并设置 return URL 为 OIDC 重定向地址(如http://localhost:8080/callback)。 - 在该 user pool 中创建类型为 Traditional web application 的 app client,return URL 同样设为回调地址,并编辑 "Managed login pages configuration"。
- 在 User Management -> Groups 中创建两个组:
mlflow和mlflow-admin。 - 在 User Management -> Users 中创建用户,并把用户分配到
mlflow或mlflow-admin组。
Azure Entra ID(可选分支)
- 在 Microsoft Entra ID 门户中进入 Manage -> App registrations,注册一个应用。
- 进入 Manage -> Groups -> New group,创建
mlflow和mlflow-admin两个组。 - 进入 Manage -> Users -> New user,创建用户并分配到
mlflow或mlflow-admin组。 - 在已注册的应用中进入 Manage -> Token configuration -> Add groups claim,添加 groups claim。
部署 MLflow Server 并启用 OIDC 插件
先安装插件:
pip install 'mlflow-oidc-auth[full]'启动 server 前需要设置环境变量。以下四个变量对所有提供商通用(...处替换为你在 IdP 控制台看到的 Client ID / Client Secret):
# OIDC Client ID / Client Secret 可在 # Okta Auth0 / Google Identity Platform / AWS Cognito / Azure Entra ID 控制台的应用信息页查看 export OIDC_CLIENT_ID=... export OIDC_CLIENT_SECRET=... # 在 OIDC 应用中配置的回调地址(redirect URI) export OIDC_REDIRECT_URI="http://localhost:8080/callback" # OAuth 2.0 和 OIDC 将 scope 参数定义为空格分隔的 scope 值列表 export OIDC_SCOPE="openid profile email" # 设置一个稳定且保密的值(例如 32 个以上随机字符),并在重启与多副本间保持一致。 # 如果不设置,应用会自动生成一个密钥,但它会在 server 重启 / UI 页面重载时变化, # 从而导致会话失效。 export SECRET_KEY="your-stable-secret-at-least-32-chars-long"其中SECRET_KEY文档给出的字符串只是占位示例,你需要换成自己的稳定随机值;如果部署了多个 server 副本,所有副本必须使用同一个值。
然后按所用提供商追加专属环境变量:
Okta Auth0:
# ${domain} 替换为 Okta 应用基本信息页中的 Domain 值 export OIDC_DISCOVERY_URL="https://${domain}/.well-known/openid-configuration" # 该值必须与 Okta post-login trigger 中 api.idToken.setCustomClaim 使用的 key 一致 export OIDC_GROUPS_ATTRIBUTE="urn:mlflow:groups"Google Identity Platform:
export OIDC_DISCOVERY_URL="https://accounts.google.com/.well-known/openid-configuration" # 仅 Google Identity Platform 需要此项,指向分组检测插件模块名 # (假设插件文件 google_oidc_auth_plugin.py 位于当前目录) export OIDC_GROUP_DETECTION_PLUGIN=google_oidc_auth_pluginAWS Cognito:
# ${region} 替换为你的 AWS 区域,例如 "ap-southeast-2" # ${user_pool_id} 替换为 user pool ID,例如 ap-southeast-2_XXXXXXXXX export OIDC_DISCOVERY_URL="https://cognito-idp.${region}.amazonaws.com/${user_pool_id}/.well-known/openid-configuration" export OIDC_GROUPS_ATTRIBUTE=cognito:groupsAzure Entra ID:
# ${tenant-id} 替换为 Azure Entra ID 门户 "overview" 页中的 tenant ID export OIDC_DISCOVERY_URL="https://login.microsoftonline.com/${tenant-id}/v2.0/.well-known/openid-configuration" # 以下两个值必须设为在 Azure Entra 中创建的对应组的组 ID # (可在 "all groups" 门户页查看),<...> 处替换为实际组 ID export OIDC_GROUP_NAME=<mlflow 组的组 ID> export OIDC_ADMIN_GROUP_NAME=<mlflow-admin 组的组 ID>环境变量设置完成后,启动带 OIDC 插件的 MLflow Server:
mlflow server --app-name oidc-auth --host 0.0.0.0 --port 8080验证登录与权限配置
浏览器验证方式如下:
打开
http://localhost:8080/,页面应跳转到 OIDC 登录页,使用 IdP 账号登录。登录成功后会跳转到 OIDC 权限配置页。如果当前登录用户属于管理员组(
mlflow-admin),可以在该页面的 UI 中为其他用户配置权限;普通组用户需要等待管理员授权后才能访问对应实体。完成登录后再次打开
http://localhost:8080/,应跳转到 MLflow UI 主页面——这表示 SSO 登录链路已经打通。
客户端连接凭证在同一权限页生成:在 OIDC 权限页为当前用户生成 access token(每次生成新 token 会使前一个 token 立即失效,只有最新生成的 token 有效)。
配置 MLflow 客户端
OIDC 插件允许 MLflow 客户端通过 MLflow basic auth 协议连接 server。在客户端环境设置:
# 设为 Okta / Google / Azure 账号的用户名 export MLFLOW_TRACKING_USERNAME=... # 设为在 OIDC 权限页生成的 access token export MLFLOW_TRACKING_PASSWORD=...然后运行客户端代码验证:
import os import mlflow mlflow.set_tracking_uri("http://localhost:8080") # Use MLflow with mlflow.start_run(): mlflow.log_param("key", "value")能成功创建 run 并记录参数,说明客户端到 SSO server 的认证链路可用。
限制与排查要点
文档中与当前接入直接相关的边界条件:
- mlflow-oidc-auth 是社区维护的插件,不属于 MLflow 官方发布的一部分。
SECRET_KEY未设置或不稳定时,会话会在 server 重启 / UI 页面重载后失效;多副本部署必须共享同一个值。- access token 只保留最新一个有效,重新生成后旧 token 立刻作废,客户端脚本中硬编码 token 的做法会在轮换后断连。
- Okta 路径下
OIDC_GROUPS_ATTRIBUTE必须与 post-login trigger 中setCustomClaim的 key(示例为urn:mlflow:groups)完全一致,否则分组无法生效。 - 回调地址在 IdP 应用配置和
OIDC_REDIRECT_URI两处都必须出现且一致,本文示例统一为http://localhost:8080/callback。 - 普通组(
mlflow)用户在被管理员授权前对 MLflow 实体没有权限,属预期行为而不是登录失败。
替代路径:反向代理处理 SSO
如果不想在 MLflow 侧安装认证插件,文档给出的另一种通用做法是把 MLflow 放到处理 SSO 的代理之后,最典型的实现是 oauth2-proxy 反向代理。步骤概括为:
- 配置代理(NGINX、Traefik、Envoy,或 AWS ALB 等云网关的 OIDC 能力)对接你的 IdP(Okta、Azure AD、Google Workspace)完成用户认证;
- 登录成功后注入用户身份头(例如
X-Email或X-Forwarded-User),并限制只有已认证会话可以访问; - 以不启用 Basic Auth 插件的方式运行 MLflow,把代理作为强制认证层,或者用自定义中间件把传入的身份头映射为 Basic Auth 用户。
这种方式让 MLflow 保持无状态,把 token 校验和 MFA 执行交给专门处理认证的组件,与插件方案的取舍可根据团队现有的网关体系决定。
更多细节可参考仓库中的 SSO 文档 与 基础认证文档。
【免费下载链接】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),仅供参考