You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
10 KiB
216 lines
10 KiB
# 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
|
|
```
|
|
|