本文へ移動
cccskills
無料GitHub で公開

auth:mlflow-oidc-auth

Configure MLflow with mlflow-oidc-auth plugin for Keycloak OIDC authentication

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctlスター 303(GitHub 303 + cccskills 0)
連携ツールKubernetesPostgreSQL

実行スコア 未検証

インストール方法を見る

含まれるファイル(1)

  • SKILL.md7.1 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

MLflow OIDC Authentication

Configure MLflow Tracking Server with Keycloak OIDC authentication using the mlflow-oidc-auth plugin.

Overview

mlflow-oidc-auth is a FastAPI wrapper around MLflow that provides:

  • OIDC authentication via Keycloak
  • Group-based authorization (READ/EDIT/MANAGE permissions)
  • Session management for browser access
  • Basic/Bearer auth for programmatic access

Architecture

Browser → Keycloak OIDC → mlflow-oidc-auth → MLflow Flask → PostgreSQL
OTEL    → mTLS (Istio) → /v1/traces       → MLflow      → PostgreSQL

Required Environment Variables

env:
  # Database for MLflow
  - name: MLFLOW_BACKEND_STORE_URI
    value: "postgresql://user:pass@postgres:5432/mlflow"
  - name: MLFLOW_TRACKING_URI
    value: "postgresql://user:pass@postgres:5432/mlflow"  # Needed for otel_router

  # OIDC Configuration
  - name: OIDC_DISCOVERY_URL
    value: "http://keycloak-service.keycloak:8080/realms/master/.well-known/openid-configuration"
  - name: OIDC_CLIENT_ID
    value: "mlflow"
  - name: OIDC_CLIENT_SECRET
    valueFrom:
      secretKeyRef:
        name: mlflow-oauth-secret
        key: OIDC_CLIENT_SECRET

  # OIDC Groups for Authorization
  - name: OIDC_GROUP_NAME
    value: "mlflow"  # Users must be in this group
  - name: OIDC_ADMIN_GROUP_NAME
    value: "mlflow-admin"  # Admin users group

  # Database for OIDC plugin
  - name: OIDC_USERS_DB_URI
    value: "postgresql://user:pass@postgres:5432/mlflow"

OTEL Trace Ingestion Setup

Problem

mlflow-oidc-auth doesn't include MLflow's otel_router which provides the /v1/traces OTLP endpoint.

Solution: Runtime Patches

Apply two patches before starting the app:

# Patch 1: Add otel_router to get_all_routers()
from mlflow.server.otel_api import otel_router
import mlflow_oidc_auth.routers as routers_module

original_get_all_routers = routers_module.get_all_routers
def patched_get_all_routers():
    return original_get_all_routers() + [otel_router]
routers_module.get_all_routers = patched_get_all_routers

# Patch 2: Exclude /v1/traces from OIDC auth
from mlflow_oidc_auth.middleware.auth_middleware import AuthMiddleware

original_is_unprotected = AuthMiddleware._is_unprotected_route
def patched_is_unprotected(self, path: str) -> bool:
    if path.startswith("/v1/traces"):
        return True
    return original_is_unprotected(self, path)
AuthMiddleware._is_unprotected_route = patched_is_unprotected

# NOW import app (uses patched functions)
from mlflow_oidc_auth.app import app
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=5000)

Security

The /v1/traces endpoint is secured via Istio instead of OIDC:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: mlflow-traces-from-otel
spec:
  targetRefs:
    - kind: Service
      name: mlflow
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - "cluster.local/ns/rossoctl-system/sa/otel-collector"
      to:
        - operation:
            methods: ["POST"]
            paths: ["/v1/traces", "/v1/traces/*"]
    - to:
        - operation:
            notPaths: ["/v1/traces", "/v1/traces/*"]

Waypoint Proxy for L7 Auth

The AuthorizationPolicy needs L7 (path-based) evaluation, which requires a waypoint proxy:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: mlflow-waypoint
  labels:
    istio.io/waypoint-for: service
spec:
  gatewayClassName: istio-waypoint
  listeners:
    - name: mesh
      port: 15008
      protocol: HBONE

Add the waypoint label to the MLflow service:

apiVersion: v1
kind: Service
metadata:
  name: mlflow
  labels:
    istio.io/use-waypoint: mlflow-waypoint

Helm Chart Integration

