Enable model-registry with UI by default#3318
Enable model-registry with UI by default#3318Raakshass wants to merge 15 commits intokubeflow:masterfrom
Conversation
|
Welcome to the Kubeflow Manifests Repository Thanks for opening your first PR. Your contribution means a lot to the Kubeflow community. Before making more PRs: Community Resources:
Thanks again for helping to improve Kubeflow. |
|
hey @juliusvonkohout can you just review this pr. |
I am still on vacation, but maybe @tarilabs can help sooner. Are you sure that the catalog and everything is properly exposed in the dashboard UI @Raakshass? Do you mind sharing screenshots? Think of how we expose Kserve models web application in the dashboard. |
|
@Raakshass are you sure that it is properly exposed similar to the kserve models web application (endpoints) in the dashboard UI? I would like to see screenshots of the dashboard and the actual UI changes you made. Please check the original issue and related ones in the Model-Registry git repository. I think you are missing 80% of the work. |
6b078df to
7f88e4f
Compare
|
could you kindly share screenshot with @ederign as Julius suggested please on this thread? |
applications/centraldashboard/upstream/overlays/kserve/patches/configmap.yaml
Show resolved
Hide resolved
|
Hey @ederign @juliusvonkohout @tarilabs, I’ve been following this PR and the related issue for a few days and thought I could jump in to help move things forward. I’d really appreciate a review when you get a chance. Thanks! |
|
I've commented on #3323 |
|
Hi @juliusvonkohout @tarilabs — addressing the feedback about showing the actual dashboard/UI change. What changed in this update
Why this changeKubeflow’s documentation for Model Registry installation and dashboard customization indicates the Model Registry entry should be added to the Central Dashboard configuration so it appears in the sidebar menu. Verification status
If you’d like the menu item to also include |
|
I think you can use a general named one called applications/centraldashboard/overlays/kustomization.yaml We should also merge https://github.com/kubeflow/manifests/blob/master/applications/centraldashboard/overlays/oauth2-proxy/kustomization.yaml into that because oauth2-proxy is anyway mandatory. |
26abe05 to
6c83297
Compare
|
@juliusvonkohout Refactor complete! |
|
Hi @juliusvonkohout @kimwnasptd, I wanted to follow up on this PR. I noticed it's listed as a related issue for GSoC 2026 Project 4 (Platform Scalability and Security) - which is exciting! Is there anything else needed from my side to move this forward? Happy to make any additional changes. Thanks for your time! |
- Resolved conflicts in model_catalog_test.yaml, model_registry_test.yaml, and README.md - Kept composite action usage and Model Registry README section from PR branch - Incorporated all upstream master changes Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
- Fix yamllint violation: change indentation from 4 to 2 spaces for list items under steps (indent-sequences: false) - Remove nonexistent kubectl_install.sh step — kubectl is already installed by install_KinD_create_KinD_cluster_install_kustomize.sh - Now matches master's exact 8-step setup pattern Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
|
@juliusvonkohout All open comments have been addressed: Copilot comments:
@manaswinidas comments:
CI deduplication:
All 8 CI checks are green. Ready for review when convenient. Signed-off-by: Siddhant Jain siddhantjainofficial26@gmail.com |
- Remove .github/actions/setup-kubeflow-base/ folder (separate PR planned) - Revert model_catalog_test.yaml to inline setup steps (match master) - Revert model_registry_test.yaml to inline setup steps (match master) - Add RegisteredModel, ModelVersion, ModelArtifact creation to test.sh - Verify created model appears in API listing Addresses reviewer feedback to remove the extra folder and ensure tests cover basic user interactions like creating a dummy model. Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
- Move tests/model_registry_test/install.sh to tests/model_registry_install.sh - Move tests/model_registry_test/test.sh to tests/model_registry_test.sh - Delete tests/model_registry_test/ subfolder (consistency with master) - Fix ModelVersion POST: add registeredModelId to request body (fixes 422) - Fix ModelArtifact POST: add modelVersionId to request body - Update model_registry_test.yaml workflow to reference flat test files - Drop extra Spark details link from README (matches master) - Update README Model Registry section to use flat paths Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
- Replace while-loop port-forward waits with timeout+until one-liner - Consolidate inline Model Registry steps in full integration test to use model_registry_install.sh and model_registry_test.sh scripts - Remove stale PID variable references Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
|
@hbelmiro @Al-Pragliola may you take a look and lgtm is that is how you want model registry and catalog ? |
|
Hi @juliusvonkohout — here is the architectural change overview you requested. Every claim below is verified by reading the raw upstream YAML files on master (links provided). 1. No New Namespaces — ConfirmedI verified every individual YAML resource file referenced by the 4 new How namespace is determined per component:
2. PSS Restricted Compliance — All Workloads VerifiedSince no new namespaces are introduced, the existing
The catalog demo overlay also adds an 3. Complete Resource DiffMaster's This PR adds: +- ../applications/model-registry/upstream/overlays/postgres
+- ../applications/model-registry/upstream/options/istio
+- ../applications/model-registry/upstream/options/ui/overlays/istio
+- ../applications/model-registry/upstream/options/catalog/overlays/demoNamespace-scoped resources (all in
|
| Kind | Name |
|---|---|
| Deployment | model-registry-deployment |
| Service | model-registry-service |
| ServiceAccount | model-registry-server |
| ConfigMap | model-registry-configmap |
| Deployment | model-registry-db |
| Service | model-registry-db |
| PVC | metadata-postgres (10Gi) |
| ConfigMap | model-registry-db-parameters (generated) |
| Secret | model-registry-db-secrets (generated) |
Istio Networking:
| Kind | Name |
|---|---|
| VirtualService | model-registry (prefix: /api/model_registry/, gateway: kubeflow-gateway) |
| DestinationRule | model-registry-service (mTLS) |
| AuthorizationPolicy | model-registry-service (ALLOW all) |
UI:
| Kind | Name |
|---|---|
| Deployment | model-registry-ui |
| Service | model-registry-ui-service (port 80 via patch) |
| ServiceAccount | model-registry-ui |
| VirtualService | model-registry-ui (prefix: /model-registry/) |
| DestinationRule | model-registry-ui (mTLS) |
| AuthorizationPolicy | model-registry-ui (source: istio-ingressgateway-service-account) |
Model Catalog (demo):
| Kind | Name |
|---|---|
| Deployment | model-catalog-server |
| Service | model-catalog |
| StatefulSet | model-catalog-postgres (postgres:17.6) |
| Service | model-catalog-postgres |
| PVC | model-catalog-postgres (5Gi) |
| ConfigMap | model-catalog-sources (generated) |
| ConfigMap | model-catalog-demo-perf-data (generated) |
| Secret | model-catalog-postgres (generated) |
| Secret | model-catalog-hf-api-key (generated) |
Cluster-scoped resources (from UI component):
| Kind | Name | Purpose |
|---|---|---|
| ClusterRole | model-registry-ui-services-reader |
get/list/watch Services |
| ClusterRoleBinding | model-registry-ui-services-reader-binding |
Binds above to SA model-registry-ui |
| ClusterRole | model-registry-retrieve-clusterrolebindings |
get/list/watch ClusterRoleBindings |
| ClusterRoleBinding | model-registry-retrieve-clusterrolebindings-binding |
Binds above to SA model-registry-ui |
| ClusterRole | model-registry-create-sars |
create SubjectAccessReviews |
| ClusterRoleBinding | model-registry-create-sars-binding |
Binds above to SA model-registry-ui |
Source: model-registry-ui-role.yaml
Note: The Model Catalog has its own separate PostgreSQL (
model-catalog-postgres, StatefulSet, postgres:17.6) distinct from Model Registry's database (model-registry-db, Deployment, postgres:16-alpine).
4. PostgreSQL Switch — Confirmed
This PR switches from overlays/db (MySQL) to overlays/postgres (PostgreSQL):
| Master CI (inline) | This PR | |
|---|---|---|
| Overlay path | overlays/db |
overlays/postgres |
| DB image | mysql:8.0 |
postgres:16-alpine |
| Server DSN | mysql:// via --embedmd-database-dsn |
postgresql:// via --embedmd-database-type=postgres |
| Base resources | ../../base (identical) |
../../base (identical) |
5. Central Dashboard Change
Base changed from ../../upstream/overlays/kserve → ../../upstream/overlays/istio, with a custom configmap patch.
Reason: The upstream kserve overlay extends ../istio and adds a configmap patch with menu items. This PR goes to istio directly and provides its own equivalent configmap patch — identical to the kserve overlay's patch except for one addition:
{
"icon": "assignment",
"link": "/model-registry/",
"text": "Model Registry",
"type": "item"
}All existing menu items (Notebooks, TensorBoards, Volumes, Katib, KServe Endpoints, Pipelines) are preserved exactly.
6. CI/Testing Changes
Inline CI steps consolidated into reusable scripts:
tests/model_registry_install.sh— installs all 4 components withkubectl apply -n kubeflow, includeskubectl waitwith diagnostic output on failuretests/model_registry_test.sh— CRUD tests (RegisteredModel → ModelVersion → ModelArtifact), plus authenticated/unauthorized gateway access tests
Both full_kubeflow_integration_test.yaml and model_registry_test.yaml now call these scripts instead of inline commands.
Signed-off-by: Siddhant Jain siddhantjainofficial26@gmail.com
|
Hello @Raakshass please let me know if you need any help to close this PR!! |
Please test and provide feedback. Now after the 26.03 release we could merge it |
|
Yeah Sure! |
|
Hello @juliusvonkohout, Verification Report: PR #3318 — Model Registry IntegrationHi, I have completed a full local testing on this PR. Here is my findings / feedback:- ✅ What Works
|
Can you elaborate a bit and provide links to files ? |
|
Hello @juliusvonkohout While the deployment is functional, the Istio-level security posture is currently permissive (ALLOW ALL), which presents a multi-tenancy risk. 1. Relevant Manifests
2. Technical Analysis of
|
…pattern
Replace permissive rules: [{}] with the same dual-path pattern used by
ml-pipeline-ui: (1) allow ingress-gateway traffic (authenticated by
authservice), (2) allow internal K8s JWTs while blocking kubeflow-userid
header spoofing. Add Authorization headers to port-forward CRUD tests
and add negative security tests for unauthenticated access and identity
spoofing.
Ref: applications/pipeline/upstream/base/installs/multi-user/istio-authorization-config.yaml
Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
kubectl port-forward creates a direct TCP tunnel to the pod, bypassing the Istio sidecar proxy. AuthorizationPolicy rules are not enforced on port-forwarded traffic. Remove Tests 7-8 and unnecessary Authorization headers from CRUD tests. AP enforcement is validated through gateway tests (authorized=200, unauthorized=403). Signed-off-by: Siddhant Jain <siddhantjainofficial26@gmail.com>
|
@juliusvonkohout @abdullahpathan22 Status Update: Security finding addressed. PR is Merge-Ready. 1. Security Hardening:
|
Review: Potential Security Improvement — AuthorizationPolicy for Model RegistryHello @juliusvonkohout / @Raakshass, I noticed one security gap that we could address before merging. The ProblemLooking at the resource diff, the current AuthorizationPolicy: model-registry-service → action: ALLOW allThis means any pod in the cluster can call the Model Registry API freely, with no identity checks. In a multi-tenant Kubeflow deployment this is a real security gap — a rogue pod in any namespace could read or modify another user's registered models. Potential Solution — Follow KFP's Dual-Path PatternKFP already solves this exact problem in # For model-registry-service (the API server)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: model-registry-service
namespace: kubeflow
spec:
selector:
matchLabels:
app: model-registry
rules:
# Path 1: Allow real user traffic authenticated at the Istio gateway
# (requests coming through the Central Dashboard)
- from:
- source:
principals:
- cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account
# Path 2: Allow internal K8s service-to-service traffic
# Only if it carries a K8s JWT (Authorization header)
# AND does NOT carry a kubeflow-userid header
# This prevents any pod from spoofing a user identity across the mesh
- when:
- key: request.headers[authorization]
values:
- "*"
- key: request.headers[kubeflow-userid]
notValues:
- "*"# For model-registry-ui (the frontend)
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: model-registry-ui
namespace: kubeflow
spec:
selector:
matchLabels:
app: model-registry-ui
rules:
# Allow only traffic from the Istio ingress gateway
- from:
- source:
principals:
- cluster.local/ns/istio-system/sa/istio-ingressgateway-service-accountWhy This Works
This is the same security model KFP uses and would make Model Registry consistent with the rest of the Kubeflow platform. |

Summary of Changes
This PR enables the Model Registry server, UI, and demo catalog components in the default Kubeflow installation (
example/kustomization.yaml), updates the Central Dashboard to include a Model Registry menu entry, adds README documentation, and adds CI tests with model CRUD verification.Components added to
example/kustomization.yaml:overlays/postgres)options/istio)options/ui/overlays/istio)options/catalog/overlays/demo)Central Dashboard:
applications/centraldashboard/overlays/oauth2-proxy/kustomization.yamlto use istio base overlay instead of kservepatches/configmap.yamlwith Model Registry menu entry alongside existing KServe Endpoints entryCI / Testing:
Documentation:
Dependencies
No external dependencies. Uses existing upstream manifests from
applications/model-registry/.Related Issues
Closes #3047