From a56df7fe85514f097192437c3a103f6a99c94804 Mon Sep 17 00:00:00 2001 From: Cyber Nagle Date: Mon, 21 Oct 2024 17:47:27 +0800 Subject: [PATCH] feat: add doc to describe use oauth2proxy directly. (#2884) * feat: add doc to describe use oauth2proxy directly. Signed-off-by: Cyber Nagle * fix: typos for OAuth2 Proxy doc. Signed-off-by: Cyber Nagle * feat: move oauth2 proxy doc to common/oauth2-proxy/README.md. Signed-off-by: Cyber Nagle * rephrasing and consolidating Signed-off-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com> * remove outdated documentation Signed-off-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com> * further documentation improvements Signed-off-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com> --------- Signed-off-by: Cyber Nagle Signed-off-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com> Co-authored-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com> --- README.md | 38 ++++------- common/oauth2-proxy/README.md | 65 ++++++++++++++----- .../oauth2-proxy/components/oauth2-flow.svg | 13 ++++ 3 files changed, 73 insertions(+), 43 deletions(-) create mode 100644 common/oauth2-proxy/components/oauth2-flow.svg diff --git a/README.md b/README.md index cefcc3ac25..6743c64a44 100755 --- a/README.md +++ b/README.md @@ -220,7 +220,8 @@ kubectl wait --for=condition=Ready pods --all -n istio-system --timeout 300s #### Oauth2-proxy -The oauth2-proxy extends your Istio Ingress-Gateway capabilities, to be able to function as an OIDC client: +The oauth2-proxy extends your Istio Ingress-Gateway capabilities, to be able to function as an OIDC client. +It supports user sessions as well as proper token-based machine to machine authentication. ```sh echo "Installing oauth2-proxy..." @@ -234,19 +235,20 @@ echo "Installing oauth2-proxy..." kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl apply -f - kubectl wait --for=condition=ready pod -l 'app.kubernetes.io/name=oauth2-proxy' --timeout=180s -n oauth2-proxy -# Option 2: works on Kind/K3D clusters, and allows K8s service account tokens to be used -# from outside the cluster via the Istio ingress-gateway. +# Option 2: works on Kind/K3D and other clusters with the proper configuration, and allows K8s service account tokens to be used +# from outside the cluster via the Istio ingress-gateway. For example for automation with github actions. # #kustomize build common/oauth2-proxy/overlays/m2m-dex-and-kind/ | kubectl apply -f - #kubectl wait --for=condition=ready pod -l 'app.kubernetes.io/name=oauth2-proxy' --timeout=180s -n oauth2-proxy #kubectl wait --for=condition=ready pod -l 'app.kubernetes.io/name=cluster-jwks-proxy' --timeout=180s -n istio-system ``` -It supports user sessions as well as proper token-based machine to machine authentication. +If you want to use OAuth2 Proxy without Dex and conenct it directly to your own IDP, you can refer to this [document](common/oauth2-proxy/README.md#change-default-authentication-from-dex--oauth2-proxy-to-oauth2-proxy-only). But you can also keep Dex and extend it with connectors to your own IDP. +TODO: rough guidance on how to connect Dex to a generic IDP with OIDC. #### Dex -Dex is an OpenID Connect Identity (OIDC) with multiple authentication backends. In this default installation, it includes a static user with email `user@example.com`. By default, the user's password is `12341234`. For any production Kubeflow deployment, you should change the default password by following [the relevant section](#change-default-user-password). +Dex is an OpenID Connect (OIDC) identity provider with multiple authentication backends. In this default installation, it includes a static user with email `user@example.com`. By default, the user's password is `12341234`. For any production Kubeflow deployment, you should change the default password by following [the relevant section](#change-default-user-password). Install Dex: @@ -255,7 +257,7 @@ echo "Installing Dex..." kustomize build common/dex/overlays/oauth2-proxy | kubectl apply -f - kubectl wait --for=condition=ready pods --all --timeout=180s -n auth ``` - + #### Knative Knative is used by the KServe official Kubeflow component. @@ -321,27 +323,7 @@ Install the [Multi-User Kubeflow Pipelines](https://www.kubeflow.org/docs/compon ```sh kustomize build apps/pipeline/upstream/env/cert-manager/platform-agnostic-multi-user | kubectl apply -f - ``` -This installs argo with the runasnonroot emissary executor. Please note that you are still responsible to analyze the security issues that arise when containers are run with root access and to decide if the kubeflow pipeline main containers are run as runasnonroot. It is in general strongly recommended that all user-accessible OCI containers run with Pod Security Standards [restricted] -(https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted) - -**Multi-User Kubeflow Pipelines dependencies** - -* Istio -* Kubeflow Roles -* OIDC Auth Service (or cloud provider specific auth service) -* Profiles + KFAM - -**Alternative: Kubeflow Pipelines Standalone** - -You can install [Kubeflow Pipelines Standalone](https://www.kubeflow.org/docs/components/pipelines/installation/standalone-deployment/) which - -* does not support multi user separation -* has no dependencies on the other services mentioned here - -You can learn more about their differences in [Installation Options for Kubeflow Pipelines -](https://www.kubeflow.org/docs/components/pipelines/installation/overview/). - -Besides installation instructions in Kubeflow Pipelines Standalone documentation, you need to apply two virtual services to expose [Kubeflow Pipelines UI](https://github.com/kubeflow/pipelines/blob/1.7.0/manifests/kustomize/base/installs/multi-user/virtual-service.yaml) and [Metadata API](https://github.com/kubeflow/pipelines/blob/1.7.0/manifests/kustomize/base/metadata/options/istio/virtual-service.yaml) in kubeflow-gateway. +This installs argo with the runasnonroot emissary executor. Please note that you are still responsible to analyze the security issues that arise when containers are run with root access and to decide if the kubeflow pipeline main containers are run as runasnonroot. It is in general strongly recommended that all user-accessible OCI containers run with Pod Security Standards [restricted](https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted). #### KServe @@ -559,6 +541,8 @@ For example, running the above command locally with required packages like _pass 4. Try to login using the new dex password. + + ## Upgrading and extending For modifications and in place upgrades of the Kubeflow platform we provide a rough description for advanced users: diff --git a/common/oauth2-proxy/README.md b/common/oauth2-proxy/README.md index 2110e0b7a0..3ebe06c273 100644 --- a/common/oauth2-proxy/README.md +++ b/common/oauth2-proxy/README.md @@ -1,17 +1,5 @@ # Kubeflow Authentication using Oauth2 Proxy -## Istio Envoy Filter - -> EnvoyFilter provides a mechanism to customize the Envoy configuration generated by Istio Pilot. Use EnvoyFilter to modify values for certain fields, add specific filters, or even add entirely new listeners, clusters, etc.[^1] - -Kubeflow will use an Envoy Filter for every incoming request when is used -with `oidc-authservice`. - -Usage of EnvoyFilter is currently not recommended. The preferred method for configuring External -Authentication in Istio is the `envoyExtAuthzHttp` extension provider[^2]. - -Envoy Filter is set up with [oidc-authservice](https://github.com/arrikto/oidc-authservice). - ## Istio envoyExtAuthzHttp This is Istio's recommended approach for External Authorization[^2]. It is not limited to the use @@ -20,11 +8,11 @@ current and foreseeable authentication needs. ## Kubeflow Pipelines User and M2M Authentication and Authorization -Kubeflow Pipelines component relies on the built-in kubernetes functionalities to authenticate and authorize +The Kubeflow Pipelines component relies on the built-in kubernetes functionalities to authenticate and authorize user requests, specifically the TokenReviews[^4] and SubjectAccessReview[^5]. The best way to describe how it works is to explain with an example. Lets analyze the flow -when client calls API to list the KF Pipeline Runs: +when a client calls the API to list the KF Pipeline runs: 1. api-server starts endpoints in: @@ -76,10 +64,55 @@ when client calls API to list the KF Pipeline Runs: {} # empty response which is fine because no pipeline runs exist ``` -### Auth analysis diagram for Kubeflow Pipelines - +### Authentication and Authorization analysis diagram for Kubeflow Pipelines ![Kubeflow Auth Diagram](./components/kubeflow_auth_diagram.svg) +### Change the default authentication from "Dex + Oauth2-proxy" to "Oauth2-proxy" only + +The authentication in Kubeflow evolved over time and we dropped envoyfilters and oidc-authservice in favor of RequestAuthentication and Oauth2-proxy in Kubeflow 1.9. +![auth-flow](components/oauth2-flow.svg) + +You can adjust OAuth2 Proxy to directly connect to your own IDP(Identity Provider) suchg as GCP, [AWS](https://docs.aws.amazon.com/cognito/latest/developerguide/federation-endpoints-oauth-grants.html), Azure etc: + +1. Create an application on your IdP (purple line) +2. Change your [OAuth2 Proxy issuer](https://github.com/kubeflow/manifests/blob/35539f162ea7fafc8c5035d8df0d8d8cf5a9d327/common/oauth2-proxy/base/oauth2-proxy-config.yaml#L10) to your IdP. Of course never ever directly, but with kustomize overlays and components. +3. In the istio-system namespace is a RequestAuthentication resource. You need to change its issuer to your own IdP, or even better create an additional one. +4. You can now directly issue a token from your IdP and use this token to access your Kubeflow platform. + +This feature is useful when you need to integrate kubeflow with you current CI/CD platform (GitHub Actions, Jenkins) via machine-to-machine authentication. + +Example for obtaining and using a JWT token From your IDP: +``` +import requests +token_url = "https://your-idp.com/oauth/token" +client_id = "YOUR_CLIENT_ID" +client_secret = "YOUR_CLIENT_SECRET" +username = "YOUR_USERNAME" +password = "YOUR_PASSWORD" +# request header +headers = { + "Content-Type": "application/x-www-form-urlencoded" +} +data = { + "grant_type": "password", + "client_id": client_id, + "client_secret": client_secret, + "username": username, + "password": password, + "scope": "openid profile email" #change your scope +} +response = requests.post(token_url, headers=headers, data=data) +TOKEN = response.json()['access_token'] +``` + +``` +import kfp +kubeflow_host="https://your_host" +pipeline_host = kubeflow_host + "/pipeline" +client = kfp.Client(host=pipeline_host, existing_token=TOKEN) +print(client.list_runs(namespace="your-profile-name")) +``` + ## Kubeflow Notebooks User and M2M Authentication and Authorization The underlying mechanism is the same as in Kubeflow Pipelines. diff --git a/common/oauth2-proxy/components/oauth2-flow.svg b/common/oauth2-proxy/components/oauth2-flow.svg new file mode 100644 index 0000000000..eee8551ada --- /dev/null +++ b/common/oauth2-proxy/components/oauth2-flow.svg @@ -0,0 +1,13 @@ + + + + + + + + istio ingress gatewaydexenvoy filteroauth2proxyauth policyIdentityProviderbefore kubeflow 1.8kubeflow 1.9 with oauth2 proxydirectly use oauth2 proxy \ No newline at end of file