See charts/rossoctl-deps/templates/mlflow.yaml for the full implementation.

Key values:

mlflow:
  auth:
    enabled: true
    secretName: mlflow-oauth-secret

Programmatic API Access

Using Client Credentials Flow

For E2E tests and CI/CD pipelines, use the MLflow client's OAuth credentials:

import base64
import requests
from kubernetes import client, config

# Get credentials from K8s secret
config.load_kube_config()
k8s = client.CoreV1Api()
secret = k8s.read_namespaced_secret("mlflow-oauth-secret", "rossoctl-system")

client_id = base64.b64decode(secret.data["OIDC_CLIENT_ID"]).decode()
client_secret = base64.b64decode(secret.data["OIDC_CLIENT_SECRET"]).decode()
token_url = base64.b64decode(secret.data["OIDC_TOKEN_URL"]).decode()

# Get token using client credentials flow
response = requests.post(token_url, data={
    "grant_type": "client_credentials",
    "client_id": client_id,
    "client_secret": client_secret,
}, verify=False)

access_token = response.json()["access_token"]

# Set for MLflow Python client
import os
os.environ["MLFLOW_TRACKING_TOKEN"] = access_token

Important: Use the mlflow client credentials, NOT admin-cli. The mlflow-oidc-auth validates the token audience and will reject tokens from other clients.

Troubleshooting

"Authentication required" for /v1/traces

Verify patches are applied:

kubectl logs -n rossoctl-system deploy/mlflow -c mlflow | grep "otel_router"
# Should see: "Patched get_all_routers() to include otel_router"
# Should see: "Excluded /v1/traces from OIDC auth (mTLS via Istio)"

Bearer token rejected with "Invalid token"

Check MLflow logs for SSL errors:

kubectl logs -n rossoctl-system deploy/mlflow -c mlflow | grep -i "ssl\|cert\|jwks"

If you see CERTIFICATE_VERIFY_FAILED, the CA bundle is incomplete. On OpenShift/HyperShift:

  • Set SSL_CERT_FILE (for httpx/authlib) in addition to REQUESTS_CA_BUNDLE
  • Include both ingress CA and root CA in the bundle (HyperShift uses a CA chain)
# In mlflow.yaml startup script:
export SSL_CERT_FILE=/etc/pki/ingress-ca/ingress-ca.pem && \
export REQUESTS_CA_BUNDLE=/etc/pki/ingress-ca/ingress-ca.pem && \

SQLite errors for trace storage

Ensure both MLFLOW_BACKEND_STORE_URI AND MLFLOW_TRACKING_URI are set to PostgreSQL.

Traces not appearing

  1. Check OTEL collector logs:
kubectl logs -n rossoctl-system deploy/otel-collector | grep mlflow
  1. Verify trace count in database:
kubectl exec -n rossoctl-system postgres-otel-0 -- \
  psql -U postgres -d mlflow -c "SELECT COUNT(*) FROM trace_info;"
  1. Check AuthorizationPolicy:
kubectl get authorizationpolicy -n rossoctl-system mlflow-traces-from-otel -o yaml

Known Limitations

  1. No path exclusion config: mlflow-oidc-auth hardcodes unprotected paths
  2. Missing otel_router: Not included in get_all_routers()
  3. Direct Access Grants disabled: MLflow client uses client_credentials flow only, not password grant

Future Improvements

  • Upstream PR for OIDC_EXCLUDE_PATHS environment variable
  • Upstream PR to include otel_router in standard routers
  • Consider Istio-level auth as alternative to application auth

Related Skills

  • auth:otel-oauth2-exporter
  • auth:keycloak-confidential-client
  • istio:ambient-waypoint

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

auth

無料

Authentication and authorization patterns for Rossoctl services

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Create confidential OAuth2 clients in Keycloak for server-to-service authentication

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Configure OpenTelemetry Collector with OAuth2 authentication for trace export

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

ci

無料

CI pipeline monitoring, status checks, and PR validation workflows

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

Monitor running CI jobs, wait for completion, create tasks for results

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

ci:status

無料

Check PR CI status - all checks, failures, test results, and artifacts

日本語の概要は準備中です。原文の説明を表示しています。

rossoctl/rossoctl3032026年10月25日 更新

rossoctl のスキルをすべて見る

このスキルの問題を報告する