Authentication

Charmed Kubeflow uses Dex for authentication. Dex allows for pluggable authentication against many different identity providers, while presenting a unified OpenId Connect (OIDC) interface.

Auth Flow

The authentication flow for an unauthenticated request consists of these steps:

  • User makes an unauthenticated request
    • Redirected to /dex
  • User logs in via Dex
  • Redirected to gatekeeper callback endpoint
    • Sets a cookie with auth token for future requests
  • Redirected back to original page, with authorization token

Unauthenticated Request

The flow of an unauthenticated request is shown here:

dex-unauthenticated

  • A user makes a request that goes through Ambassador
  • Ambassador checks with the gatekeeper service before allowing any request to go through
  • The gatekeeper service responds to Ambassador that the request is unauthenticated, and a redirect URL
  • Ambassador returns an HTTP 301 redirecting user to Dex

Logging In

dex-login

  • User makes request to /dex
  • Ambassador is configured to not check with the gatekeeper for requests to /dex
  • Dex presents a login page to the user
  • The user submits their credentials
  • Dex uses the configured connector to authenticate the user against an external auth service
    • Dex may also be configured with basic username/password support. This is the default in Charmed Kubeflow.
    • See the dex configuration section for more information on how to configure Dex with other connectors.
  • Dex redirects the user to a callback URL managed by the gatekeeper

Receive Token

dex-callback

  • User makes request to callback URL
  • Ambassador sends request to gatekeeper service
  • Gatekeeper service generates JWT token in the Set-Cookie response header

Authenticated Request

dex-authenticated

  • User makes authenticated request
  • Ambassador checks with the gatekeeper service to see if request is authenticated
  • Gatekeeper service affirms request is authenticated by looking at JWT token
  • Ambassador communicates with Kubeflow service for requested endpoint
  • Ambassador returns requested endpoint to user

Configuring Dex

Dex presents a unified OIDC interface that is capable of authenticating against many different backend authentication services. See the Dex README section on Connectors for a complete list.

By default, Dex is configured with a basic username/password combo. These values can be displayed with:

juju config dex-auth static-username
juju config dex-auth static-password

If you would like to configure dex to use a different connector, start by disabling the default username/password:

juju config dex-auth static-username='' static-password=''

Then, configure the connectors you wish to use:

juju config dex-auth connectors="$CONNECTOR_YAML"

Where $CONNECTOR_YAML is a YAML list of connector configurations. The complete list of available connector configurations can be found here:

https://dexidp.io/docs/connectors/

As an example connector configuration, this is what you might use for $CONNECTOR_YAML to configure Dex to authenticate against an OpenLDAP server:

[{
    "id": "ldap",
    "name": "OpenLDAP",
    "type": "ldap",
    "config": {
        "bindDN": "cn=admin,dc=example,dc=org",
        "bindPW": "admin",
        "groupSearch": {
            "baseDN": "cn=admin,dc=example,dc=org",
            "filter": "",
            "groupAttr": "DN",
            "nameAttr": "cn",
            "userAttr": "DN"
        },
        "host": "ldap-service.auth.svc.cluster.local:389",
        "insecureNoSSL": true,
        "userSearch": {
            "baseDN": "cn=admin,dc=example,dc=org",
            "emailAttr": "DN",
            "filter": "",
            "idAttr": "DN",
            "nameAttr": "cn",
            "username": "cn"
        },
        "usernamePrompt": "Email Address"
    }
}]
'
1 Like

change the available connectors github url

The connector configuration is described as a YAML, but the example below is JSON. Please align both of them to be in the same format. Additionally, if the expected format is JSON, please adjust the charm config description - there is explicitly written that YAML is supported.

YAML is a superset of JSON, so the example is technically still YAML (but agreed, it is in the form most anyone would call JSON rather than YAML). I won’t change the example above as it is technically valid, but to clarify the situation both YAML and JSON will work in this config. Note though that the config is asking for the list of connectors to put inside the Dex connectors config (example here), not the entire connectors: [ ... ] key value pair. So the pure YAML equivalent to the example above would be:

- id: ldap
  name: OpenLDAP
  type: ldap
  config:
    bindDN: cn=admin,dc=example,dc=org
    bindPW: admin
    groupSearch:
      baseDN: cn=admin,dc=example,dc=org
      filter: ''
      groupAttr: DN
      nameAttr: cn
      userAttr: DN
    host: ldap-service.auth.svc.cluster.local:389
    insecureNoSSL: true
    userSearch:
      baseDN: cn=admin,dc=example,dc=org
      emailAttr: DN
      filter: ''
      idAttr: DN
      nameAttr: cn
      username: cn
    usernamePrompt: Email Address