192 lines
5.9 KiB
Markdown
192 lines
5.9 KiB
Markdown
# 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: user@example.com
|
||
# 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.
|