Skip to content

Commit

Permalink
docs: Add guide for Dex and Keycloak (kubeflow#3012)
Browse files Browse the repository at this point in the history
* Add guide for Dex and Keycloak

Signed-off-by: WOOYOUNG SEO <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>

* Update README.md

Signed-off-by: Julius von Kohout <[email protected]>
Signed-off-by: WOOYOUNG SEO <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>

* Rename common/README.md to common/dex/README.md

Signed-off-by: Julius von Kohout <[email protected]>
Signed-off-by: 서우영 책임 Architect AI 아키텍처팀 ([email protected] <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>

* Update README.md

Signed-off-by: Julius von Kohout <[email protected]>
Signed-off-by: 서우영 책임 Architect AI 아키텍처팀 ([email protected] <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>

---------

Signed-off-by: WOOYOUNG SEO <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>
Signed-off-by: Julius von Kohout <[email protected]>
Signed-off-by: wooyoung85 <[email protected]>
Signed-off-by: 서우영 책임 Architect AI 아키텍처팀 ([email protected] <[email protected]>
Co-authored-by: Julius von Kohout <[email protected]>
  • Loading branch information
wooyoung85 and juliusvonkohout authored Feb 25, 2025
1 parent 27eb1a5 commit 2f332cd
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ data:
#- groups # groups might be used in the future
```
For Keycloak we have rough guidelines in <https://github.com/kubeflow/manifests/blob/master/common/dex/README.md>.
#### Knative
Knative is used by the KServe official Kubeflow component.
Expand Down
191 changes: 191 additions & 0 deletions common/dex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# Kubeflow Dex & Keycloak Integration Guide

In addition to the guidelines for GitHub, Google, Microsoft and other OIDC providers in https://github.com/kubeflow/manifests#dex and direct oauth2-proxy connection without DEX to typical OIDC IDP providers such as Azure in https://github.com/kubeflow/manifests/blob/master/common/oauth2-proxy/README.md#change-the-default-authentication-from-dex--oauth2-proxy-to-oauth2-proxy-only we try to roughly explain here how to configure Dex to use Keycloak as an external OpenID Connect provider for Kubeflow.

> [Note]
> ✅ Replace the domains of Keycloak and Kubeflow containing `example.com` with ones that are appropriately tailored to the actual situation.
> ✅ If a realm already exists, there's no need to create one.
> ✅ As you know, If the first attempt fails, you can just run it again.
## Configure Keycloak

### Create a Realm

- Realm Name: `<my-realm>`

### Create a Client
- Client Type: `OpenID Connect`
- Client ID: `kubeflow-oidc-authservice` (⚠️ Never use a different value)
- Client Authentication: `On`
- Authentication Flow: Check `Standard flow` and `Direct access grants`
- Root URL: `https://kubeflow.example.com`
- Home URL: `https://kubeflow.example.com`
- Valid Redirect URIs: `https://kubeflow.example.com/dex/callback`
- Valid Post Logout Redirect URIs: `https://kubeflow.example.com/oauth2/sign_out`
- Web Origins: `*`

After creating the realm and client, note down the **Client Secret**(`YOUR_KEYCLOAK_CLIENT_SECRET`) which will be used in later steps.

## Update Dex Configuration

Modify the Dex ConfigMap to connect to Keycloak.

```bash
KEYCLOAK_ISSUER="https://keycloak.example.com/realms/<my-realm>"
CLIENT_ID="kubeflow-oidc-authservice"
CLIENT_SECRET="<YOUR_KEYCLOAK_CLIENT_SECRET>"
REDIRECT_URI="https://kubeflow.example.com/dex/callback"
DEX_ISSUER="https://kubeflow.example.com/dex"


tee common/dex/overlays/oauth2-proxy/config-map.yaml <<- DEX_CONFIG
apiVersion: v1
kind: ConfigMap
metadata:
name: dex
data:
config.yaml: |
issuer: $DEX_ISSUER
storage:
type: kubernetes
config:
inCluster: true
web:
http: 0.0.0.0:5556
logger:
level: "debug"
format: text
oauth2:
skipApprovalScreen: true
enablePasswordDB: false
# staticPasswords:
# - email: [email protected]
# hashFromEnv: DEX_USER_PASSWORD
# username: user
# userID: "15841185641784"
staticClients:
- idEnv: OIDC_CLIENT_ID
redirectURIs: ["/oauth2/callback"]
name: 'Dex Login Application'
secretEnv: OIDC_CLIENT_SECRET
connectors:
- type: oidc
id: keycloak
name: keycloak
config:
issuer: $KEYCLOAK_ISSUER
clientID: $CLIENT_ID
clientSecret: $CLIENT_SECRET
redirectURI: $REDIRECT_URI
insecure: false
insecureSkipEmailVerified: true
userNameKey: email
scopes:
- openid
- profile
- email
- offline_access
DEX_CONFIG


kustomize build common/dex/overlays/oauth2-proxy | kubectl delete -f -
kustomize build common/dex/overlays/oauth2-proxy | kubectl apply -f -
```

## Update OAuth2 Proxy Configuration
Configure the OAuth2 Proxy to use the newly configured Dex issuer.

```bash
DEX_ISSUER="https://kubeflow.example.com/dex"

tee common/oauth2-proxy/base/oauth2_proxy.cfg <<- OAUTH2_PROXY_CONFIG
provider = "oidc"
oidc_issuer_url = "$DEX_ISSUER"
scope = "profile email offline_access openid"
email_domains = "*"
insecure_oidc_allow_unverified_email = "true"
upstreams = [ "static://200" ]
skip_auth_routes = [
"^/dex/",
]
api_routes = [
"/api/",
"/apis/",
"^/ml_metadata",
]
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"
skip_provider_button = false
provider_display_name = "Dex"
custom_sign_in_logo = "/custom-theme/kubeflow-logo.svg"
banner = "-"
footer = "-"
prompt = "none"
set_authorization_header = true
set_xauthrequest = true
cookie_name = "oauth2_proxy_kubeflow"
cookie_expire = "24h"
cookie_refresh = 0
code_challenge_method = "S256"
redirect_url = "/oauth2/callback"
relative_redirect_url = true
OAUTH2_PROXY_CONFIG


kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl delete -f -
kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl apply -f -
```

## Update Istio Request Authentication
Adjust the Istio Request Authentication configuration to pass the correct JWT claims.

```bash
DEX_ISSUER="https://kubeflow.example.com/dex"

tee common/oauth2-proxy/components/istio-external-auth/requestauthentication.dex-jwt.yaml <<- ISTIO_REQUEST_AUTH_CONFIG
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: dex-jwt
namespace: istio-system
spec:
selector:
matchLabels:
app: istio-ingressgateway
jwtRules:
- issuer: $DEX_ISSUER
forwardOriginalToken: true
outputClaimToHeaders:
- header: kubeflow-userid
claim: email
- header: kubeflow-groups
claim: groups
fromHeaders:
- name: Authorization
prefix: "Bearer "
ISTIO_REQUEST_AUTH_CONFIG


# For Kubeflow 1.91, change istio-1-24 to istio-1-22
kustomize build common/istio-1-24/istio-install/overlays/oauth2-proxy | kubectl delete -f -
kustomize build common/istio-1-24/istio-install/overlays/oauth2-proxy | kubectl apply -f -
kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl delete -f -
kustomize build common/oauth2-proxy/overlays/m2m-dex-only/ | kubectl apply -f -
```

## Final Checks
- **Review Logs**: Make sure to tail the logs of the Dex, OAuth2 Proxy, and Istio ingress gateway deployments to verify that the configurations are working as expected.
- **Test Authentication**: Try accessing your Kubeflow endpoint (ex. https://kubeflow.example.com) and verify that you’re redirected to Keycloak for authentication and that after login you are correctly returned to Kubeflow.

0 comments on commit 2f332cd

Please sign in to comment.