Skip to content

Latest commit

 

History

History
191 lines (155 loc) · 5.9 KB

README.md

File metadata and controls

191 lines (155 loc) · 5.9 KB

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.

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.

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.

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.