From 9efc35189e5c28bd4b525492288cb45ee7e9f11f Mon Sep 17 00:00:00 2001 From: danish9039 Date: Fri, 22 May 2026 02:54:19 +0530 Subject: [PATCH 01/19] helm: add oauth2-proxy wrapper chart Signed-off-by: danish9039 --- .../helm/charts/oauth2-proxy/Chart.yaml | 21 ++ .../helm/charts/oauth2-proxy/README.md | 46 +++++ .../charts/oauth2-proxy/ci/values-base.yaml | 8 + .../ci/values-m2m-dex-and-eks.yaml | 12 ++ .../ci/values-m2m-dex-and-kind.yaml | 16 ++ .../oauth2-proxy/ci/values-m2m-dex-only.yaml | 11 ++ .../oauth2-proxy/files/kubeflow-logo.svg | 15 ++ .../oauth2-proxy/files/oauth2_proxy.cfg | 79 ++++++++ .../oauth2-proxy/templates/_helpers.tpl | 39 ++++ .../templates/cluster-jwks-proxy.yaml | 85 ++++++++ .../templates/istio-external-auth.yaml | 68 +++++++ .../charts/oauth2-proxy/templates/m2m.yaml | 16 ++ .../oauth2-proxy/templates/namespace.yaml | 8 + .../templates/networkpolicies.yaml | 40 ++++ .../oauth2-proxy/templates/oauth2-proxy.yaml | 184 ++++++++++++++++++ .../helm/charts/oauth2-proxy/values.yaml | 58 ++++++ tests/helm_kustomize_compare.py | 23 ++- tests/helm_kustomize_compare.sh | 35 +++- tests/helm_kustomize_compare_all.sh | 6 +- 19 files changed, 758 insertions(+), 12 deletions(-) create mode 100644 experimental/helm/charts/oauth2-proxy/Chart.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/README.md create mode 100644 experimental/helm/charts/oauth2-proxy/ci/values-base.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg create mode 100644 experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg create mode 100644 experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl create mode 100644 experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/templates/m2m.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/templates/namespace.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml create mode 100644 experimental/helm/charts/oauth2-proxy/values.yaml diff --git a/experimental/helm/charts/oauth2-proxy/Chart.yaml b/experimental/helm/charts/oauth2-proxy/Chart.yaml new file mode 100644 index 0000000000..7e7bc21970 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: oauth2-proxy +description: A Helm chart for Kubeflow oauth2-proxy authentication resources +version: 0.1.0 +appVersion: 7.14.3 + +keywords: +- authentication +- oauth2 +- kubeflow +- oauth2-proxy + +home: https://github.com/kubeflow/manifests + +sources: +- https://github.com/kubeflow/manifests/tree/master/common/oauth2-proxy +- https://github.com/oauth2-proxy/oauth2-proxy + +annotations: + category: Authentication + licenses: Apache-2.0 diff --git a/experimental/helm/charts/oauth2-proxy/README.md b/experimental/helm/charts/oauth2-proxy/README.md new file mode 100644 index 0000000000..ac7cf60b52 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/README.md @@ -0,0 +1,46 @@ +# OAuth2-Proxy Helm Chart + +This chart renders the current Kubeflow oauth2-proxy Kustomize resources with +Helm. It is intentionally static for the first chart slice so rendered output +stays aligned with `common/oauth2-proxy`. + +## Install + +Install foundation, cert-manager, and Istio first. Store Helm release metadata +in `kubeflow-system`; oauth2-proxy workloads still run in `oauth2-proxy`. + +```bash +helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ + --namespace kubeflow-system \ + --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml +``` + +For kind-like clusters that use Kubernetes service account JWTs for gateway +machine-to-machine auth, use: + +```bash +helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ + --namespace kubeflow-system \ + --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml +``` + +## Kustomize Mapping + +- `ci/values-base.yaml`: `common/oauth2-proxy/base` +- `ci/values-m2m-dex-only.yaml`: `common/oauth2-proxy/overlays/m2m-dex-only` +- `ci/values-m2m-dex-and-kind.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-kind` +- `ci/values-m2m-dex-and-eks.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-eks` + +Direct enterprise IdP mode, Cloudflare cache policies, and an upstream +oauth2-proxy Helm dependency wrapper are deferred until the parity chart is +stable. + +## Comparison + +```bash +helm lint experimental/helm/charts/oauth2-proxy +./tests/helm_kustomize_compare.sh oauth2-proxy base +./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-only +./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-and-kind +./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-and-eks +``` diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml new file mode 100644 index 0000000000..eab1ac1d6e --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml @@ -0,0 +1,8 @@ +istioExternalAuth: + enabled: false + +m2m: + enabled: false + +clusterJwksProxy: + enabled: false diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml new file mode 100644 index 0000000000..75fc9bc427 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml @@ -0,0 +1,12 @@ +istioExternalAuth: + enabled: true + +m2m: + enabled: true + issuer: https://oidc.eks.AWS_REGION.amazonaws.com/id/CLUSTER_ID + +clusterJwksProxy: + enabled: false + +parameters: + forceHttps: "true" diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml new file mode 100644 index 0000000000..2f1601244e --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml @@ -0,0 +1,16 @@ +istioExternalAuth: + enabled: true + +m2m: + enabled: true + issuer: https://kubernetes.default.svc.cluster.local + jwksUri: http://cluster-jwks-proxy.istio-system.svc.cluster.local/openid/v1/jwks + additionalJwtRules: + - issuer: https://kubernetes.default.svc + jwksUri: http://cluster-jwks-proxy.istio-system.svc.cluster.local/openid/v1/jwks + +clusterJwksProxy: + enabled: true + +parameters: + allowSelfSignedIssuer: "true" diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml new file mode 100644 index 0000000000..e773e7d593 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml @@ -0,0 +1,11 @@ +istioExternalAuth: + enabled: true + +m2m: + enabled: false + +clusterJwksProxy: + enabled: false + +parameters: + allowSelfSignedIssuer: "true" diff --git a/experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg b/experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg new file mode 100644 index 0000000000..19a3174ae0 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg b/experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg new file mode 100644 index 0000000000..946768aa60 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg @@ -0,0 +1,79 @@ +provider = "oidc" +oidc_issuer_url = "http://dex.auth.svc.cluster.local:5556/dex" +scope = "profile email groups openid" +email_domains = [ "*" ] + +# serve a static HTTP 200 upstream on for authentication success +# we are using oauth2-proxy as an ExtAuthz to "check" each request, not pass it on +upstreams = [ "static://200" ] + +# skip authentication for these paths +skip_auth_routes = [ + "^/dex/", +] + +# requests to paths matching these regex patterns will receive a 401 Unauthorized response +# when not authenticated, instead of being redirected to the login page with a 302, +# this prevents background requests being redirected to the login page, +# and the accumulation of CSRF cookies +api_routes = [ + # Generic + # NOTE: included because most background requests contain these paths + "/api/", + "/apis/", + + # Kubeflow Pipelines + # NOTE: included because KFP UI makes MANY background requests to these paths but because they are + # not `application/json` requests, oauth2-proxy will redirect them to the login page + "^/ml_metadata", +] + +# OIDC Discovery has to be skipped and login url has to be provided directly +# in order to enable relative auth redirect. Using OIDC Discovery would set +# the redirect location to http://dex.auth.svc.cluster.local:5556 in the example +# installation. This address is usually not available through the Web Browser. +# If you have a setup where dex has it's url as other than the in-cluster +# service, this is optional. +skip_oidc_discovery = true +login_url = "/dex/auth" +redeem_url = "http://dex.auth.svc.cluster.local:5556/dex/token" +oidc_jwks_url = "http://dex.auth.svc.cluster.local:5556/dex/keys" + +# if `false`, a sign-in page is displayed before starting the login flow +# prevents background requests starting their own login flow on token expiry, +# which can lead to many CSRF cookies, potentially exceeding the cookie limit +skip_provider_button = false + +# style the sign-in page +provider_display_name = "Dex" +custom_sign_in_logo = "/custom-theme/kubeflow-logo.svg" +banner = "-" +footer = "-" + +# oauth2-proxy sends "force" by default, which causes dex to always prompt for login +# https://github.com/dexidp/dex/pull/3086 +prompt = "none" + +# set Authorization Bearer response header. This is needed in order to +# forward the Authorization Bearer token to Istio and enable authorization +# based on JWT. +set_authorization_header = true + +# set X-Auth-Request-User, X-Auth-Request-Groups, X-Auth-Request-Email and +# X-Auth-Request-Preferred-Username. This is optional for Kubeflow but you +# may have other services that use standard auth headers. +set_xauthrequest = true + +cookie_name = "oauth2_proxy_kubeflow" + +# Dex default cookie expiration is 24h. +# If set to 168h (default oauth2-proxy), Istio will not be able to use the JWT after 24h, +# but oauth2-proxy will still consider the cookie valid. +# It's possible to configure the JWT Refresh Token to enable longer login session. +cookie_expire = "24h" +cookie_refresh = 0 + +code_challenge_method = "S256" + +redirect_url = "/oauth2/callback" +relative_redirect_url = true \ No newline at end of file diff --git a/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl b/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl new file mode 100644 index 0000000000..89d776cc0d --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl @@ -0,0 +1,39 @@ +{{/* +oauth2-proxy workload namespace. +*/}} +{{- define "oauth2-proxy.namespace" -}} +{{- .Values.global.oauth2ProxyNamespace -}} +{{- end -}} + +{{/* +Istio namespace. +*/}} +{{- define "oauth2-proxy.istioNamespace" -}} +{{- .Values.global.istioNamespace -}} +{{- end -}} + +{{/* +Kubeflow namespace. +*/}} +{{- define "oauth2-proxy.kubeflowNamespace" -}} +{{- .Values.global.kubeflowNamespace -}} +{{- end -}} + +{{/* +Render a JWT rule for Istio RequestAuthentication. +*/}} +{{- define "oauth2-proxy.m2mJwtRule" -}} +- forwardOriginalToken: true + fromHeaders: + - name: Authorization + prefix: "Bearer " + issuer: {{ .issuer }} +{{- if .jwksUri }} + jwksUri: {{ .jwksUri }} +{{- end }} + outputClaimToHeaders: + - claim: sub + header: kubeflow-userid + - claim: groups + header: kubeflow-groups +{{- end -}} diff --git a/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml b/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml new file mode 100644 index 0000000000..86e3782d69 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml @@ -0,0 +1,85 @@ +{{- if .Values.clusterJwksProxy.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/name: cluster-jwks-proxy + name: cluster-jwks-proxy + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/name: cluster-jwks-proxy + name: cluster-jwks-proxy + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + ports: + - name: http + port: 80 + targetPort: http + selector: + app.kubernetes.io/name: cluster-jwks-proxy +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/name: cluster-jwks-proxy + name: cluster-jwks-proxy + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: cluster-jwks-proxy + template: + metadata: + labels: + app.kubernetes.io/name: cluster-jwks-proxy + spec: + containers: + - args: + - proxy + - --address=0.0.0.0 + - --port=8080 + - --accept-hosts=.* + - --accept-paths=^(?:/openid/v1/jwks)|(?:/.well-known/openid-configuration)$ + - --reject-methods=^(POST|PUT|PATCH|DELETE|HEAD|OPTIONS|CONNECT|TRACE)$ + image: {{ .Values.clusterJwksProxy.image }} + livenessProbe: + httpGet: + path: /openid/v1/jwks + port: http + initialDelaySeconds: 15 + periodSeconds: 15 + timeoutSeconds: 5 + name: kubectl-proxy + ports: + - containerPort: 8080 + name: http + readinessProbe: + httpGet: + path: /openid/v1/jwks + port: http + initialDelaySeconds: 15 + periodSeconds: 15 + timeoutSeconds: 5 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + startupProbe: + httpGet: + path: /openid/v1/jwks + port: http + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 2 + serviceAccountName: cluster-jwks-proxy +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml b/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml new file mode 100644 index 0000000000..d8619a6df4 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml @@ -0,0 +1,68 @@ +{{- if .Values.istioExternalAuth.enabled }} +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: istio-ingressgateway-oauth2-proxy + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + action: CUSTOM + provider: + name: oauth2-proxy + rules: + - to: + - operation: + notPaths: + - /dex/* + - /dex/** + - /oauth2/* + when: + - key: request.headers[authorization] + notValues: + - '*' + selector: + matchLabels: + app: istio-ingressgateway +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: istio-ingressgateway-require-jwt + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + action: DENY + rules: + - from: + - source: + notRequestPrincipals: + - '*' + to: + - operation: + notPaths: + - /dex/* + - /dex/** + - /oauth2/* + selector: + matchLabels: + app: istio-ingressgateway +--- +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: dex-jwt + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + jwtRules: + - forwardOriginalToken: true + fromHeaders: + - name: Authorization + prefix: 'Bearer ' + issuer: http://dex.auth.svc.cluster.local:5556/dex + outputClaimToHeaders: + - claim: email + header: kubeflow-userid + - claim: groups + header: kubeflow-groups + selector: + matchLabels: + app: istio-ingressgateway +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml b/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml new file mode 100644 index 0000000000..85f6a55e10 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml @@ -0,0 +1,16 @@ +{{- if .Values.m2m.enabled }} +apiVersion: security.istio.io/v1beta1 +kind: RequestAuthentication +metadata: + name: m2m-token-issuer + namespace: {{ include "oauth2-proxy.istioNamespace" . }} +spec: + jwtRules: +{{ include "oauth2-proxy.m2mJwtRule" (dict "issuer" .Values.m2m.issuer "jwksUri" .Values.m2m.jwksUri) | nindent 2 }} +{{- range .Values.m2m.additionalJwtRules }} +{{ include "oauth2-proxy.m2mJwtRule" (dict "issuer" .issuer "jwksUri" .jwksUri) | nindent 2 }} +{{- end }} + selector: + matchLabels: + app: istio-ingressgateway +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml b/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml new file mode 100644 index 0000000000..b9dcfeb1a0 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml @@ -0,0 +1,8 @@ +{{- if .Values.namespace.enabled }} +apiVersion: v1 +kind: Namespace +metadata: + labels: + pod-security.kubernetes.io/enforce: restricted + name: {{ include "oauth2-proxy.namespace" . }} +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml b/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml new file mode 100644 index 0000000000..708f2cdf0e --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml @@ -0,0 +1,40 @@ +{{- if .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-istio-ingressgateway + namespace: {{ include "oauth2-proxy.namespace" . }} +spec: + ingress: + - from: + - namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + - {{ include "oauth2-proxy.istioNamespace" . }} + podSelector: + matchLabels: + app: istio-ingressgateway + podSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - oauth2-proxy + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-allow-same-namespace-oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +spec: + ingress: + - from: + - podSelector: {} + podSelector: {} + policyTypes: + - Ingress +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml new file mode 100644 index 0000000000..43a7e018fc --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml @@ -0,0 +1,184 @@ +{{- if .Values.oauth2Proxy.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +--- +apiVersion: v1 +data: + oauth2_proxy.cfg: |- +{{ .Files.Get "files/oauth2_proxy.cfg" | indent 4 }} +kind: ConfigMap +metadata: + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +--- +apiVersion: v1 +data: + ALLOW_SELF_SIGNED_ISSUER: {{ .Values.parameters.allowSelfSignedIssuer | quote }} + ENABLE_M2M_TOKENS: {{ .Values.parameters.enableM2MTokens | quote }} + EXTRA_JWT_ISSUERS: {{ .Values.parameters.extraJwtIssuers | quote }} + FORCE_HTTPS: {{ .Values.parameters.forceHttps | quote }} +kind: ConfigMap +metadata: + name: oauth2-proxy-parameters + namespace: {{ include "oauth2-proxy.namespace" . }} +--- +apiVersion: v1 +data: + kubeflow-logo.svg: | +{{ .Files.Get "files/kubeflow-logo.svg" | indent 4 }} +kind: ConfigMap +metadata: + name: oauth2-proxy-theme + namespace: {{ include "oauth2-proxy.namespace" . }} +--- +apiVersion: v1 +data: + client-id: {{ .Values.credentials.clientID | b64enc }} + client-secret: {{ .Values.credentials.clientSecret | b64enc }} + cookie-secret: {{ .Values.credentials.cookieSecret | b64enc }} +kind: Secret +metadata: + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +type: Opaque +--- +apiVersion: v1 +kind: Service +metadata: + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +spec: + ports: + - name: http + port: 80 + targetPort: http + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: oauth2-proxy + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: oauth2-proxy + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +spec: + replicas: 2 + selector: + matchLabels: + app.kubernetes.io/name: oauth2-proxy + template: + metadata: + labels: + app.kubernetes.io/name: oauth2-proxy + spec: + containers: + - args: + - --http-address=0.0.0.0:4180 + - --config=/etc/oauth2_proxy/oauth2_proxy.cfg + env: + - name: OAUTH2_PROXY_CLIENT_ID + valueFrom: + secretKeyRef: + key: client-id + name: oauth2-proxy + - name: OAUTH2_PROXY_CLIENT_SECRET + valueFrom: + secretKeyRef: + key: client-secret + name: oauth2-proxy + - name: OAUTH2_PROXY_COOKIE_SECRET + valueFrom: + secretKeyRef: + key: cookie-secret + name: oauth2-proxy + - name: OAUTH2_PROXY_COOKIE_SECURE + valueFrom: + configMapKeyRef: + key: FORCE_HTTPS + name: oauth2-proxy-parameters + - name: OAUTH2_PROXY_SSL_INSECURE_SKIP_VERIFY + valueFrom: + configMapKeyRef: + key: ALLOW_SELF_SIGNED_ISSUER + name: oauth2-proxy-parameters + - name: OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS + valueFrom: + configMapKeyRef: + key: ENABLE_M2M_TOKENS + name: oauth2-proxy-parameters + - name: OAUTH2_PROXY_EXTRA_JWT_ISSUERS + valueFrom: + configMapKeyRef: + key: EXTRA_JWT_ISSUERS + name: oauth2-proxy-parameters + image: quay.io/oauth2-proxy/oauth2-proxy:v7.14.3 + livenessProbe: + httpGet: + path: /ping + port: http + scheme: HTTP + name: oauth2-proxy + ports: + - containerPort: 4180 + name: http + protocol: TCP + - containerPort: 44180 + name: metrics + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: http + scheme: HTTP + resources: {} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + volumeMounts: + - mountPath: /etc/oauth2_proxy/oauth2_proxy.cfg + name: oauth2-proxy-config + readOnly: true + subPath: oauth2_proxy.cfg + - mountPath: /custom-theme/kubeflow-logo.svg + name: oauth2-proxy-theme + readOnly: true + subPath: kubeflow-logo.svg + volumes: + - configMap: + name: oauth2-proxy + name: oauth2-proxy-config + - configMap: + name: oauth2-proxy-theme + name: oauth2-proxy-theme +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: oauth2-proxy + namespace: {{ include "oauth2-proxy.namespace" . }} +spec: + gateways: + - {{ include "oauth2-proxy.kubeflowNamespace" . }}/kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: /oauth2/ + route: + - destination: + host: oauth2-proxy.{{ include "oauth2-proxy.namespace" . }}.svc.cluster.local + port: + number: 80 +{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/values.yaml b/experimental/helm/charts/oauth2-proxy/values.yaml new file mode 100644 index 0000000000..c524ef3366 --- /dev/null +++ b/experimental/helm/charts/oauth2-proxy/values.yaml @@ -0,0 +1,58 @@ +# Default values for the Kubeflow oauth2-proxy chart. + +global: + # -- Namespace for oauth2-proxy workloads. + oauth2ProxyNamespace: oauth2-proxy + # -- Namespace for Istio ingress gateway and auth resources. + istioNamespace: istio-system + # -- Namespace containing the Kubeflow gateway. + kubeflowNamespace: kubeflow + +credentials: + # -- OAuth client ID used by oauth2-proxy. + clientID: kubeflow-oidc-authservice + # -- OAuth client secret used by oauth2-proxy. + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + # -- Cookie secret used by oauth2-proxy. + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + +parameters: + # -- Configure oauth2-proxy cookie secure behavior. + forceHttps: "false" + # -- Allow self-signed issuer certificates. + allowSelfSignedIssuer: "true" + # -- Allow machine-to-machine bearer tokens. + enableM2MTokens: "true" + # -- Extra JWT issuers in oauth2-proxy --extra-jwt-issuers format. + extraJwtIssuers: "" + +namespace: + # -- Render oauth2-proxy workload namespace. + enabled: true + +oauth2Proxy: + # -- Render oauth2-proxy workload resources. + enabled: true + +networkPolicies: + # -- Render oauth2-proxy namespace NetworkPolicies. + enabled: true + +istioExternalAuth: + # -- Render Istio external auth resources for oauth2-proxy. + enabled: false + +m2m: + # -- Render machine-to-machine RequestAuthentication. + enabled: false + # -- Primary JWT issuer. + issuer: PATCH_ME + # -- Optional JWKS URI for the primary JWT issuer. + jwksUri: "" + # -- Additional JWT rules. + additionalJwtRules: [] + +clusterJwksProxy: + # -- Render the cluster JWKS proxy used by kind-like clusters. + enabled: false + image: docker.io/bitnamisecure/kubectl:latest diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index 035d816526..6f3d25c3e7 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -6,6 +6,10 @@ from typing import Dict, List, Tuple, Any import re +KUSTOMIZE_HASH_SUFFIX = re.compile( + r"-(?=[a-z0-9]{10}$)(?=[a-z0-9]*[0-9])[a-z0-9]{10}$" +) + CERT_MANAGER_KUBEFLOW_RESOURCES = { ("ClusterIssuer", "kubeflow-self-signing-issuer"), ("NetworkPolicy", "cert-manager-webhook"), @@ -119,11 +123,11 @@ def normalize_kustomize_refs(obj: Any, path: str = "") -> Any: "volumes", ] ): - value = re.sub(r"-[a-z0-9]{10}$", "", value) + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) elif "volumes" in path and key == "secretName": - value = re.sub(r"-[a-z0-9]{10}$", "", value) + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) elif "volumes" in path and "configMap" in path: - value = re.sub(r"-[a-z0-9]{10}$", "", value) + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) normalized[key] = normalize_kustomize_refs(value, current_path) return normalized @@ -170,7 +174,7 @@ def normalize_manifest(manifest: Dict, component: str = "katib") -> Dict: kind = normalized.get("kind", "") if kind in ["Secret", "ConfigMap"]: name = normalized["metadata"]["name"] - normalized["metadata"]["name"] = re.sub(r"-[a-z0-9]{10}$", "", name) + normalized["metadata"]["name"] = KUSTOMIZE_HASH_SUFFIX.sub("", name) if "metadata" in normalized: metadata = normalized["metadata"] @@ -242,10 +246,10 @@ def get_resource_key(manifest: Dict, component: str = "katib") -> str: namespace = manifest.get("metadata", {}).get("namespace", "") if kind in ["Secret", "ConfigMap"]: - name = re.sub(r"-[a-z0-9]{10}$", "", name) + name = KUSTOMIZE_HASH_SUFFIX.sub("", name) # Include namespace in key for components with same-named namespaced resources. - if component in ["katib", "cert-manager", "kubeflow-namespaces"] and namespace: + if component in ["katib", "cert-manager", "kubeflow-namespaces", "oauth2-proxy"] and namespace: return f"{kind}/{namespace}/{name}" else: return f"{kind}/{name}" @@ -297,6 +301,8 @@ def get_expected_helm_extras(component: str, scenario: str) -> set: return set() # No extra resources in Helm for Model Registry elif component == "kserve-models-web-application": return set() + elif component == "oauth2-proxy": + return set() else: return set() @@ -377,7 +383,7 @@ def compare_manifests( "Usage: python compare.py [namespace] [--verbose]" ) print( - "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform" + "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) @@ -396,10 +402,11 @@ def compare_manifests( "cert-manager", "kubeflow-namespaces", "kubeflow-platform", + "oauth2-proxy", ]: print(f"ERROR: Unknown component: {component}") print( - "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform" + "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) diff --git a/tests/helm_kustomize_compare.sh b/tests/helm_kustomize_compare.sh index 44406e1385..3c1ca4accc 100755 --- a/tests/helm_kustomize_compare.sh +++ b/tests/helm_kustomize_compare.sh @@ -11,7 +11,7 @@ ROOT_DIRECTORY="$(dirname "$SCRIPT_DIRECTORY")" if [[ -z "$COMPONENT" ]]; then echo "ERROR: Component is required" echo "Usage: $0 " - echo "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform" + echo "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" exit 1 fi @@ -199,9 +199,35 @@ case "$COMPONENT" in ) ;; + "oauth2-proxy") + CHART_DIRECTORY="$ROOT_DIRECTORY/experimental/helm/charts/oauth2-proxy" + MANIFESTS_DIRECTORY="$ROOT_DIRECTORY/common/oauth2-proxy" + + declare -A KUSTOMIZE_PATHS=( + ["base"]="$MANIFESTS_DIRECTORY/base" + ["m2m-dex-only"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-only" + ["m2m-dex-and-kind"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-and-kind" + ["m2m-dex-and-eks"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-and-eks" + ) + + declare -A HELM_VALUES=( + ["base"]="$CHART_DIRECTORY/ci/values-base.yaml" + ["m2m-dex-only"]="$CHART_DIRECTORY/ci/values-m2m-dex-only.yaml" + ["m2m-dex-and-kind"]="$CHART_DIRECTORY/ci/values-m2m-dex-and-kind.yaml" + ["m2m-dex-and-eks"]="$CHART_DIRECTORY/ci/values-m2m-dex-and-eks.yaml" + ) + + declare -A NAMESPACES=( + ["base"]="kubeflow-system" + ["m2m-dex-only"]="kubeflow-system" + ["m2m-dex-and-kind"]="kubeflow-system" + ["m2m-dex-and-eks"]="kubeflow-system" + ) + ;; + *) echo "ERROR: Unknown component: $COMPONENT" - echo "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform" + echo "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" exit 1 ;; esac @@ -291,6 +317,11 @@ else --namespace "$NAMESPACE" \ --include-crds \ --values "$HELM_VALUES_ARGUMENTS" > "$HELM_OUTPUT" + elif [[ "$COMPONENT" == "oauth2-proxy" ]]; then + helm template oauth2-proxy . \ + --namespace "$NAMESPACE" \ + --include-crds \ + --values "$HELM_VALUES_ARGUMENTS" > "$HELM_OUTPUT" else helm template hub . \ --namespace "$NAMESPACE" \ diff --git a/tests/helm_kustomize_compare_all.sh b/tests/helm_kustomize_compare_all.sh index d886baf348..dd310a8084 100755 --- a/tests/helm_kustomize_compare_all.sh +++ b/tests/helm_kustomize_compare_all.sh @@ -15,6 +15,7 @@ declare -A COMPONENT_SCENARIOS=( ["cert-manager"]="base kubeflow existing-cert-manager" ["kubeflow-namespaces"]="base platform-namespaces" ["kubeflow-platform"]="base" + ["oauth2-proxy"]="base m2m-dex-only m2m-dex-and-kind m2m-dex-and-eks" ) prepare_component() { @@ -63,7 +64,7 @@ if [[ "$COMPONENT" == "all" ]]; then declare -a passed_components=() declare -a failed_components=() - for component in katib hub kserve-models-web-application cert-manager kubeflow-namespaces kubeflow-platform; do + for component in katib hub kserve-models-web-application cert-manager kubeflow-namespaces kubeflow-platform oauth2-proxy; do if test_component "$component"; then passed_components+=("$component") else @@ -94,6 +95,7 @@ elif [[ "$COMPONENT" == "help" ]] || [[ "$COMPONENT" == "--help" ]] || [[ "$COMP echo " cert-manager Test cert-manager wrapper scenarios" echo " kubeflow-namespaces Test Kubeflow namespace foundation chart" echo " kubeflow-platform Test Kubeflow platform foundation chart" + echo " oauth2-proxy Test oauth2-proxy wrapper scenarios" echo "" echo "Examples:" echo " $0 # Test all components" @@ -113,7 +115,7 @@ elif [[ "${COMPONENT_SCENARIOS[$COMPONENT]:-}" ]]; then else echo "ERROR: Unknown component: $COMPONENT" - echo "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, all" + echo "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy, all" echo "Use '$0 help' for more information." exit 1 fi From b897278e7154104e1f2427216c4c0257d448ad44 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Mon, 25 May 2026 21:19:32 +0530 Subject: [PATCH 02/19] helm: address oauth2-proxy review comments Signed-off-by: danish9039 --- experimental/helm/charts/oauth2-proxy/ci/values-base.yaml | 4 ++++ .../helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml | 4 ++++ .../charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml | 5 +++++ .../helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml | 4 ++++ experimental/helm/charts/oauth2-proxy/values.yaml | 6 +++--- 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml index eab1ac1d6e..788165cf09 100644 --- a/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml +++ b/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml @@ -1,3 +1,7 @@ +credentials: + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + istioExternalAuth: enabled: false diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml index 75fc9bc427..50b0c55904 100644 --- a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml @@ -1,3 +1,7 @@ +credentials: + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + istioExternalAuth: enabled: true diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml index 2f1601244e..8f8199b55a 100644 --- a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml @@ -1,3 +1,7 @@ +credentials: + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + istioExternalAuth: enabled: true @@ -11,6 +15,7 @@ m2m: clusterJwksProxy: enabled: true + image: docker.io/bitnamisecure/kubectl:latest parameters: allowSelfSignedIssuer: "true" diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml index e773e7d593..862f19d2ac 100644 --- a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml +++ b/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml @@ -1,3 +1,7 @@ +credentials: + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + istioExternalAuth: enabled: true diff --git a/experimental/helm/charts/oauth2-proxy/values.yaml b/experimental/helm/charts/oauth2-proxy/values.yaml index c524ef3366..cc9fb41810 100644 --- a/experimental/helm/charts/oauth2-proxy/values.yaml +++ b/experimental/helm/charts/oauth2-proxy/values.yaml @@ -12,9 +12,9 @@ credentials: # -- OAuth client ID used by oauth2-proxy. clientID: kubeflow-oidc-authservice # -- OAuth client secret used by oauth2-proxy. - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + clientSecret: REPLACE_ME_CLIENT_SECRET # -- Cookie secret used by oauth2-proxy. - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + cookieSecret: REPLACE_ME_COOKIE_SECRET parameters: # -- Configure oauth2-proxy cookie secure behavior. @@ -55,4 +55,4 @@ m2m: clusterJwksProxy: # -- Render the cluster JWKS proxy used by kind-like clusters. enabled: false - image: docker.io/bitnamisecure/kubectl:latest + image: "" From 1875ec53c7a615da5b1f6c0864980e3f9c29d180 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Wed, 27 May 2026 01:22:07 +0530 Subject: [PATCH 03/19] helm: align oauth2-proxy wrapper with v7.15.2 Signed-off-by: danish9039 --- experimental/helm/charts/oauth2-proxy/Chart.yaml | 2 +- .../helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/experimental/helm/charts/oauth2-proxy/Chart.yaml b/experimental/helm/charts/oauth2-proxy/Chart.yaml index 7e7bc21970..f82ba5a4ff 100644 --- a/experimental/helm/charts/oauth2-proxy/Chart.yaml +++ b/experimental/helm/charts/oauth2-proxy/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: oauth2-proxy description: A Helm chart for Kubeflow oauth2-proxy authentication resources version: 0.1.0 -appVersion: 7.14.3 +appVersion: 7.15.2 keywords: - authentication diff --git a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml index 43a7e018fc..41dc5252dd 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml @@ -117,7 +117,7 @@ spec: configMapKeyRef: key: EXTRA_JWT_ISSUERS name: oauth2-proxy-parameters - image: quay.io/oauth2-proxy/oauth2-proxy:v7.14.3 + image: quay.io/oauth2-proxy/oauth2-proxy:v7.15.2 livenessProbe: httpGet: path: /ping From 8a30b3ec8895f1453830eff29a7463dbc9f14899 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sun, 7 Jun 2026 23:07:12 +0530 Subject: [PATCH 04/19] helm: use foundation-owned oauth2-proxy namespace Signed-off-by: danish9039 --- experimental/helm/charts/oauth2-proxy/README.md | 9 +++++---- .../helm/charts/oauth2-proxy/templates/namespace.yaml | 8 -------- experimental/helm/charts/oauth2-proxy/values.yaml | 4 ---- tests/helm_kustomize_compare.py | 4 +--- tests/helm_kustomize_compare.sh | 8 ++++---- 5 files changed, 10 insertions(+), 23 deletions(-) delete mode 100644 experimental/helm/charts/oauth2-proxy/templates/namespace.yaml diff --git a/experimental/helm/charts/oauth2-proxy/README.md b/experimental/helm/charts/oauth2-proxy/README.md index ac7cf60b52..7a7ca3c96d 100644 --- a/experimental/helm/charts/oauth2-proxy/README.md +++ b/experimental/helm/charts/oauth2-proxy/README.md @@ -6,12 +6,13 @@ stays aligned with `common/oauth2-proxy`. ## Install -Install foundation, cert-manager, and Istio first. Store Helm release metadata -in `kubeflow-system`; oauth2-proxy workloads still run in `oauth2-proxy`. +Install foundation, cert-manager, and Istio first. The `kubeflow-namespaces` +foundation chart creates `Namespace/oauth2-proxy`; this chart stores Helm +release metadata in that same workload namespace. ```bash helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ - --namespace kubeflow-system \ + --namespace oauth2-proxy \ --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml ``` @@ -20,7 +21,7 @@ machine-to-machine auth, use: ```bash helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ - --namespace kubeflow-system \ + --namespace oauth2-proxy \ --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml ``` diff --git a/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml b/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml deleted file mode 100644 index b9dcfeb1a0..0000000000 --- a/experimental/helm/charts/oauth2-proxy/templates/namespace.yaml +++ /dev/null @@ -1,8 +0,0 @@ -{{- if .Values.namespace.enabled }} -apiVersion: v1 -kind: Namespace -metadata: - labels: - pod-security.kubernetes.io/enforce: restricted - name: {{ include "oauth2-proxy.namespace" . }} -{{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/values.yaml b/experimental/helm/charts/oauth2-proxy/values.yaml index cc9fb41810..6b4fe4bd0a 100644 --- a/experimental/helm/charts/oauth2-proxy/values.yaml +++ b/experimental/helm/charts/oauth2-proxy/values.yaml @@ -26,10 +26,6 @@ parameters: # -- Extra JWT issuers in oauth2-proxy --extra-jwt-issuers format. extraJwtIssuers: "" -namespace: - # -- Render oauth2-proxy workload namespace. - enabled: true - oauth2Proxy: # -- Render oauth2-proxy workload resources. enabled: true diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index 6f3d25c3e7..2512f0cf32 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -201,7 +201,6 @@ def remove_empty_values(obj): return remove_empty_values(normalized) - def preserve_cert_manager_kubeflow_labels(original: Dict, normalized: Dict) -> None: """Keep labels that are intentionally added by cert-manager's Kubeflow overlay.""" kind = original.get("kind", "") @@ -227,7 +226,7 @@ def should_compare_manifest(manifest: Dict, component: str, scenario: str) -> bo """Select the resource subset owned by a comparison scenario.""" kind = manifest.get("kind", "") - if component == "cert-manager" and manifest.get("kind") == "Namespace": + if component in ["cert-manager", "oauth2-proxy"] and kind == "Namespace": return False if component == "kubeflow-namespaces" and scenario == "base": @@ -238,7 +237,6 @@ def should_compare_manifest(manifest: Dict, component: str, scenario: str) -> bo return True - def get_resource_key(manifest: Dict, component: str = "katib") -> str: """Generate a unique key for the resource.""" kind = manifest.get("kind", "Unknown") diff --git a/tests/helm_kustomize_compare.sh b/tests/helm_kustomize_compare.sh index 3c1ca4accc..e6246251d0 100755 --- a/tests/helm_kustomize_compare.sh +++ b/tests/helm_kustomize_compare.sh @@ -218,10 +218,10 @@ case "$COMPONENT" in ) declare -A NAMESPACES=( - ["base"]="kubeflow-system" - ["m2m-dex-only"]="kubeflow-system" - ["m2m-dex-and-kind"]="kubeflow-system" - ["m2m-dex-and-eks"]="kubeflow-system" + ["base"]="oauth2-proxy" + ["m2m-dex-only"]="oauth2-proxy" + ["m2m-dex-and-kind"]="oauth2-proxy" + ["m2m-dex-and-eks"]="oauth2-proxy" ) ;; From d19f4bd48c7a50e67340c7b0552d51addfdd2638 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Tue, 9 Jun 2026 17:00:21 +0530 Subject: [PATCH 05/19] helm: fix oauth2-proxy namespace names Signed-off-by: danish9039 --- .../helm/charts/oauth2-proxy/README.md | 4 ++++ .../oauth2-proxy/templates/_helpers.tpl | 21 ------------------- .../templates/cluster-jwks-proxy.yaml | 6 +++--- .../templates/istio-external-auth.yaml | 6 +++--- .../charts/oauth2-proxy/templates/m2m.yaml | 2 +- .../templates/networkpolicies.yaml | 6 +++--- .../oauth2-proxy/templates/oauth2-proxy.yaml | 20 +++++++++--------- .../helm/charts/oauth2-proxy/values.yaml | 8 ------- 8 files changed, 24 insertions(+), 49 deletions(-) diff --git a/experimental/helm/charts/oauth2-proxy/README.md b/experimental/helm/charts/oauth2-proxy/README.md index 7a7ca3c96d..03a8f43783 100644 --- a/experimental/helm/charts/oauth2-proxy/README.md +++ b/experimental/helm/charts/oauth2-proxy/README.md @@ -10,6 +10,10 @@ Install foundation, cert-manager, and Istio first. The `kubeflow-namespaces` foundation chart creates `Namespace/oauth2-proxy`; this chart stores Helm release metadata in that same workload namespace. +## Namespace names + +Namespace names are fixed to match the Kustomize baseline and `kubeflow-namespaces` foundation chart. oauth2-proxy workloads use `oauth2-proxy`, Istio auth resources use `istio-system`, and gateway references use `kubeflow`. These names are not configurable. + ```bash helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ --namespace oauth2-proxy \ diff --git a/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl b/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl index 89d776cc0d..16ac5a6415 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl +++ b/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl @@ -1,24 +1,3 @@ -{{/* -oauth2-proxy workload namespace. -*/}} -{{- define "oauth2-proxy.namespace" -}} -{{- .Values.global.oauth2ProxyNamespace -}} -{{- end -}} - -{{/* -Istio namespace. -*/}} -{{- define "oauth2-proxy.istioNamespace" -}} -{{- .Values.global.istioNamespace -}} -{{- end -}} - -{{/* -Kubeflow namespace. -*/}} -{{- define "oauth2-proxy.kubeflowNamespace" -}} -{{- .Values.global.kubeflowNamespace -}} -{{- end -}} - {{/* Render a JWT rule for Istio RequestAuthentication. */}} diff --git a/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml b/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml index 86e3782d69..6fe934dfd2 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml @@ -5,7 +5,7 @@ metadata: labels: app.kubernetes.io/name: cluster-jwks-proxy name: cluster-jwks-proxy - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system --- apiVersion: v1 kind: Service @@ -13,7 +13,7 @@ metadata: labels: app.kubernetes.io/name: cluster-jwks-proxy name: cluster-jwks-proxy - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: ports: - name: http @@ -28,7 +28,7 @@ metadata: labels: app.kubernetes.io/name: cluster-jwks-proxy name: cluster-jwks-proxy - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: replicas: 1 selector: diff --git a/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml b/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml index d8619a6df4..6054650164 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml @@ -3,7 +3,7 @@ apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: istio-ingressgateway-oauth2-proxy - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: action: CUSTOM provider: @@ -27,7 +27,7 @@ apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: istio-ingressgateway-require-jwt - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: action: DENY rules: @@ -49,7 +49,7 @@ apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: dex-jwt - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: jwtRules: - forwardOriginalToken: true diff --git a/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml b/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml index 85f6a55e10..28f1791024 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml @@ -3,7 +3,7 @@ apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: m2m-token-issuer - namespace: {{ include "oauth2-proxy.istioNamespace" . }} + namespace: istio-system spec: jwtRules: {{ include "oauth2-proxy.m2mJwtRule" (dict "issuer" .Values.m2m.issuer "jwksUri" .Values.m2m.jwksUri) | nindent 2 }} diff --git a/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml b/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml index 708f2cdf0e..2ed13cbd39 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml @@ -3,7 +3,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-istio-ingressgateway - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy spec: ingress: - from: @@ -12,7 +12,7 @@ spec: - key: kubernetes.io/metadata.name operator: In values: - - {{ include "oauth2-proxy.istioNamespace" . }} + - istio-system podSelector: matchLabels: app: istio-ingressgateway @@ -29,7 +29,7 @@ apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-allow-same-namespace-oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy spec: ingress: - from: diff --git a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml index 41dc5252dd..42abfeaf85 100644 --- a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml +++ b/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml @@ -3,7 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy --- apiVersion: v1 data: @@ -12,7 +12,7 @@ data: kind: ConfigMap metadata: name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy --- apiVersion: v1 data: @@ -23,7 +23,7 @@ data: kind: ConfigMap metadata: name: oauth2-proxy-parameters - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy --- apiVersion: v1 data: @@ -32,7 +32,7 @@ data: kind: ConfigMap metadata: name: oauth2-proxy-theme - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy --- apiVersion: v1 data: @@ -42,14 +42,14 @@ data: kind: Secret metadata: name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy type: Opaque --- apiVersion: v1 kind: Service metadata: name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy spec: ports: - name: http @@ -66,7 +66,7 @@ metadata: labels: app: oauth2-proxy name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy spec: replicas: 2 selector: @@ -166,10 +166,10 @@ apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: oauth2-proxy - namespace: {{ include "oauth2-proxy.namespace" . }} + namespace: oauth2-proxy spec: gateways: - - {{ include "oauth2-proxy.kubeflowNamespace" . }}/kubeflow-gateway + - kubeflow/kubeflow-gateway hosts: - '*' http: @@ -178,7 +178,7 @@ spec: prefix: /oauth2/ route: - destination: - host: oauth2-proxy.{{ include "oauth2-proxy.namespace" . }}.svc.cluster.local + host: oauth2-proxy.oauth2-proxy.svc.cluster.local port: number: 80 {{- end }} diff --git a/experimental/helm/charts/oauth2-proxy/values.yaml b/experimental/helm/charts/oauth2-proxy/values.yaml index 6b4fe4bd0a..ed5f048bc9 100644 --- a/experimental/helm/charts/oauth2-proxy/values.yaml +++ b/experimental/helm/charts/oauth2-proxy/values.yaml @@ -1,13 +1,5 @@ # Default values for the Kubeflow oauth2-proxy chart. -global: - # -- Namespace for oauth2-proxy workloads. - oauth2ProxyNamespace: oauth2-proxy - # -- Namespace for Istio ingress gateway and auth resources. - istioNamespace: istio-system - # -- Namespace containing the Kubeflow gateway. - kubeflowNamespace: kubeflow - credentials: # -- OAuth client ID used by oauth2-proxy. clientID: kubeflow-oidc-authservice From 77159f3e1ba5fb354833e29fe909d9084a27ee39 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Mon, 15 Jun 2026 09:15:56 +0530 Subject: [PATCH 06/19] helm: move oauth2-proxy chart to common/oauth2-proxy/helm Signed-off-by: danish9039 --- .github/workflows/helm-kustomize-comparison.yml | 1 + .../oauth2-proxy/helm}/Chart.yaml | 0 .../oauth2-proxy/helm}/README.md | 10 +++++----- .../oauth2-proxy/helm}/ci/values-base.yaml | 0 .../oauth2-proxy/helm}/ci/values-m2m-dex-and-eks.yaml | 0 .../oauth2-proxy/helm}/ci/values-m2m-dex-and-kind.yaml | 0 .../oauth2-proxy/helm}/ci/values-m2m-dex-only.yaml | 0 .../oauth2-proxy/helm}/files/kubeflow-logo.svg | 0 .../oauth2-proxy/helm}/files/oauth2_proxy.cfg | 0 .../oauth2-proxy/helm}/templates/_helpers.tpl | 0 .../helm}/templates/cluster-jwks-proxy.yaml | 0 .../helm}/templates/istio-external-auth.yaml | 0 .../oauth2-proxy/helm}/templates/m2m.yaml | 0 .../oauth2-proxy/helm}/templates/networkpolicies.yaml | 0 .../oauth2-proxy/helm}/templates/oauth2-proxy.yaml | 0 .../oauth2-proxy/helm}/values.yaml | 0 tests/helm_kustomize_compare.sh | 2 +- 17 files changed, 7 insertions(+), 6 deletions(-) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/Chart.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/README.md (82%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/ci/values-base.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/ci/values-m2m-dex-and-eks.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/ci/values-m2m-dex-and-kind.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/ci/values-m2m-dex-only.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/files/kubeflow-logo.svg (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/files/oauth2_proxy.cfg (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/_helpers.tpl (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/cluster-jwks-proxy.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/istio-external-auth.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/m2m.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/networkpolicies.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/templates/oauth2-proxy.yaml (100%) rename {experimental/helm/charts/oauth2-proxy => common/oauth2-proxy/helm}/values.yaml (100%) diff --git a/.github/workflows/helm-kustomize-comparison.yml b/.github/workflows/helm-kustomize-comparison.yml index f88bd46959..b79634f2f3 100644 --- a/.github/workflows/helm-kustomize-comparison.yml +++ b/.github/workflows/helm-kustomize-comparison.yml @@ -8,6 +8,7 @@ on: - common/kubeflow-namespace/** - common/kubeflow-roles/** - scripts/synchronize-cert-manager-manifests.sh + - common/oauth2-proxy/helm/** - tests/kustomize_install.sh - tests/helm_kustomize_compare.py - tests/helm_kustomize_compare.sh diff --git a/experimental/helm/charts/oauth2-proxy/Chart.yaml b/common/oauth2-proxy/helm/Chart.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/Chart.yaml rename to common/oauth2-proxy/helm/Chart.yaml diff --git a/experimental/helm/charts/oauth2-proxy/README.md b/common/oauth2-proxy/helm/README.md similarity index 82% rename from experimental/helm/charts/oauth2-proxy/README.md rename to common/oauth2-proxy/helm/README.md index 03a8f43783..46c7a5f483 100644 --- a/experimental/helm/charts/oauth2-proxy/README.md +++ b/common/oauth2-proxy/helm/README.md @@ -15,18 +15,18 @@ release metadata in that same workload namespace. Namespace names are fixed to match the Kustomize baseline and `kubeflow-namespaces` foundation chart. oauth2-proxy workloads use `oauth2-proxy`, Istio auth resources use `istio-system`, and gateway references use `kubeflow`. These names are not configurable. ```bash -helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ +helm install oauth2-proxy ./common/oauth2-proxy/helm \ --namespace oauth2-proxy \ - --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml + --values ./common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml ``` For kind-like clusters that use Kubernetes service account JWTs for gateway machine-to-machine auth, use: ```bash -helm install oauth2-proxy ./experimental/helm/charts/oauth2-proxy \ +helm install oauth2-proxy ./common/oauth2-proxy/helm \ --namespace oauth2-proxy \ - --values ./experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml + --values ./common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml ``` ## Kustomize Mapping @@ -43,7 +43,7 @@ stable. ## Comparison ```bash -helm lint experimental/helm/charts/oauth2-proxy +helm lint common/oauth2-proxy/helm ./tests/helm_kustomize_compare.sh oauth2-proxy base ./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-only ./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-and-kind diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-base.yaml b/common/oauth2-proxy/helm/ci/values-base.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/ci/values-base.yaml rename to common/oauth2-proxy/helm/ci/values-base.yaml diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-eks.yaml rename to common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-and-kind.yaml rename to common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml diff --git a/experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/ci/values-m2m-dex-only.yaml rename to common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml diff --git a/experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg b/common/oauth2-proxy/helm/files/kubeflow-logo.svg similarity index 100% rename from experimental/helm/charts/oauth2-proxy/files/kubeflow-logo.svg rename to common/oauth2-proxy/helm/files/kubeflow-logo.svg diff --git a/experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg b/common/oauth2-proxy/helm/files/oauth2_proxy.cfg similarity index 100% rename from experimental/helm/charts/oauth2-proxy/files/oauth2_proxy.cfg rename to common/oauth2-proxy/helm/files/oauth2_proxy.cfg diff --git a/experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl b/common/oauth2-proxy/helm/templates/_helpers.tpl similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/_helpers.tpl rename to common/oauth2-proxy/helm/templates/_helpers.tpl diff --git a/experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml b/common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/cluster-jwks-proxy.yaml rename to common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml diff --git a/experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml b/common/oauth2-proxy/helm/templates/istio-external-auth.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/istio-external-auth.yaml rename to common/oauth2-proxy/helm/templates/istio-external-auth.yaml diff --git a/experimental/helm/charts/oauth2-proxy/templates/m2m.yaml b/common/oauth2-proxy/helm/templates/m2m.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/m2m.yaml rename to common/oauth2-proxy/helm/templates/m2m.yaml diff --git a/experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml b/common/oauth2-proxy/helm/templates/networkpolicies.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/networkpolicies.yaml rename to common/oauth2-proxy/helm/templates/networkpolicies.yaml diff --git a/experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml b/common/oauth2-proxy/helm/templates/oauth2-proxy.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/templates/oauth2-proxy.yaml rename to common/oauth2-proxy/helm/templates/oauth2-proxy.yaml diff --git a/experimental/helm/charts/oauth2-proxy/values.yaml b/common/oauth2-proxy/helm/values.yaml similarity index 100% rename from experimental/helm/charts/oauth2-proxy/values.yaml rename to common/oauth2-proxy/helm/values.yaml diff --git a/tests/helm_kustomize_compare.sh b/tests/helm_kustomize_compare.sh index e6246251d0..a4ff15daaa 100755 --- a/tests/helm_kustomize_compare.sh +++ b/tests/helm_kustomize_compare.sh @@ -200,7 +200,7 @@ case "$COMPONENT" in ;; "oauth2-proxy") - CHART_DIRECTORY="$ROOT_DIRECTORY/experimental/helm/charts/oauth2-proxy" + CHART_DIRECTORY="$ROOT_DIRECTORY/common/oauth2-proxy/helm" MANIFESTS_DIRECTORY="$ROOT_DIRECTORY/common/oauth2-proxy" declare -A KUSTOMIZE_PATHS=( From 9b50a5ddf9cdf148c1c30c0a3ea5972c9ecce673 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Mon, 15 Jun 2026 10:44:53 +0530 Subject: [PATCH 07/19] test: add oauth2-proxy component to helm_kustomize_compare.sh Signed-off-by: danish9039 --- common/oauth2-proxy/helm/README.md | 4 +--- common/oauth2-proxy/helm/ci/values-istio.yaml | 15 +++++++++++++++ .../overlays/istio/kustomization.yaml | 5 +++++ tests/helm_kustomize_compare.sh | 19 +++++++++---------- tests/helm_kustomize_compare_all.sh | 2 +- 5 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 common/oauth2-proxy/helm/ci/values-istio.yaml create mode 100644 common/oauth2-proxy/overlays/istio/kustomization.yaml diff --git a/common/oauth2-proxy/helm/README.md b/common/oauth2-proxy/helm/README.md index 46c7a5f483..07535da0c0 100644 --- a/common/oauth2-proxy/helm/README.md +++ b/common/oauth2-proxy/helm/README.md @@ -45,7 +45,5 @@ stable. ```bash helm lint common/oauth2-proxy/helm ./tests/helm_kustomize_compare.sh oauth2-proxy base -./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-only -./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-and-kind -./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-and-eks +./tests/helm_kustomize_compare.sh oauth2-proxy overlays-istio ``` diff --git a/common/oauth2-proxy/helm/ci/values-istio.yaml b/common/oauth2-proxy/helm/ci/values-istio.yaml new file mode 100644 index 0000000000..862f19d2ac --- /dev/null +++ b/common/oauth2-proxy/helm/ci/values-istio.yaml @@ -0,0 +1,15 @@ +credentials: + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + +istioExternalAuth: + enabled: true + +m2m: + enabled: false + +clusterJwksProxy: + enabled: false + +parameters: + allowSelfSignedIssuer: "true" diff --git a/common/oauth2-proxy/overlays/istio/kustomization.yaml b/common/oauth2-proxy/overlays/istio/kustomization.yaml new file mode 100644 index 0000000000..ce30d80bbb --- /dev/null +++ b/common/oauth2-proxy/overlays/istio/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../m2m-dex-only diff --git a/tests/helm_kustomize_compare.sh b/tests/helm_kustomize_compare.sh index a4ff15daaa..3a40575694 100755 --- a/tests/helm_kustomize_compare.sh +++ b/tests/helm_kustomize_compare.sh @@ -4,7 +4,7 @@ set -euo pipefail COMPONENT=${1:-""} -SCENARIO=${2:-"base"} +SCENARIO=${2:-""} SCRIPT_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ROOT_DIRECTORY="$(dirname "$SCRIPT_DIRECTORY")" @@ -204,24 +204,15 @@ case "$COMPONENT" in MANIFESTS_DIRECTORY="$ROOT_DIRECTORY/common/oauth2-proxy" declare -A KUSTOMIZE_PATHS=( - ["base"]="$MANIFESTS_DIRECTORY/base" ["m2m-dex-only"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-only" - ["m2m-dex-and-kind"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-and-kind" - ["m2m-dex-and-eks"]="$MANIFESTS_DIRECTORY/overlays/m2m-dex-and-eks" ) declare -A HELM_VALUES=( - ["base"]="$CHART_DIRECTORY/ci/values-base.yaml" ["m2m-dex-only"]="$CHART_DIRECTORY/ci/values-m2m-dex-only.yaml" - ["m2m-dex-and-kind"]="$CHART_DIRECTORY/ci/values-m2m-dex-and-kind.yaml" - ["m2m-dex-and-eks"]="$CHART_DIRECTORY/ci/values-m2m-dex-and-eks.yaml" ) declare -A NAMESPACES=( - ["base"]="oauth2-proxy" ["m2m-dex-only"]="oauth2-proxy" - ["m2m-dex-and-kind"]="oauth2-proxy" - ["m2m-dex-and-eks"]="oauth2-proxy" ) ;; @@ -232,6 +223,14 @@ case "$COMPONENT" in ;; esac +if [[ -z "$SCENARIO" ]]; then + if [[ "$COMPONENT" == "oauth2-proxy" ]]; then + SCENARIO="m2m-dex-only" + else + SCENARIO="base" + fi +fi + if [[ ! "${KUSTOMIZE_PATHS[$SCENARIO]:-}" ]]; then echo "ERROR: Unknown scenario '$SCENARIO' for component '$COMPONENT'" echo "Supported scenarios for $COMPONENT:" diff --git a/tests/helm_kustomize_compare_all.sh b/tests/helm_kustomize_compare_all.sh index dd310a8084..f96f5eb291 100755 --- a/tests/helm_kustomize_compare_all.sh +++ b/tests/helm_kustomize_compare_all.sh @@ -15,7 +15,7 @@ declare -A COMPONENT_SCENARIOS=( ["cert-manager"]="base kubeflow existing-cert-manager" ["kubeflow-namespaces"]="base platform-namespaces" ["kubeflow-platform"]="base" - ["oauth2-proxy"]="base m2m-dex-only m2m-dex-and-kind m2m-dex-and-eks" + ["oauth2-proxy"]="m2m-dex-only" ) prepare_component() { From 33e4f8fdd9f35f37eec61285bacdcd07f2393b79 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Mon, 15 Jun 2026 17:57:05 +0530 Subject: [PATCH 08/19] helm: address oauth2-proxy review comments Signed-off-by: danish9039 --- common/oauth2-proxy/base/deployment.yaml | 1 + common/oauth2-proxy/base/kustomization.yaml | 4 +- common/oauth2-proxy/helm/ci/values-base.yaml | 4 +- common/oauth2-proxy/helm/ci/values-istio.yaml | 4 +- .../helm/ci/values-m2m-dex-and-eks.yaml | 4 +- .../helm/ci/values-m2m-dex-and-kind.yaml | 4 +- .../helm/ci/values-m2m-dex-only.yaml | 4 +- .../helm/templates/cluster-jwks-proxy.yaml | 2 +- .../helm/templates/oauth2-proxy.yaml | 1 + tests/helm_kustomize_compare.py | 225 +++++++----------- 10 files changed, 105 insertions(+), 148 deletions(-) diff --git a/common/oauth2-proxy/base/deployment.yaml b/common/oauth2-proxy/base/deployment.yaml index 0b5b2b2865..72a7c63d42 100644 --- a/common/oauth2-proxy/base/deployment.yaml +++ b/common/oauth2-proxy/base/deployment.yaml @@ -14,6 +14,7 @@ spec: labels: app.kubernetes.io/name: oauth2-proxy spec: + serviceAccountName: oauth2-proxy volumes: - name: oauth2-proxy-config configMap: diff --git a/common/oauth2-proxy/base/kustomization.yaml b/common/oauth2-proxy/base/kustomization.yaml index e4e7f4d335..2ebab332f9 100644 --- a/common/oauth2-proxy/base/kustomization.yaml +++ b/common/oauth2-proxy/base/kustomization.yaml @@ -17,8 +17,8 @@ secretGenerator: type: Opaque literals: - client-id=kubeflow-oidc-authservice - - client-secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - - cookie-secret=7d16fee92f8d11b8940b081b3f8b8acb + - client-secret=not-a-real-client-secret + - cookie-secret=not-a-real-cookie-secret-00000 configMapGenerator: - name: oauth2-proxy diff --git a/common/oauth2-proxy/helm/ci/values-base.yaml b/common/oauth2-proxy/helm/ci/values-base.yaml index 788165cf09..1b59d051d1 100644 --- a/common/oauth2-proxy/helm/ci/values-base.yaml +++ b/common/oauth2-proxy/helm/ci/values-base.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + clientSecret: not-a-real-client-secret + cookieSecret: not-a-real-cookie-secret-00000 istioExternalAuth: enabled: false diff --git a/common/oauth2-proxy/helm/ci/values-istio.yaml b/common/oauth2-proxy/helm/ci/values-istio.yaml index 862f19d2ac..7f1d580d14 100644 --- a/common/oauth2-proxy/helm/ci/values-istio.yaml +++ b/common/oauth2-proxy/helm/ci/values-istio.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + clientSecret: not-a-real-client-secret + cookieSecret: not-a-real-cookie-secret-00000 istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml index 50b0c55904..dad6bce4e2 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + clientSecret: not-a-real-client-secret + cookieSecret: not-a-real-cookie-secret-00000 istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml index 8f8199b55a..7407e62b4b 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + clientSecret: not-a-real-client-secret + cookieSecret: not-a-real-cookie-secret-00000 istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml index 862f19d2ac..7f1d580d14 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb + clientSecret: not-a-real-client-secret + cookieSecret: not-a-real-cookie-secret-00000 istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml b/common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml index 6fe934dfd2..8d52d47d0b 100644 --- a/common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml +++ b/common/oauth2-proxy/helm/templates/cluster-jwks-proxy.yaml @@ -47,7 +47,7 @@ spec: - --accept-hosts=.* - --accept-paths=^(?:/openid/v1/jwks)|(?:/.well-known/openid-configuration)$ - --reject-methods=^(POST|PUT|PATCH|DELETE|HEAD|OPTIONS|CONNECT|TRACE)$ - image: {{ .Values.clusterJwksProxy.image }} + image: {{ required "clusterJwksProxy.image is required when clusterJwksProxy.enabled is true" .Values.clusterJwksProxy.image }} livenessProbe: httpGet: path: /openid/v1/jwks diff --git a/common/oauth2-proxy/helm/templates/oauth2-proxy.yaml b/common/oauth2-proxy/helm/templates/oauth2-proxy.yaml index 42abfeaf85..a299d808b7 100644 --- a/common/oauth2-proxy/helm/templates/oauth2-proxy.yaml +++ b/common/oauth2-proxy/helm/templates/oauth2-proxy.yaml @@ -77,6 +77,7 @@ spec: labels: app.kubernetes.io/name: oauth2-proxy spec: + serviceAccountName: oauth2-proxy containers: - args: - --http-address=0.0.0.0:4180 diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index 2512f0cf32..682a7c8ebd 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -6,9 +6,7 @@ from typing import Dict, List, Tuple, Any import re -KUSTOMIZE_HASH_SUFFIX = re.compile( - r"-(?=[a-z0-9]{10}$)(?=[a-z0-9]*[0-9])[a-z0-9]{10}$" -) +KUSTOMIZE_HASH_SUFFIX = re.compile(r'-(?=[a-z0-9]{10}$)[a-z0-9]{10}$') CERT_MANAGER_KUBEFLOW_RESOURCES = { ("ClusterIssuer", "kubeflow-self-signing-issuer"), @@ -21,31 +19,29 @@ "app.kubernetes.io/name", } - def load_manifests(file_path: str) -> List[Dict]: """Load YAML manifests from file.""" - with open(file_path, "r") as f: + with open(file_path, 'r') as f: content = f.read() - + docs = [] try: for doc in yaml.safe_load_all(content): - if doc: + if doc: docs.append(doc) except yaml.YAMLError: - for doc_str in content.split("---"): + for doc_str in content.split('---'): doc_str = doc_str.strip() if doc_str: try: doc = yaml.safe_load(doc_str) - if doc: + if doc: docs.append(doc) except yaml.YAMLError: continue - + return docs - def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: """Remove Helm-specific metadata that should be ignored in comparison.""" if isinstance(obj, dict): @@ -61,23 +57,18 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: for label_key, label_value in meta_value.items(): if component == "kserve-models-web-application": # More restrictive filtering for KServe - if not label_key.startswith( - ("helm.sh/", "app.kubernetes.io/managed-by") - ): + if not label_key.startswith(('helm.sh/', 'app.kubernetes.io/managed-by')): cleaned_labels[label_key] = label_value else: # Standard filtering for Katib and Model Registry helm_labels = [ - "app.kubernetes.io/managed-by", - "app.kubernetes.io/version", - "app.kubernetes.io/name", - "app.kubernetes.io/instance", - "app.kubernetes.io/component", + 'app.kubernetes.io/managed-by', + 'app.kubernetes.io/version', + 'app.kubernetes.io/name', + 'app.kubernetes.io/instance', + 'app.kubernetes.io/component' ] - if ( - not label_key.startswith("helm.sh/") - and label_key not in helm_labels - ): + if not label_key.startswith('helm.sh/') and label_key not in helm_labels: cleaned_labels[label_key] = label_value if cleaned_labels: # Only add if there are remaining labels cleaned_metadata[meta_key] = cleaned_labels @@ -85,11 +76,9 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: # Remove only Helm-specific annotations cleaned_annotations = {} for ann_key, ann_value in meta_value.items(): - if not ann_key.startswith(("helm.sh/", "meta.helm.sh/")): + if not ann_key.startswith(('helm.sh/', 'meta.helm.sh/')): cleaned_annotations[ann_key] = ann_value - if ( - cleaned_annotations - ): # Only add if there are remaining annotations + if cleaned_annotations: # Only add if there are remaining annotations cleaned_metadata[meta_key] = cleaned_annotations else: # Keep all other metadata fields as-is @@ -103,32 +92,24 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: else: return obj - def normalize_kustomize_refs(obj: Any, path: str = "") -> Any: """Normalize Kustomize hash suffixes in secret/configmap references throughout the manifest.""" if isinstance(obj, dict): normalized = {} for key, value in obj.items(): current_path = f"{path}.{key}" if path else key - + # Normalize secret/configmap references in common locations - if key == "name" and isinstance(value, str): - if any( - ref_pattern in path - for ref_pattern in [ - "secretKeyRef", - "configMapKeyRef", - "configMapRef", - "secret", - "volumes", - ] - ): - value = KUSTOMIZE_HASH_SUFFIX.sub("", value) - elif "volumes" in path and key == "secretName": - value = KUSTOMIZE_HASH_SUFFIX.sub("", value) - elif "volumes" in path and "configMap" in path: - value = KUSTOMIZE_HASH_SUFFIX.sub("", value) - + if isinstance(value, str): + if key == "name" and any(ref_pattern in path for ref_pattern in [ + 'secretKeyRef', 'configMapKeyRef', 'configMapRef', 'secret', 'volumes' + ]): + value = KUSTOMIZE_HASH_SUFFIX.sub('', value) + elif key == 'secretName' and 'volumes' in path: + value = KUSTOMIZE_HASH_SUFFIX.sub('', value) + elif key == "name" and 'volumes' in path and 'configMap' in path: + value = KUSTOMIZE_HASH_SUFFIX.sub('', value) + normalized[key] = normalize_kustomize_refs(value, current_path) return normalized elif isinstance(obj, list): @@ -136,69 +117,62 @@ def normalize_kustomize_refs(obj: Any, path: str = "") -> Any: else: return obj - -def normalize_manifest(manifest: Dict, component: str = "katib") -> Dict: +def normalize_manifest(manifest: Dict, component: str = "katib", normalize_kustomize_names: bool = True) -> Dict: """Normalize manifest by removing/standardizing certain fields.""" normalized = manifest.copy() - + # Clean Helm-specific metadata normalized = clean_helm_metadata(normalized, component) if component == "cert-manager": preserve_cert_manager_kubeflow_labels(manifest, normalized) - - # Normalize Kustomize hash references - normalized = normalize_kustomize_refs(normalized) - + + # Normalize Kustomize hash references only for Kustomize output. + if normalize_kustomize_names: + normalized = normalize_kustomize_refs(normalized) + # Handle ConfigMap data normalization (only for Katib) - if ( - component == "katib" - and normalized.get("kind") == "ConfigMap" - and "data" in normalized - ): - data = normalized["data"] + if component == "katib" and normalized.get('kind') == 'ConfigMap' and 'data' in normalized: + data = normalized['data'] normalized_data = {} for key, value in data.items(): if isinstance(value, str): # Remove leading/trailing whitespace and normalize YAML content normalized_value = value.strip() # Remove leading --- if present (common in ConfigMap YAML data) - if normalized_value.startswith("---"): + if normalized_value.startswith('---'): normalized_value = normalized_value[3:].strip() normalized_data[key] = normalized_value else: normalized_data[key] = value - normalized["data"] = normalized_data - - if "metadata" in normalized and "name" in normalized["metadata"]: - kind = normalized.get("kind", "") - if kind in ["Secret", "ConfigMap"]: - name = normalized["metadata"]["name"] - normalized["metadata"]["name"] = KUSTOMIZE_HASH_SUFFIX.sub("", name) - - if "metadata" in normalized: - metadata = normalized["metadata"] - - metadata.pop("generation", None) - metadata.pop("resourceVersion", None) - metadata.pop("uid", None) - metadata.pop("creationTimestamp", None) - metadata.pop("managedFields", None) - - normalized.pop("status", None) - + normalized['data'] = normalized_data + + if normalize_kustomize_names and 'metadata' in normalized and 'name' in normalized['metadata']: + kind = normalized.get('kind', '') + if kind in ['Secret', 'ConfigMap']: + name = normalized['metadata']['name'] + normalized['metadata']['name'] = KUSTOMIZE_HASH_SUFFIX.sub('', name) + + if 'metadata' in normalized: + metadata = normalized['metadata'] + + metadata.pop('generation', None) + metadata.pop('resourceVersion', None) + metadata.pop('uid', None) + metadata.pop('creationTimestamp', None) + metadata.pop('managedFields', None) + + normalized.pop('status', None) + def remove_empty_values(obj): if isinstance(obj, dict): - return { - k: remove_empty_values(v) - for k, v in obj.items() - if v is not None and v != {} and v != [] - } + return {k: remove_empty_values(v) for k, v in obj.items() + if v is not None and v != {} and v != []} elif isinstance(obj, list): return [remove_empty_values(item) for item in obj if item is not None] else: return obj - + return remove_empty_values(normalized) def preserve_cert_manager_kubeflow_labels(original: Dict, normalized: Dict) -> None: @@ -221,7 +195,6 @@ def preserve_cert_manager_kubeflow_labels(original: Dict, normalized: Dict) -> N preserved_labels ) - def should_compare_manifest(manifest: Dict, component: str, scenario: str) -> bool: """Select the resource subset owned by a comparison scenario.""" kind = manifest.get("kind", "") @@ -246,23 +219,20 @@ def get_resource_key(manifest: Dict, component: str = "katib") -> str: if kind in ["Secret", "ConfigMap"]: name = KUSTOMIZE_HASH_SUFFIX.sub("", name) - # Include namespace in key for components with same-named namespaced resources. + # Include namespace in key for components that render repeated names across namespaces. if component in ["katib", "cert-manager", "kubeflow-namespaces", "oauth2-proxy"] and namespace: return f"{kind}/{namespace}/{name}" else: return f"{kind}/{name}" - def deep_diff(obj1: Any, obj2: Any, path: str = "") -> List[str]: """Compare two objects and return list of differences.""" differences = [] - + if type(obj1) != type(obj2): - differences.append( - f"{path}: type mismatch ({type(obj1).__name__} vs {type(obj2).__name__})" - ) + differences.append(f"{path}: type mismatch ({type(obj1).__name__} vs {type(obj2).__name__})") return differences - + if isinstance(obj1, dict): all_keys = set(obj1.keys()) | set(obj2.keys()) for key in sorted(all_keys): @@ -273,108 +243,97 @@ def deep_diff(obj1: Any, obj2: Any, path: str = "") -> List[str]: differences.append(f"{key_path}: missing in helm") else: differences.extend(deep_diff(obj1[key], obj2[key], key_path)) - + elif isinstance(obj1, list): if len(obj1) != len(obj2): - differences.append( - f"{path}: list length mismatch ({len(obj1)} vs {len(obj2)})" - ) + differences.append(f"{path}: list length mismatch ({len(obj1)} vs {len(obj2)})") else: for i, (item1, item2) in enumerate(zip(obj1, obj2)): differences.extend(deep_diff(item1, item2, f"{path}[{i}]")) - + elif obj1 != obj2: differences.append(f"{path}: '{obj1}' != '{obj2}'") - + return differences - def get_expected_helm_extras(component: str, scenario: str) -> set: """Get expected extra resources in Helm for different components and scenarios.""" if component == "katib": return { - "Secret/kubeflow/katib-webhook-cert", # Webhook certificates + 'Secret/kubeflow/katib-webhook-cert', # Webhook certificates } elif component == "hub": return set() # No extra resources in Helm for Model Registry elif component == "kserve-models-web-application": return set() - elif component == "oauth2-proxy": + elif component == "cert-manager": return set() else: return set() - -def compare_manifests( - kustomize_file: str, - helm_file: str, - component: str, - scenario: str, - namespace: str = "", -) -> bool: +def compare_manifests(kustomize_file: str, helm_file: str, component: str, scenario: str, namespace: str = "") -> bool: """Compare Kustomize and Helm manifests.""" kustomize_manifests = load_manifests(kustomize_file) helm_manifests = load_manifests(helm_file) - + kustomize_resources = {} helm_resources = {} - + for manifest in kustomize_manifests: if not should_compare_manifest(manifest, component, scenario): continue - normalized = normalize_manifest(manifest, component) + normalized = normalize_manifest(manifest, component, normalize_kustomize_names=True) key = get_resource_key(normalized, component) kustomize_resources[key] = normalized - + for manifest in helm_manifests: if not should_compare_manifest(manifest, component, scenario): continue - normalized = normalize_manifest(manifest, component) + normalized = normalize_manifest(manifest, component, normalize_kustomize_names=False) key = get_resource_key(normalized, component) helm_resources[key] = normalized - + kustomize_keys = set(kustomize_resources.keys()) helm_keys = set(helm_resources.keys()) - + common_keys = kustomize_keys & helm_keys only_in_kustomize = kustomize_keys - helm_keys only_in_helm = helm_keys - kustomize_keys - + expected_helm_extras = get_expected_helm_extras(component, scenario) unexpected_helm_extras = only_in_helm - expected_helm_extras - + differences_found = [] success = True - + if only_in_kustomize: print(f"Resources only in Kustomize: {len(only_in_kustomize)}") success = False differences_found.extend(only_in_kustomize) - + if unexpected_helm_extras: print(f"Unexpected resources only in Helm: {len(unexpected_helm_extras)}") success = False differences_found.extend(unexpected_helm_extras) - + # Compare common resources for key in sorted(common_keys): kustomize_resource = kustomize_resources[key] helm_resource = helm_resources[key] - + differences = deep_diff(kustomize_resource, helm_resource) - + if differences: print(f"Differences in {key}: {len(differences)} fields") differences_found.append(key) success = False - + if not success: print(f"Found differences in {len(differences_found)} resources") return False - + return True - if __name__ == "__main__": if len(sys.argv) < 5: print( @@ -384,14 +343,12 @@ def compare_manifests( "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) - + kustomize_file = sys.argv[1] helm_file = sys.argv[2] component = sys.argv[3] scenario = sys.argv[4] - namespace = ( - sys.argv[5] if len(sys.argv) > 5 and not sys.argv[5].startswith("--") else "" - ) + namespace = sys.argv[5] if len(sys.argv) > 5 and not sys.argv[5].startswith('--') else "" if component not in [ "katib", @@ -407,8 +364,6 @@ def compare_manifests( "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) - - success = compare_manifests( - kustomize_file, helm_file, component, scenario, namespace - ) + + success = compare_manifests(kustomize_file, helm_file, component, scenario, namespace) sys.exit(0 if success else 1) From e6e9a349afe246586b381c5d1c26e16af87507d4 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Mon, 15 Jun 2026 18:00:25 +0530 Subject: [PATCH 09/19] test: keep oauth2-proxy hash normalization scoped Signed-off-by: danish9039 --- tests/helm_kustomize_compare.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index 682a7c8ebd..de8bbe03a6 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -289,7 +289,11 @@ def compare_manifests(kustomize_file: str, helm_file: str, component: str, scena for manifest in helm_manifests: if not should_compare_manifest(manifest, component, scenario): continue - normalized = normalize_manifest(manifest, component, normalize_kustomize_names=False) + normalized = normalize_manifest( + manifest, + component, + normalize_kustomize_names=(component != "oauth2-proxy"), + ) key = get_resource_key(normalized, component) helm_resources[key] = normalized From 10727dadc95203e9806c0b8a5d260dc2403f843e Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sun, 21 Jun 2026 22:06:29 +0530 Subject: [PATCH 10/19] helm: restore oauth2-proxy parity fixture values Signed-off-by: danish9039 --- common/oauth2-proxy/base/kustomization.yaml | 4 ++-- common/oauth2-proxy/helm/ci/values-base.yaml | 4 ++-- common/oauth2-proxy/helm/ci/values-istio.yaml | 4 ++-- common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml | 4 ++-- common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml | 4 ++-- common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/common/oauth2-proxy/base/kustomization.yaml b/common/oauth2-proxy/base/kustomization.yaml index 2ebab332f9..e4e7f4d335 100644 --- a/common/oauth2-proxy/base/kustomization.yaml +++ b/common/oauth2-proxy/base/kustomization.yaml @@ -17,8 +17,8 @@ secretGenerator: type: Opaque literals: - client-id=kubeflow-oidc-authservice - - client-secret=not-a-real-client-secret - - cookie-secret=not-a-real-cookie-secret-00000 + - client-secret=pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + - cookie-secret=7d16fee92f8d11b8940b081b3f8b8acb configMapGenerator: - name: oauth2-proxy diff --git a/common/oauth2-proxy/helm/ci/values-base.yaml b/common/oauth2-proxy/helm/ci/values-base.yaml index 1b59d051d1..788165cf09 100644 --- a/common/oauth2-proxy/helm/ci/values-base.yaml +++ b/common/oauth2-proxy/helm/ci/values-base.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: not-a-real-client-secret - cookieSecret: not-a-real-cookie-secret-00000 + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb istioExternalAuth: enabled: false diff --git a/common/oauth2-proxy/helm/ci/values-istio.yaml b/common/oauth2-proxy/helm/ci/values-istio.yaml index 7f1d580d14..862f19d2ac 100644 --- a/common/oauth2-proxy/helm/ci/values-istio.yaml +++ b/common/oauth2-proxy/helm/ci/values-istio.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: not-a-real-client-secret - cookieSecret: not-a-real-cookie-secret-00000 + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml index dad6bce4e2..50b0c55904 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: not-a-real-client-secret - cookieSecret: not-a-real-cookie-secret-00000 + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml index 7407e62b4b..8f8199b55a 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: not-a-real-client-secret - cookieSecret: not-a-real-cookie-secret-00000 + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb istioExternalAuth: enabled: true diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml index 7f1d580d14..862f19d2ac 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml @@ -1,6 +1,6 @@ credentials: - clientSecret: not-a-real-client-secret - cookieSecret: not-a-real-cookie-secret-00000 + clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok + cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb istioExternalAuth: enabled: true From 8a5d5d31ec3a5d5c75adfe5c6fa497511f2b5bb8 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sat, 27 Jun 2026 13:51:00 +0530 Subject: [PATCH 11/19] test: clean oauth2-proxy helm comparison style Signed-off-by: danish9039 --- common/oauth2-proxy/helm/README.md | 3 ++- common/oauth2-proxy/helm/values.yaml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/common/oauth2-proxy/helm/README.md b/common/oauth2-proxy/helm/README.md index 07535da0c0..d2c0bce7b5 100644 --- a/common/oauth2-proxy/helm/README.md +++ b/common/oauth2-proxy/helm/README.md @@ -4,7 +4,7 @@ This chart renders the current Kubeflow oauth2-proxy Kustomize resources with Helm. It is intentionally static for the first chart slice so rendered output stays aligned with `common/oauth2-proxy`. -## Install +## Installation Install foundation, cert-manager, and Istio first. The `kubeflow-namespaces` foundation chart creates `Namespace/oauth2-proxy`; this chart stores Helm @@ -32,6 +32,7 @@ helm install oauth2-proxy ./common/oauth2-proxy/helm \ ## Kustomize Mapping - `ci/values-base.yaml`: `common/oauth2-proxy/base` +- `ci/values-istio.yaml`: `common/oauth2-proxy/overlays/istio` - `ci/values-m2m-dex-only.yaml`: `common/oauth2-proxy/overlays/m2m-dex-only` - `ci/values-m2m-dex-and-kind.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-kind` - `ci/values-m2m-dex-and-eks.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-eks` diff --git a/common/oauth2-proxy/helm/values.yaml b/common/oauth2-proxy/helm/values.yaml index ed5f048bc9..137f3116ea 100644 --- a/common/oauth2-proxy/helm/values.yaml +++ b/common/oauth2-proxy/helm/values.yaml @@ -13,7 +13,7 @@ parameters: forceHttps: "false" # -- Allow self-signed issuer certificates. allowSelfSignedIssuer: "true" - # -- Allow machine-to-machine bearer tokens. + # -- Allow machine-to-machine bearer tokens by setting OAUTH2_PROXY_SKIP_JWT_BEARER_TOKENS. enableM2MTokens: "true" # -- Extra JWT issuers in oauth2-proxy --extra-jwt-issuers format. extraJwtIssuers: "" @@ -27,7 +27,7 @@ networkPolicies: enabled: true istioExternalAuth: - # -- Render Istio external auth resources for oauth2-proxy. + # -- Render Istio AuthorizationPolicy and RequestAuthentication resources for oauth2-proxy external auth. enabled: false m2m: From 0b04aec8477b5ed4b07ddb2c18ae03fd11095416 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sun, 28 Jun 2026 16:22:26 +0530 Subject: [PATCH 12/19] scripts: sync oauth2-proxy helm chart updates Signed-off-by: danish9039 --- scripts/synchronize-oauth2-proxy-manifests.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/synchronize-oauth2-proxy-manifests.sh b/scripts/synchronize-oauth2-proxy-manifests.sh index 7b76ec2f1c..48abeb6afd 100755 --- a/scripts/synchronize-oauth2-proxy-manifests.sh +++ b/scripts/synchronize-oauth2-proxy-manifests.sh @@ -9,16 +9,28 @@ COMMIT="v7.15.2" BRANCH_NAME=${BRANCH_NAME:=synchronize-${COMPONENT_NAME}-manifests-${COMMIT?}} MANIFESTS_DIRECTORY=$(dirname $SCRIPT_DIRECTORY) DESTINATION_DIRECTORY=$MANIFESTS_DIRECTORY/common/${COMPONENT_NAME} +CHART_DIRECTORY="$DESTINATION_DIRECTORY/helm" create_branch "$BRANCH_NAME" if [[ "$OSTYPE" == "darwin"* ]]; then sed -i "" "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ $DESTINATION_DIRECTORY/base/deployment.yaml + sed -i "" "s|^appVersion: .*|appVersion: ${COMMIT#v}|g" \ + "$CHART_DIRECTORY/Chart.yaml" + sed -i "" "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ + "$CHART_DIRECTORY/templates/oauth2-proxy.yaml" else sed -i "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ $DESTINATION_DIRECTORY/base/deployment.yaml + sed -i "s|^appVersion: .*|appVersion: ${COMMIT#v}|g" \ + "$CHART_DIRECTORY/Chart.yaml" + sed -i "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ + "$CHART_DIRECTORY/templates/oauth2-proxy.yaml" fi SOURCE_TEXT="\[.*\](https://github.com/${REPOSITORY_NAME}/releases/tag/v.*)" DESTINATION_TEXT="\[${COMMIT#v}\](https://github.com/${REPOSITORY_NAME}/releases/tag/${COMMIT})" update_readme "$MANIFESTS_DIRECTORY" "$SOURCE_TEXT" "$DESTINATION_TEXT" -commit_changes "$MANIFESTS_DIRECTORY" "Update ${REPOSITORY_NAME} manifests from ${COMMIT}" "$MANIFESTS_DIRECTORY" +commit_changes "$MANIFESTS_DIRECTORY" "Update ${REPOSITORY_NAME} manifests from ${COMMIT}" \ + "README.md" \ + "scripts/synchronize-oauth2-proxy-manifests.sh" \ + "common/${COMPONENT_NAME}" echo "Synchronization completed successfully." From 396a4d3a3817ae2c89c28d6f87b96062a1a59d12 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sun, 28 Jun 2026 16:22:26 +0530 Subject: [PATCH 13/19] ci: run helm compare for oauth2-proxy sync changes Signed-off-by: danish9039 --- .github/workflows/helm-kustomize-comparison.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/helm-kustomize-comparison.yml b/.github/workflows/helm-kustomize-comparison.yml index b79634f2f3..1d4256138c 100644 --- a/.github/workflows/helm-kustomize-comparison.yml +++ b/.github/workflows/helm-kustomize-comparison.yml @@ -8,7 +8,8 @@ on: - common/kubeflow-namespace/** - common/kubeflow-roles/** - scripts/synchronize-cert-manager-manifests.sh - - common/oauth2-proxy/helm/** + - common/oauth2-proxy/** + - scripts/synchronize-oauth2-proxy-manifests.sh - tests/kustomize_install.sh - tests/helm_kustomize_compare.py - tests/helm_kustomize_compare.sh From 08ce0db0ae0fba382c8e38b88cc2c1d039940569 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Wed, 1 Jul 2026 17:44:10 +0530 Subject: [PATCH 14/19] helm: focus oauth2-proxy ci values on default scenario Signed-off-by: danish9039 --- common/oauth2-proxy/helm/README.md | 19 ++++------------- common/oauth2-proxy/helm/ci/values-base.yaml | 12 ----------- common/oauth2-proxy/helm/ci/values-istio.yaml | 15 ------------- .../helm/ci/values-m2m-dex-and-eks.yaml | 16 -------------- .../helm/ci/values-m2m-dex-and-kind.yaml | 21 ------------------- .../overlays/istio/kustomization.yaml | 5 ----- 6 files changed, 4 insertions(+), 84 deletions(-) delete mode 100644 common/oauth2-proxy/helm/ci/values-base.yaml delete mode 100644 common/oauth2-proxy/helm/ci/values-istio.yaml delete mode 100644 common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml delete mode 100644 common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml delete mode 100644 common/oauth2-proxy/overlays/istio/kustomization.yaml diff --git a/common/oauth2-proxy/helm/README.md b/common/oauth2-proxy/helm/README.md index d2c0bce7b5..6fd85bb6f7 100644 --- a/common/oauth2-proxy/helm/README.md +++ b/common/oauth2-proxy/helm/README.md @@ -20,22 +20,12 @@ helm install oauth2-proxy ./common/oauth2-proxy/helm \ --values ./common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml ``` -For kind-like clusters that use Kubernetes service account JWTs for gateway -machine-to-machine auth, use: - -```bash -helm install oauth2-proxy ./common/oauth2-proxy/helm \ - --namespace oauth2-proxy \ - --values ./common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml -``` - ## Kustomize Mapping -- `ci/values-base.yaml`: `common/oauth2-proxy/base` -- `ci/values-istio.yaml`: `common/oauth2-proxy/overlays/istio` - `ci/values-m2m-dex-only.yaml`: `common/oauth2-proxy/overlays/m2m-dex-only` -- `ci/values-m2m-dex-and-kind.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-kind` -- `ci/values-m2m-dex-and-eks.yaml`: `common/oauth2-proxy/overlays/m2m-dex-and-eks` + +Kubernetes in Docker and Amazon EKS machine-to-machine values are deferred until +Helm integration tests or documented cluster-specific scenarios cover them. Direct enterprise IdP mode, Cloudflare cache policies, and an upstream oauth2-proxy Helm dependency wrapper are deferred until the parity chart is @@ -45,6 +35,5 @@ stable. ```bash helm lint common/oauth2-proxy/helm -./tests/helm_kustomize_compare.sh oauth2-proxy base -./tests/helm_kustomize_compare.sh oauth2-proxy overlays-istio +./tests/helm_kustomize_compare.sh oauth2-proxy m2m-dex-only ``` diff --git a/common/oauth2-proxy/helm/ci/values-base.yaml b/common/oauth2-proxy/helm/ci/values-base.yaml deleted file mode 100644 index 788165cf09..0000000000 --- a/common/oauth2-proxy/helm/ci/values-base.yaml +++ /dev/null @@ -1,12 +0,0 @@ -credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb - -istioExternalAuth: - enabled: false - -m2m: - enabled: false - -clusterJwksProxy: - enabled: false diff --git a/common/oauth2-proxy/helm/ci/values-istio.yaml b/common/oauth2-proxy/helm/ci/values-istio.yaml deleted file mode 100644 index 862f19d2ac..0000000000 --- a/common/oauth2-proxy/helm/ci/values-istio.yaml +++ /dev/null @@ -1,15 +0,0 @@ -credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb - -istioExternalAuth: - enabled: true - -m2m: - enabled: false - -clusterJwksProxy: - enabled: false - -parameters: - allowSelfSignedIssuer: "true" diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml deleted file mode 100644 index 50b0c55904..0000000000 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-eks.yaml +++ /dev/null @@ -1,16 +0,0 @@ -credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb - -istioExternalAuth: - enabled: true - -m2m: - enabled: true - issuer: https://oidc.eks.AWS_REGION.amazonaws.com/id/CLUSTER_ID - -clusterJwksProxy: - enabled: false - -parameters: - forceHttps: "true" diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml deleted file mode 100644 index 8f8199b55a..0000000000 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-and-kind.yaml +++ /dev/null @@ -1,21 +0,0 @@ -credentials: - clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok - cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb - -istioExternalAuth: - enabled: true - -m2m: - enabled: true - issuer: https://kubernetes.default.svc.cluster.local - jwksUri: http://cluster-jwks-proxy.istio-system.svc.cluster.local/openid/v1/jwks - additionalJwtRules: - - issuer: https://kubernetes.default.svc - jwksUri: http://cluster-jwks-proxy.istio-system.svc.cluster.local/openid/v1/jwks - -clusterJwksProxy: - enabled: true - image: docker.io/bitnamisecure/kubectl:latest - -parameters: - allowSelfSignedIssuer: "true" diff --git a/common/oauth2-proxy/overlays/istio/kustomization.yaml b/common/oauth2-proxy/overlays/istio/kustomization.yaml deleted file mode 100644 index ce30d80bbb..0000000000 --- a/common/oauth2-proxy/overlays/istio/kustomization.yaml +++ /dev/null @@ -1,5 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: -- ../m2m-dex-only From b6883c2a517b29a1ae98e32a50e398858ec92f0d Mon Sep 17 00:00:00 2001 From: danish9039 Date: Wed, 1 Jul 2026 20:40:11 +0530 Subject: [PATCH 15/19] helm: clarify oauth2-proxy external authorization values Signed-off-by: danish9039 --- common/oauth2-proxy/helm/Chart.yaml | 3 ++- common/oauth2-proxy/helm/README.md | 2 +- common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml | 2 +- ...o-external-auth.yaml => istio-external-authorization.yaml} | 2 +- common/oauth2-proxy/helm/values.yaml | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) rename common/oauth2-proxy/helm/templates/{istio-external-auth.yaml => istio-external-authorization.yaml} (96%) diff --git a/common/oauth2-proxy/helm/Chart.yaml b/common/oauth2-proxy/helm/Chart.yaml index f82ba5a4ff..5b72d70bf5 100644 --- a/common/oauth2-proxy/helm/Chart.yaml +++ b/common/oauth2-proxy/helm/Chart.yaml @@ -1,11 +1,12 @@ apiVersion: v2 name: oauth2-proxy -description: A Helm chart for Kubeflow oauth2-proxy authentication resources +description: A Helm chart for Kubeflow oauth2-proxy authentication and authorization resources version: 0.1.0 appVersion: 7.15.2 keywords: - authentication +- authorization - oauth2 - kubeflow - oauth2-proxy diff --git a/common/oauth2-proxy/helm/README.md b/common/oauth2-proxy/helm/README.md index 6fd85bb6f7..174b0cbea7 100644 --- a/common/oauth2-proxy/helm/README.md +++ b/common/oauth2-proxy/helm/README.md @@ -12,7 +12,7 @@ release metadata in that same workload namespace. ## Namespace names -Namespace names are fixed to match the Kustomize baseline and `kubeflow-namespaces` foundation chart. oauth2-proxy workloads use `oauth2-proxy`, Istio auth resources use `istio-system`, and gateway references use `kubeflow`. These names are not configurable. +Namespace names are fixed to match the Kustomize baseline and `kubeflow-namespaces` foundation chart. oauth2-proxy workloads use `oauth2-proxy`, Istio authentication and authorization resources use `istio-system`, and gateway references use `kubeflow`. These names are not configurable. ```bash helm install oauth2-proxy ./common/oauth2-proxy/helm \ diff --git a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml index 862f19d2ac..e3902a63cf 100644 --- a/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml +++ b/common/oauth2-proxy/helm/ci/values-m2m-dex-only.yaml @@ -2,7 +2,7 @@ credentials: clientSecret: pUBnBOY80SnXgjibTYM9ZWNzY2xreNGQok cookieSecret: 7d16fee92f8d11b8940b081b3f8b8acb -istioExternalAuth: +istioExternalAuthorization: enabled: true m2m: diff --git a/common/oauth2-proxy/helm/templates/istio-external-auth.yaml b/common/oauth2-proxy/helm/templates/istio-external-authorization.yaml similarity index 96% rename from common/oauth2-proxy/helm/templates/istio-external-auth.yaml rename to common/oauth2-proxy/helm/templates/istio-external-authorization.yaml index 6054650164..63f3d96283 100644 --- a/common/oauth2-proxy/helm/templates/istio-external-auth.yaml +++ b/common/oauth2-proxy/helm/templates/istio-external-authorization.yaml @@ -1,4 +1,4 @@ -{{- if .Values.istioExternalAuth.enabled }} +{{- if .Values.istioExternalAuthorization.enabled }} apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: diff --git a/common/oauth2-proxy/helm/values.yaml b/common/oauth2-proxy/helm/values.yaml index 137f3116ea..b0e9503a56 100644 --- a/common/oauth2-proxy/helm/values.yaml +++ b/common/oauth2-proxy/helm/values.yaml @@ -26,8 +26,8 @@ networkPolicies: # -- Render oauth2-proxy namespace NetworkPolicies. enabled: true -istioExternalAuth: - # -- Render Istio AuthorizationPolicy and RequestAuthentication resources for oauth2-proxy external auth. +istioExternalAuthorization: + # -- Render Istio AuthorizationPolicy and RequestAuthentication resources for oauth2-proxy external authorization. enabled: false m2m: From b0853b7321669531167e5e55adff044f4367158b Mon Sep 17 00:00:00 2001 From: danish9039 Date: Fri, 3 Jul 2026 04:35:00 +0530 Subject: [PATCH 16/19] test: clarify oauth2-proxy helm comparison scenario Signed-off-by: danish9039 --- scripts/synchronize-oauth2-proxy-manifests.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/synchronize-oauth2-proxy-manifests.sh b/scripts/synchronize-oauth2-proxy-manifests.sh index 48abeb6afd..9bf4b6b7ef 100755 --- a/scripts/synchronize-oauth2-proxy-manifests.sh +++ b/scripts/synchronize-oauth2-proxy-manifests.sh @@ -7,20 +7,20 @@ COMPONENT_NAME="oauth2-proxy" REPOSITORY_NAME="oauth2-proxy/oauth2-proxy" COMMIT="v7.15.2" BRANCH_NAME=${BRANCH_NAME:=synchronize-${COMPONENT_NAME}-manifests-${COMMIT?}} -MANIFESTS_DIRECTORY=$(dirname $SCRIPT_DIRECTORY) -DESTINATION_DIRECTORY=$MANIFESTS_DIRECTORY/common/${COMPONENT_NAME} +MANIFESTS_DIRECTORY="$(dirname "$SCRIPT_DIRECTORY")" +DESTINATION_DIRECTORY="$MANIFESTS_DIRECTORY/common/${COMPONENT_NAME}" CHART_DIRECTORY="$DESTINATION_DIRECTORY/helm" create_branch "$BRANCH_NAME" if [[ "$OSTYPE" == "darwin"* ]]; then sed -i "" "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ - $DESTINATION_DIRECTORY/base/deployment.yaml + "$DESTINATION_DIRECTORY/base/deployment.yaml" sed -i "" "s|^appVersion: .*|appVersion: ${COMMIT#v}|g" \ "$CHART_DIRECTORY/Chart.yaml" sed -i "" "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ "$CHART_DIRECTORY/templates/oauth2-proxy.yaml" else sed -i "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ - $DESTINATION_DIRECTORY/base/deployment.yaml + "$DESTINATION_DIRECTORY/base/deployment.yaml" sed -i "s|^appVersion: .*|appVersion: ${COMMIT#v}|g" \ "$CHART_DIRECTORY/Chart.yaml" sed -i "s|quay.io/oauth2-proxy/oauth2-proxy:.*|quay.io/oauth2-proxy/oauth2-proxy:${COMMIT}|g" \ From be97b6b122fbbda21ead3185b5808cecf9f78fe0 Mon Sep 17 00:00:00 2001 From: danish9039 Date: Fri, 3 Jul 2026 15:10:39 +0530 Subject: [PATCH 17/19] test: format helm compare helper Signed-off-by: danish9039 --- tests/helm_kustomize_compare.py | 220 ++++++++++++++++++++------------ 1 file changed, 137 insertions(+), 83 deletions(-) diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index de8bbe03a6..4d075d4fc8 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -6,7 +6,7 @@ from typing import Dict, List, Tuple, Any import re -KUSTOMIZE_HASH_SUFFIX = re.compile(r'-(?=[a-z0-9]{10}$)[a-z0-9]{10}$') +KUSTOMIZE_HASH_SUFFIX = re.compile(r"-(?=[a-z0-9]{10}$)[a-z0-9]{10}$") CERT_MANAGER_KUBEFLOW_RESOURCES = { ("ClusterIssuer", "kubeflow-self-signing-issuer"), @@ -19,29 +19,31 @@ "app.kubernetes.io/name", } + def load_manifests(file_path: str) -> List[Dict]: """Load YAML manifests from file.""" - with open(file_path, 'r') as f: + with open(file_path, "r") as f: content = f.read() - + docs = [] try: for doc in yaml.safe_load_all(content): - if doc: + if doc: docs.append(doc) except yaml.YAMLError: - for doc_str in content.split('---'): + for doc_str in content.split("---"): doc_str = doc_str.strip() if doc_str: try: doc = yaml.safe_load(doc_str) - if doc: + if doc: docs.append(doc) except yaml.YAMLError: continue - + return docs + def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: """Remove Helm-specific metadata that should be ignored in comparison.""" if isinstance(obj, dict): @@ -57,18 +59,23 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: for label_key, label_value in meta_value.items(): if component == "kserve-models-web-application": # More restrictive filtering for KServe - if not label_key.startswith(('helm.sh/', 'app.kubernetes.io/managed-by')): + if not label_key.startswith( + ("helm.sh/", "app.kubernetes.io/managed-by") + ): cleaned_labels[label_key] = label_value else: # Standard filtering for Katib and Model Registry helm_labels = [ - 'app.kubernetes.io/managed-by', - 'app.kubernetes.io/version', - 'app.kubernetes.io/name', - 'app.kubernetes.io/instance', - 'app.kubernetes.io/component' + "app.kubernetes.io/managed-by", + "app.kubernetes.io/version", + "app.kubernetes.io/name", + "app.kubernetes.io/instance", + "app.kubernetes.io/component", ] - if not label_key.startswith('helm.sh/') and label_key not in helm_labels: + if ( + not label_key.startswith("helm.sh/") + and label_key not in helm_labels + ): cleaned_labels[label_key] = label_value if cleaned_labels: # Only add if there are remaining labels cleaned_metadata[meta_key] = cleaned_labels @@ -76,9 +83,11 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: # Remove only Helm-specific annotations cleaned_annotations = {} for ann_key, ann_value in meta_value.items(): - if not ann_key.startswith(('helm.sh/', 'meta.helm.sh/')): + if not ann_key.startswith(("helm.sh/", "meta.helm.sh/")): cleaned_annotations[ann_key] = ann_value - if cleaned_annotations: # Only add if there are remaining annotations + if ( + cleaned_annotations + ): # Only add if there are remaining annotations cleaned_metadata[meta_key] = cleaned_annotations else: # Keep all other metadata fields as-is @@ -92,24 +101,32 @@ def clean_helm_metadata(obj: Any, component: str = "katib") -> Any: else: return obj + def normalize_kustomize_refs(obj: Any, path: str = "") -> Any: """Normalize Kustomize hash suffixes in secret/configmap references throughout the manifest.""" if isinstance(obj, dict): normalized = {} for key, value in obj.items(): current_path = f"{path}.{key}" if path else key - + # Normalize secret/configmap references in common locations if isinstance(value, str): - if key == "name" and any(ref_pattern in path for ref_pattern in [ - 'secretKeyRef', 'configMapKeyRef', 'configMapRef', 'secret', 'volumes' - ]): - value = KUSTOMIZE_HASH_SUFFIX.sub('', value) - elif key == 'secretName' and 'volumes' in path: - value = KUSTOMIZE_HASH_SUFFIX.sub('', value) - elif key == "name" and 'volumes' in path and 'configMap' in path: - value = KUSTOMIZE_HASH_SUFFIX.sub('', value) - + if key == "name" and any( + ref_pattern in path + for ref_pattern in [ + "secretKeyRef", + "configMapKeyRef", + "configMapRef", + "secret", + "volumes", + ] + ): + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) + elif key == "secretName" and "volumes" in path: + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) + elif key == "name" and "volumes" in path and "configMap" in path: + value = KUSTOMIZE_HASH_SUFFIX.sub("", value) + normalized[key] = normalize_kustomize_refs(value, current_path) return normalized elif isinstance(obj, list): @@ -117,64 +134,79 @@ def normalize_kustomize_refs(obj: Any, path: str = "") -> Any: else: return obj -def normalize_manifest(manifest: Dict, component: str = "katib", normalize_kustomize_names: bool = True) -> Dict: + +def normalize_manifest( + manifest: Dict, component: str = "katib", normalize_kustomize_names: bool = True +) -> Dict: """Normalize manifest by removing/standardizing certain fields.""" normalized = manifest.copy() - + # Clean Helm-specific metadata normalized = clean_helm_metadata(normalized, component) if component == "cert-manager": preserve_cert_manager_kubeflow_labels(manifest, normalized) - + # Normalize Kustomize hash references only for Kustomize output. if normalize_kustomize_names: normalized = normalize_kustomize_refs(normalized) - + # Handle ConfigMap data normalization (only for Katib) - if component == "katib" and normalized.get('kind') == 'ConfigMap' and 'data' in normalized: - data = normalized['data'] + if ( + component == "katib" + and normalized.get("kind") == "ConfigMap" + and "data" in normalized + ): + data = normalized["data"] normalized_data = {} for key, value in data.items(): if isinstance(value, str): # Remove leading/trailing whitespace and normalize YAML content normalized_value = value.strip() # Remove leading --- if present (common in ConfigMap YAML data) - if normalized_value.startswith('---'): + if normalized_value.startswith("---"): normalized_value = normalized_value[3:].strip() normalized_data[key] = normalized_value else: normalized_data[key] = value - normalized['data'] = normalized_data - - if normalize_kustomize_names and 'metadata' in normalized and 'name' in normalized['metadata']: - kind = normalized.get('kind', '') - if kind in ['Secret', 'ConfigMap']: - name = normalized['metadata']['name'] - normalized['metadata']['name'] = KUSTOMIZE_HASH_SUFFIX.sub('', name) - - if 'metadata' in normalized: - metadata = normalized['metadata'] - - metadata.pop('generation', None) - metadata.pop('resourceVersion', None) - metadata.pop('uid', None) - metadata.pop('creationTimestamp', None) - metadata.pop('managedFields', None) - - normalized.pop('status', None) - + normalized["data"] = normalized_data + + if ( + normalize_kustomize_names + and "metadata" in normalized + and "name" in normalized["metadata"] + ): + kind = normalized.get("kind", "") + if kind in ["Secret", "ConfigMap"]: + name = normalized["metadata"]["name"] + normalized["metadata"]["name"] = KUSTOMIZE_HASH_SUFFIX.sub("", name) + + if "metadata" in normalized: + metadata = normalized["metadata"] + + metadata.pop("generation", None) + metadata.pop("resourceVersion", None) + metadata.pop("uid", None) + metadata.pop("creationTimestamp", None) + metadata.pop("managedFields", None) + + normalized.pop("status", None) + def remove_empty_values(obj): if isinstance(obj, dict): - return {k: remove_empty_values(v) for k, v in obj.items() - if v is not None and v != {} and v != []} + return { + k: remove_empty_values(v) + for k, v in obj.items() + if v is not None and v != {} and v != [] + } elif isinstance(obj, list): return [remove_empty_values(item) for item in obj if item is not None] else: return obj - + return remove_empty_values(normalized) + def preserve_cert_manager_kubeflow_labels(original: Dict, normalized: Dict) -> None: """Keep labels that are intentionally added by cert-manager's Kubeflow overlay.""" kind = original.get("kind", "") @@ -195,6 +227,7 @@ def preserve_cert_manager_kubeflow_labels(original: Dict, normalized: Dict) -> N preserved_labels ) + def should_compare_manifest(manifest: Dict, component: str, scenario: str) -> bool: """Select the resource subset owned by a comparison scenario.""" kind = manifest.get("kind", "") @@ -210,6 +243,7 @@ def should_compare_manifest(manifest: Dict, component: str, scenario: str) -> bo return True + def get_resource_key(manifest: Dict, component: str = "katib") -> str: """Generate a unique key for the resource.""" kind = manifest.get("kind", "Unknown") @@ -225,14 +259,17 @@ def get_resource_key(manifest: Dict, component: str = "katib") -> str: else: return f"{kind}/{name}" + def deep_diff(obj1: Any, obj2: Any, path: str = "") -> List[str]: """Compare two objects and return list of differences.""" differences = [] - + if type(obj1) != type(obj2): - differences.append(f"{path}: type mismatch ({type(obj1).__name__} vs {type(obj2).__name__})") + differences.append( + f"{path}: type mismatch ({type(obj1).__name__} vs {type(obj2).__name__})" + ) return differences - + if isinstance(obj1, dict): all_keys = set(obj1.keys()) | set(obj2.keys()) for key in sorted(all_keys): @@ -243,24 +280,27 @@ def deep_diff(obj1: Any, obj2: Any, path: str = "") -> List[str]: differences.append(f"{key_path}: missing in helm") else: differences.extend(deep_diff(obj1[key], obj2[key], key_path)) - + elif isinstance(obj1, list): if len(obj1) != len(obj2): - differences.append(f"{path}: list length mismatch ({len(obj1)} vs {len(obj2)})") + differences.append( + f"{path}: list length mismatch ({len(obj1)} vs {len(obj2)})" + ) else: for i, (item1, item2) in enumerate(zip(obj1, obj2)): differences.extend(deep_diff(item1, item2, f"{path}[{i}]")) - + elif obj1 != obj2: differences.append(f"{path}: '{obj1}' != '{obj2}'") - + return differences + def get_expected_helm_extras(component: str, scenario: str) -> set: """Get expected extra resources in Helm for different components and scenarios.""" if component == "katib": return { - 'Secret/kubeflow/katib-webhook-cert', # Webhook certificates + "Secret/kubeflow/katib-webhook-cert", # Webhook certificates } elif component == "hub": return set() # No extra resources in Helm for Model Registry @@ -271,21 +311,30 @@ def get_expected_helm_extras(component: str, scenario: str) -> set: else: return set() -def compare_manifests(kustomize_file: str, helm_file: str, component: str, scenario: str, namespace: str = "") -> bool: + +def compare_manifests( + kustomize_file: str, + helm_file: str, + component: str, + scenario: str, + namespace: str = "", +) -> bool: """Compare Kustomize and Helm manifests.""" kustomize_manifests = load_manifests(kustomize_file) helm_manifests = load_manifests(helm_file) - + kustomize_resources = {} helm_resources = {} - + for manifest in kustomize_manifests: if not should_compare_manifest(manifest, component, scenario): continue - normalized = normalize_manifest(manifest, component, normalize_kustomize_names=True) + normalized = normalize_manifest( + manifest, component, normalize_kustomize_names=True + ) key = get_resource_key(normalized, component) kustomize_resources[key] = normalized - + for manifest in helm_manifests: if not should_compare_manifest(manifest, component, scenario): continue @@ -296,48 +345,49 @@ def compare_manifests(kustomize_file: str, helm_file: str, component: str, scena ) key = get_resource_key(normalized, component) helm_resources[key] = normalized - + kustomize_keys = set(kustomize_resources.keys()) helm_keys = set(helm_resources.keys()) - + common_keys = kustomize_keys & helm_keys only_in_kustomize = kustomize_keys - helm_keys only_in_helm = helm_keys - kustomize_keys - + expected_helm_extras = get_expected_helm_extras(component, scenario) unexpected_helm_extras = only_in_helm - expected_helm_extras - + differences_found = [] success = True - + if only_in_kustomize: print(f"Resources only in Kustomize: {len(only_in_kustomize)}") success = False differences_found.extend(only_in_kustomize) - + if unexpected_helm_extras: print(f"Unexpected resources only in Helm: {len(unexpected_helm_extras)}") success = False differences_found.extend(unexpected_helm_extras) - + # Compare common resources for key in sorted(common_keys): kustomize_resource = kustomize_resources[key] helm_resource = helm_resources[key] - + differences = deep_diff(kustomize_resource, helm_resource) - + if differences: print(f"Differences in {key}: {len(differences)} fields") differences_found.append(key) success = False - + if not success: print(f"Found differences in {len(differences_found)} resources") return False - + return True + if __name__ == "__main__": if len(sys.argv) < 5: print( @@ -347,12 +397,14 @@ def compare_manifests(kustomize_file: str, helm_file: str, component: str, scena "Components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) - + kustomize_file = sys.argv[1] helm_file = sys.argv[2] component = sys.argv[3] scenario = sys.argv[4] - namespace = sys.argv[5] if len(sys.argv) > 5 and not sys.argv[5].startswith('--') else "" + namespace = ( + sys.argv[5] if len(sys.argv) > 5 and not sys.argv[5].startswith("--") else "" + ) if component not in [ "katib", @@ -368,6 +420,8 @@ def compare_manifests(kustomize_file: str, helm_file: str, component: str, scena "Supported components: katib, hub, kserve-models-web-application, cert-manager, kubeflow-namespaces, kubeflow-platform, oauth2-proxy" ) sys.exit(1) - - success = compare_manifests(kustomize_file, helm_file, component, scenario, namespace) + + success = compare_manifests( + kustomize_file, helm_file, component, scenario, namespace + ) sys.exit(0 if success else 1) From 26348530663b7398e532579d6db0df1bbcd95f1a Mon Sep 17 00:00:00 2001 From: danish9039 Date: Sun, 5 Jul 2026 20:18:38 +0530 Subject: [PATCH 18/19] helm: update chart repository metadata Signed-off-by: danish9039 --- common/oauth2-proxy/helm/Chart.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/oauth2-proxy/helm/Chart.yaml b/common/oauth2-proxy/helm/Chart.yaml index 5b72d70bf5..86d0cbc916 100644 --- a/common/oauth2-proxy/helm/Chart.yaml +++ b/common/oauth2-proxy/helm/Chart.yaml @@ -11,10 +11,10 @@ keywords: - kubeflow - oauth2-proxy -home: https://github.com/kubeflow/manifests +home: https://github.com/kubeflow/community-distribution sources: -- https://github.com/kubeflow/manifests/tree/master/common/oauth2-proxy +- https://github.com/kubeflow/community-distribution/tree/master/common/oauth2-proxy - https://github.com/oauth2-proxy/oauth2-proxy annotations: From bb70257b97372bf9063845ad9bfb0ca3cc12df7b Mon Sep 17 00:00:00 2001 From: danish9039 Date: Wed, 8 Jul 2026 22:12:52 +0530 Subject: [PATCH 19/19] test: format oauth2-proxy helm compare helper Signed-off-by: danish9039 --- tests/helm_kustomize_compare.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/helm_kustomize_compare.py b/tests/helm_kustomize_compare.py index 4d075d4fc8..5ffb54ce1b 100755 --- a/tests/helm_kustomize_compare.py +++ b/tests/helm_kustomize_compare.py @@ -254,7 +254,10 @@ def get_resource_key(manifest: Dict, component: str = "katib") -> str: name = KUSTOMIZE_HASH_SUFFIX.sub("", name) # Include namespace in key for components that render repeated names across namespaces. - if component in ["katib", "cert-manager", "kubeflow-namespaces", "oauth2-proxy"] and namespace: + if ( + component in ["katib", "cert-manager", "kubeflow-namespaces", "oauth2-proxy"] + and namespace + ): return f"{kind}/{namespace}/{name}" else: return f"{kind}/{name}"