Add kubeflow/v1.10.0

This commit is contained in:
wbsong111
2025-06-24 12:03:10 +09:00
parent 0132496142
commit 6e8dd89e48
1531 changed files with 120984 additions and 262120 deletions
@@ -0,0 +1,216 @@
# Kubeflow with oauth2-proxy and envoyExtAuthzHttp
For a quick install, see [Example installation](#example-installation).
## Description
Kubeflow authorization operates using custom authentication headers:
* `kubeflow-userid`: Contains the user's email address.
* `kubeflow-groups`: Holds a comma-separated list of user groups.
* Note: The functionality for `kubeflow-groups` is not fully operational at this time.
This feature was implemented using a custom, minimalistic authorization tool from Arrikto
named `oidc-authservice`. This tool was integrated into Istio using `EnvoyFilter`.
The adoption of `envoyExtAuthzHttp` for authentication offers several advantages:
* **Simplified Authorization Process**: `envoyExtAuthzHttp` extension streamlines adding
external authorization to the Envoy proxy within an Istio service mesh. It allows for
declarative policy configuration, reducing the complexity associated with direct
`EnvoyFilter` modifications.
* **Standardization**: Istio recommends `envoyExtAuthzHttp` for its standardized approach.
This promotes consistency across Istio deployments and simplifies understanding and
maintenance of the authorization logic.
* **Separate Policy Management**: Authorization policies are defined in distinct
configuration resources, not directly in `EnvoyFilter`. This separation eases policy
management and facilitates updates or replacements of authorization logic without
altering `EnvoyFilter` configurations.
* **Seamless Integration with Istio**: `envoyExtAuthzHttp` harmonizes with Istio features
like `AuthorizationPolicy` and `VirtualService`, enabling smoother integration within
Istio's ecosystem and taking advantage of its architecture and capabilities.
* **Future-Proofing**: There is a high likelihood that Kubeflow's internal authentication
decisions will transition to relying directly on JWTs instead of custom auth headers.
Additional information on the benefits of moving away from `EnvoyFilter` can be found in these
resources:
* [Istio GitHub Issue #27790](https://github.com/istio/istio/issues/27790)
* [Istio Documentation on Authorization with Custom Authentication](https://istio.io/latest/docs/tasks/security/authorization/authz-custom/)
While `envoyExtAuthzHttp` could potentially integrate with `oidc-authservice`, `oauth2-proxy`
emerges as a more advanced authentication proxy. It boasts broader community support and is
widely used in the industry, including in the official Istio documentation on [External
Authorization](https://istio.io/latest/docs/tasks/security/authorization/authz-custom).
For more details on the `oauth2-proxy`, refer to the [official documentation](https://oauth2-proxy.github.io/oauth2-proxy/docs/behaviour).
## Available Components
Below is a list of the available Kustomize Components with brief descriptions. Click on each for more details.
* **[allow-unauthenticated-issuer-discovery](./allow-unauthenticated-issuer-discovery.md)** -
Creates a ClusterRoleBinding for anonymous access to Kubernetes OIDC
discovery.
* **[central-dashboard](./central-dashboard.md)** - Configures the central
dashboard to use oauth2-proxy logout URL.
* **[istio-external-auth](./istio-external-auth.md)** - Modifies Istio
configuration to define oauth2-proxy as external authentication middleware via
envoyExtAuthzHttp extension provider. Adds RequestAuthentication to trust Dex
as IdP and AuthorizationPolicies to delegate authentication to oauth2-proxy.
* **[istio-m2m](./istio-m2m.md)** - Creates RequestAuthentication for Istio to
trust the OIDC Issuer specified in parameters. This allows the generation of
JWTs for authenticating requests, typically as Bearer Tokens in the
Authorization header. By default, the OIDC Issuer is the in-cluster Kubernetes
OIDC.
## CloudFlare
CloudFlare requires that certain static, standard web browser assets are accessible without
user authentication. This is crucial because CloudFlare aims to cache these assets for
enhanced performance. If these assets necessitate user authentication, CloudFlare robots
will be redirected to the authentication page, potentially causing access issues with the
Kubeflow instance behind CloudFlare.
This issue can be resolved by defining a set of assets in the Istio `AuthorizationPolicy`
that do not require authentication. An example `AuthorizationPolicy` for this purpose is
provided in the file `authorizationpolicy.istio-ingressgateway-oauth2-proxy.cloudflare.yaml`.
## Explaining the Auth Routine
1. Istio is configured with the `envoyExtAuthzHttp` extension provider pointing to the
`oauth2-proxy` service. This configuration enables the use of this extension in
`AuthorizationPolicy` for adding external authorization to the service mesh.
2. The Istio service mesh has an `AuthorizationPolicy` named `istio-ingressgateway-oauth2-proxy`
in the `istio-system` (Istio root) namespace. This policy is set with `action: CUSTOM` and
specifies the `oauth2-proxy` provider. Consequently, every request to the
`istio-ingressgateway` must pass through the external authorization service, `oauth2-proxy`.
3. `oauth2-proxy` decides based on the cookie named `oauth2_proxy_kubeflow`. If this cookie
is absent, expired, or invalid, `oauth2-proxy` redirects to the configured OIDC provider,
typically `dex`. The authentication redirect includes:
* A `redirect_uri` for redirecting the user post-authentication,
* A code challenge to guard against interception and replay attacks,
* A state parameter to validate the authorization response's authenticity and
ensure it originates from the initial request.
Post-authentication, a cookie is set in the user's browser, used by Istio and `oauth2-proxy`
for authorizing requests.
`oauth2-proxy` also checks for an `Authorization` header with a JWT bearer token. It trusts
JWTs issued by the configured OIDC provider (default `dex`) and can be configured to trust
additional JWTs. If a valid JWT is present, `oauth2-proxy` forwards the request to Istio
along with the authorization header.
The key objective here is to supply an `Authorization` header with a JWT Bearer Token,
later used in `RequestAuthentication`. This step configures Istio to trust the JWT, parse
its claims to include user email and groups in custom Kubeflow authorization headers, and
make routing and authorization decisions based on these JWT claims.
4. With this setup, Istio always receives the JWT in requests, enabling authorization
decisions based on JWT claims.
## Using HTTPS
`oauth2-proxy` is initially set up with an `http` endpoint, secured by the Istio Service Mesh.
As a result, `oauth2-proxy` may default to assuming that the authentication redirect URI should
also use `http`. To enforce the use of `https`, modify the variable `FORCE_HTTPS` in
`kustomization.yaml` to `true`. This adjustment leverages the `oauth2-proxy` configuration
option `--cookie-secure`, ensuring redirection occurs with `https`.
## Istio JWT Public Key Refresh Interval
In the initial setup of Kubeflow, it's common for `istiod` to become available before `dex`.
Istio's `RequestAuthentication` is configured to retrieve the JWT Public Key from the Issuer
URL. If the Issuer is not yet operational, placeholder keys are set, which can render the
setup nonfunctional until Istio can access the correct JWT Public Key. To address this,
`istiod` is configured with the environment variable `PILOT_JWT_PUB_KEY_REFRESH_INTERVAL="1m"`.
This setting ensures the JWT Public Key is refreshed every minute, rather than the default
20 minutes.
Without this configuration, users may encounter the following Istio error:
```
Jwks doesn't have key to match kid or alg from Jwt
```
## Issues with This Setup
While not an inherent issue with Istio or `oauth2-proxy`, the current Kubeflow configuration
automatically redirects to a URL specified in the logout response body's `afterLogoutURL` key.
This behavior stems from custom integration with the `oidc-authservice` component. While
`oauth2-proxy` is capable of redirecting to the base Kubeflow page, this custom setup results
in users being logged out (with the authentication cookie removed) but not redirected back to
the Kubeflow Home Page.
Details of this custom integration are available at:
* [oidc-authservice server.go](https://github.com/arrikto/oidc-authservice/blob/0c4ea9a/server.go#L509)
* [Kubeflow logout-button.js](https://github.com/kubeflow/kubeflow/blob/c6c4492/components/centraldashboard/public/components/logout-button.js#L50)
To log in again, users must manually refresh the page.
## Example Installation
To install Kubeflow configured to use `oauth2-proxy` with Istio's `envoyExtAuthzHttp` extension,
make the following changes to the `example/kustomization.yaml` file:
* use `oauth2-proxy` overlay for istio-install
```
# from
- ../common/istio-1-24/istio-install/base
# to
- ../common/istio-1-24/istio-install/overlays/oauth2-proxy
```
* change `OIDC Authservice` to `oauth2-proxy for OIDC` and use overlay for m2m
bearer tokens with self-signed in-cluster issuer
```
# from
- ../common//oidc-authservice/base
# to
- ../common/oauth2-proxy/overlays/m2m-dex-and-kind
```
* change Dex overlay
```
# from
- ../common/dex/overlays/istio
# to
- ../common/dex/overlays/oauth2-proxy
* change Central Dashboard overlay to use oauth2-proxy for logout
```
# from
- ../apps/centraldashboard/upstream/overlays/kserve
# to
- ../apps/centraldashboard/manuel-patches/overlays/oauth2-proxy
```
All those changes combined can be done with this single command:
```diff
$ git apply <<EOF
diff --git a/example/kustomization.yaml b/example/kustomization.yaml
index c1a85789..4a50440c 100644
--- a/example/kustomization.yaml
+++ b/example/kustomization.yaml
@@ -38,11 +38,11 @@ resources:
# Istio
- ../common/istio-1-24/istio-crds/base
- ../common/istio-1-24/istio-namespace/base
-- ../common/istio-1-24/istio-install/base
-# OIDC Authservice
-- ../common//oidc-authservice/base
+- ../common/istio-1-24/istio-install/overlays/oauth2-proxy
+# oauth2-proxy for OIDC
+- ../common/oauth2-proxy/overlays/m2m-dex-and-kind
# Dex
-- ../common/dex/overlays/istio
+- ../common/dex/overlays/oauth2-proxy
# KNative
- ../common/knative/knative-serving/overlays/gateways
- ../common/knative/knative-eventing/base
@@ -60,7 +60,7 @@ resources:
# Katib
- ../apps/katib/upstream/installs/katib-with-kubeflow
# Central Dashboard
-- ../apps/centraldashboard/upstream/overlays/kserve
+- ../apps/centraldashboard/overlays
# Admission Webhook
- ../apps/admission-webhook/upstream/overlays/cert-manager
# Jupyter Web App
EOF
```
@@ -0,0 +1,43 @@
# Unauthenticated Issuer Discovery
If you are using Kubernetes with tools like kind, vCluster, minikube, or similar solutions for local
development, it's highly likely that the Kubernetes OIDC Issuer operates within the cluster and is
secured with self-signed certificates.
To facilitate the use of m2m tokens with `oauth2-proxy` and Istio, both tools must perform OIDC
Connect Discovery on the Token Issuer. Kubernetes offers OIDC Discovery functionality at a specific
URI:
```
https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
```
Access to this endpoint is blocked by default due to RBAC policies, but it can be enabled by
creating a `ClusterRoleBinding`. This binding associates the predefined `ClusterRole`
`system:service-account-issuer-discovery` with the `system:unauthenticated` group. The
configuration for this is detailed in the resource file `clusterrolebinding.unauthenticated-oidc-viewer.yaml`.
Once this step is completed, the endpoint can be accessed to reveal the Issuer URL:
```bash
$ curl -k https://kubernetes.default.svc.cluster.local/.well-known/openid-configuration
# Example output in kind:
{"issuer":"https://kubernetes.default.svc.cluster.local","jwks_uri":"https://172.18.0.5:6443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
# Example output in vCluster:
{"issuer":"https://kubernetes.default.svc.cluster.local","jwks_uri":"https://1.2.3.4:6443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
# Example output in AWS EKS:
{"issuer":"https://oidc.eks.region.amazonaws.com/id/123abc","jwks_uri":"https://ip-1-2-3-4.eu-central-1.compute.internal:443/openid/v1/jwks","response_types_supported":["id_token"],"subject_types_supported":["public"],"id_token_signing_alg_values_supported":["RS256"]}
```
If you're operating in a `vCluster`, access to the endpoint specified under `jwks_uri` (for example,
`https://1.2.3.4:6443/openid/v1/jwks`) is managed separately, and merely creating the previously
mentioned `ClusterRoleBinding` is insufficient. To circumvent this limitation, you can configure the
`kube-apiserver` to allow anonymous authentication by setting `--anonymous-auth=true`. This is
achieved by appending `--kube-apiserver-arg=anonymous-auth=true` to the list of arguments in the
Helm Chart Values file:
```yaml
vcluster:
extraArgs:
- --kube-apiserver-arg=anonymous-auth=true
```
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: unauthenticated-oidc-viewer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:service-account-issuer-discovery
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:unauthenticated
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- clusterrolebinding.unauthenticated-oidc-viewer.yaml
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
patches:
- path: patches/deployment.logout-url.yaml
@@ -0,0 +1,17 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: centraldashboard
namespace: kubeflow
spec:
template:
spec:
containers:
- name: centraldashboard
env:
# This successfully logs out the user but the user is not redirected to
# the home page.
# https://github.com/kubeflow/kubeflow/blob/c6c4492/components/centraldashboard/public/components/logout-button.js#L50
# Please refresh the page after logging out.
- name: LOGOUT_URL
value: /oauth2/sign_out
@@ -0,0 +1,88 @@
# the default JWKS endpoint for Kind is not public, and uses a self-signed certificate
# for the Istio RequestAuthentication to trust it, we need to proxy the cluster's JWKS endpoint over HTTP
apiVersion: v1
kind: ServiceAccount
metadata:
name: cluster-jwks-proxy
namespace: istio-system
labels:
app.kubernetes.io/name: cluster-jwks-proxy
---
apiVersion: v1
kind: Service
metadata:
name: cluster-jwks-proxy
namespace: istio-system
labels:
app.kubernetes.io/name: cluster-jwks-proxy
spec:
ports:
- name: http
port: 80
targetPort: http
selector:
app.kubernetes.io/name: cluster-jwks-proxy
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: cluster-jwks-proxy
namespace: istio-system
labels:
app.kubernetes.io/name: cluster-jwks-proxy
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: cluster-jwks-proxy
template:
metadata:
labels:
app.kubernetes.io/name: cluster-jwks-proxy
spec:
serviceAccountName: cluster-jwks-proxy
containers:
- name: kubectl-proxy
image: docker.io/bitnami/kubectl
securityContext:
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
runAsNonRoot: true
capabilities:
drop:
- ALL
ports:
- name: http
containerPort: 8080
startupProbe:
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 2
httpGet:
path: /openid/v1/jwks
port: http
livenessProbe:
initialDelaySeconds: 15
periodSeconds: 15
timeoutSeconds: 5
httpGet:
path: /openid/v1/jwks
port: http
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 15
timeoutSeconds: 5
httpGet:
path: /openid/v1/jwks
port: http
args:
- proxy
- --address=0.0.0.0
- --port=8080
## accept all hosts (default is local only)
- --accept-hosts=.*
## only accept requests to '/openid/v1/jwks' and '/.well-known/openid-configuration'
- --accept-paths=^(?:/openid/v1/jwks)|(?:/.well-known/openid-configuration)$
## reject all methods except 'GET'
- --reject-methods=^(POST|PUT|PATCH|DELETE|HEAD|OPTIONS|CONNECT|TRACE)$
@@ -0,0 +1,10 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- cluster-jwks-proxy.yaml
images:
- name: docker.io/bitnami/kubectl
newName: docker.io/bitnami/kubectl
newTag: 1.30.4
@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
patches:
- path: patches/cm.enable-oauth2-proxy.yaml
- path: patches/deployment.jwt-refresh-interval.yaml
@@ -0,0 +1,36 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
data:
mesh: |-
accessLogFile: /dev/stdout
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata: {}
tracing: {}
enablePrometheusMerge: true
rootNamespace: istio-system
tcpKeepalive:
interval: 5s
probes: 3
time: 10s
trustDomain: cluster.local
extensionProviders:
- envoyExtAuthzHttp:
headersToDownstreamOnDeny:
- content-type
- set-cookie
headersToUpstreamOnAllow:
- authorization
- path
- x-auth-request-email
- x-auth-request-groups
- x-auth-request-user
includeRequestHeadersInCheck:
- authorization
- cookie
service: oauth2-proxy.oauth2-proxy.svc.cluster.local
port: 80
name: oauth2-proxy
@@ -0,0 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: istiod
namespace: istio-system
spec:
template:
spec:
containers:
- name: discovery
env:
# Istio will refresh the JWT Public Keys provided with
# RequestAuthentication by default every 20 minutes. For deployment
# from scratch this is not ideal because there is a high chance that
# the istiod will be available before dex is available, triggering
# Istio mechanism to use a placeholder jwt until refreshed.
- name: PILOT_JWT_PUB_KEY_REFRESH_INTERVAL
value: "1m"
@@ -0,0 +1,34 @@
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: istio-ingressgateway-oauth2-proxy
namespace: istio-system
spec:
action: CUSTOM
provider:
name: oauth2-proxy
selector:
matchLabels:
app: istio-ingressgateway
rules:
# We ONLY authenticate requests that DON'T have an `Authorization` header using oauth2-proxy.
# This is because we use RequestAuthentication to authenticate requests with an `Authorization` header.
- when:
- key: request.headers[authorization]
notValues: ["*"]
to:
- operation:
notPaths:
# Exclude dex paths, otherwise users won't be able to log in.
- /dex/*
- /dex/**
- /oauth2/*
# Exclude paths which are safe to cache by Cloudflare.
- /favicon*
- /webcomponentsjs*
- /vendor.bundle.js
- /app.bundle.js
- /dashboard_lib.bundle.js
- /assets*
- /app.css
@@ -0,0 +1,25 @@
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: istio-ingressgateway-oauth2-proxy
namespace: istio-system
spec:
action: CUSTOM
provider:
name: oauth2-proxy
selector:
matchLabels:
app: istio-ingressgateway
rules:
# We ONLY authenticate requests that DON'T have an `Authorization` header using oauth2-proxy.
# This is because we use RequestAuthentication to authenticate requests with an `Authorization` header.
- when:
- key: request.headers[authorization]
notValues: ["*"]
to:
- operation:
notPaths:
# Exclude dex paths, otherwise users won't be able to log in.
- /dex/*
- /dex/**
- /oauth2/*
@@ -0,0 +1,33 @@
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: istio-ingressgateway-require-jwt
namespace: istio-system
spec:
action: DENY
selector:
matchLabels:
app: istio-ingressgateway
rules:
# Deny requests that don't have a verified JWT (from a RequestAuthentication)
# Note, even user requests that have been authenticated by oauth2-proxy will have a JWT,
# because oauth2-proxy injects a Dex JWT into the request.
- from:
- source:
notRequestPrincipals: ["*"]
to:
- operation:
notPaths:
# Exclude dex paths, otherwise users won't be able to log in.
- /dex/*
- /dex/**
- /oauth2/*
# Exclude paths which are safe to cache by Cloudflare.
- /favicon*
- /webcomponentsjs*
- /vendor.bundle.js
- /app.bundle.js
- /dashboard_lib.bundle.js
- /assets*
- /app.css
@@ -0,0 +1,24 @@
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: istio-ingressgateway-require-jwt
namespace: istio-system
spec:
action: DENY
selector:
matchLabels:
app: istio-ingressgateway
rules:
# Deny requests that don't have a verified JWT (from a RequestAuthentication)
# Note, even user requests that have been authenticated by oauth2-proxy will have a JWT,
# because oauth2-proxy injects a Dex JWT into the request.
- from:
- source:
notRequestPrincipals: ["*"]
to:
- operation:
notPaths:
# Exclude dex paths, otherwise users won't be able to log in.
- /dex/*
- /dex/**
- /oauth2/*
@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- authorizationpolicy.istio-ingressgateway-oauth2-proxy.yaml
- authorizationpolicy.istio-ingressgateway-require-jwt.yaml
- requestauthentication.dex-jwt.yaml
# If want to enable caching for some paths (e.g. when using Cloudflare),
# use the following AuthorizationPolicies instead of the default ones.
#- authorizationpolicy.istio-ingressgateway-oauth2-proxy.cloudflare.yaml
#- authorizationpolicy.istio-ingressgateway-require-jwt.cloudflare.yaml
@@ -0,0 +1,44 @@
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: dex-jwt
namespace: istio-system
spec:
# we only apply to the ingress-gateway because:
# - there is no need to verify the same tokens at each sidecar
# - having no selector will apply to the RequestAuthentication to ALL
# Pods in the mesh, even ones which are not part of Kubeflow
# - some Kubeflow services accept direct connections with Kubernetes JWTs,
# and we don't want to require that users configure Istio to verify Kubernetes JWTs
# as there is no method to do this which works on all distributions.
selector:
matchLabels:
app: istio-ingressgateway
jwtRules:
- issuer: http://dex.auth.svc.cluster.local:5556/dex
# `forwardOriginalToken` is not strictly required to be true.
# there are pros and cons to each value:
# - true: the original token is forwarded to the destination service
# which raises the risk of the token leaking
# - false: the original token is stripped from the request
# which will prevent the destination service from
# verifying the token (possibly with its own RequestAuthentication)
forwardOriginalToken: true
# This will unpack the JWTs issued by dex into the expected headers.
# It is applied to BOTH the m2m tokens from outside the cluster (which skip
# oauth2-proxy because they already have a dex JWT), AND user requests which were
# authenticated by oauth2-proxy (which injected a dex JWT).
outputClaimToHeaders:
- header: kubeflow-userid
claim: email
- header: kubeflow-groups
claim: groups
# We explicitly set `fromHeaders` to ensure that the JWT is only extracted from the `Authorization` header.
# This is because we exclude requests that have an `Authorization` header from oauth2-proxy.
fromHeaders:
- name: Authorization
prefix: "Bearer "
@@ -0,0 +1,13 @@
# Kubernetes M2M Authentication with Istio and RequestAuthentication
## Overview
This kustomize component enables M2M (Machine-to-Machine) authentication in Kubernetes, using
Istio and the `RequestAuthentication` object. It configures Istio to trust JWTs (JSON Web Tokens)
in Authorization Bearer tokens when the JWT issuer matches the one in `RequestAuthentication`. The
default setup uses Kubernetes' self-served OIDC issuer with self-signed certificates.
In Kubernetes clusters managed by platform providers, the OIDC issuer is usually managed by the
provider and served behind publicly trusted certificates. In these cases, it's advisable to use
the platform-managed Kubernetes OIDC issuer in the `RequestAuthentication` for seamless integration
and authentication compliance with the platform's security standards.
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- requestauthentication.yaml
@@ -0,0 +1,42 @@
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: m2m-token-issuer
namespace: istio-system
spec:
# we only apply to the ingress-gateway because:
# - there is no need to verify the same tokens at each sidecar
# - having no selector will apply the RequestAuthentication to ALL
# Pods in the mesh, even ones which are not part of Kubeflow
selector:
matchLabels:
app: istio-ingressgateway
jwtRules:
- # The `issuer` must be replaced with a Kustomize patch.
issuer: PATCH_ME
# `forwardOriginalToken` is not strictly required to be true.
# there are pros and cons to each value:
# - true: the original token is forwarded to the destination service
# which raises the risk of the token leaking
# - false: the original token is stripped from the request
# which will prevent the destination service from
# verifying the token (possibly with its own RequestAuthentication)
forwardOriginalToken: true
# This will unpack the JWTs issued by Kubernetes into the expected headers.
outputClaimToHeaders:
- header: kubeflow-userid
claim: sub
- # NOTE: K8S SA Tokens (e.g. those created with `kubectl create token`) do not contain a `groups` claim,
# but we need to ensure that any groups header provided by the request is overwritten to avoid
# users passing a valid JWT with `kubeflow-groups` header to impersonate other users.
header: kubeflow-groups
claim: groups
# We explicitly set `fromHeaders` to ensure that the JWT is only extracted from the `Authorization` header.
# This is because we exclude requests that have an `Authorization` header from oauth2-proxy.
fromHeaders:
- name: Authorization
prefix: "Bearer "
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 636 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB