Skip to content

Commit

Permalink
feat: add doc to describe use oauth2proxy directly. (#2884)
Browse files Browse the repository at this point in the history
* feat: add doc to describe use oauth2proxy directly.

Signed-off-by: Cyber Nagle <nagle.zhang@qq.com>

* fix: typos for OAuth2 Proxy doc.

Signed-off-by: Cyber Nagle <nagle.zhang@qq.com>

* feat: move oauth2 proxy doc to common/oauth2-proxy/README.md.

Signed-off-by: Cyber Nagle <nagle.zhang@qq.com>

* 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 <nagle.zhang@qq.com>
Signed-off-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com>
Co-authored-by: juliusvonkohout <45896133+juliusvonkohout@users.noreply.github.com>
  • Loading branch information
cybernagle and juliusvonkohout authored Oct 21, 2024
1 parent fd176a1 commit a56df7f
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 43 deletions.
38 changes: 11 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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..."
Expand All @@ -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:

Expand All @@ -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.
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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:
Expand Down
65 changes: 49 additions & 16 deletions common/oauth2-proxy/README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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:

Expand Down Expand Up @@ -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.
Expand Down
Loading

0 comments on commit a56df7f

Please sign in to comment.