This guide describes how authentication works in Charmed Kubeflow (CKF).
All CKF applications and services, including the Kubeflow central dashboard, are centrally exposed through a single ingress, which can also be configured for TLS. Since these applications can modify resources in the underlying Kubernetes (K8s) cluster, they require users to be logged in and authenticated to enable proper authorization checks.
Authentication is handled by configuring the central ingress to enforce request authentication via the OIDC flow. If a request is unauthenticated, the user is redirected to log in. This ensures that access to all CKF applications and resources is restricted to authenticated users.
Components
Authentication in CKF leverages three components:
- An Identity Provider (IdP), which stores and manages digital identities. It is implemented by the
dex-authcharm. Also referred to as OpenID Connect (OIDC) provider. - An OIDC client, which requests tokens for authentication. It is implemented by the
oidc-gatekeepercharm. Also referred to asAuthService. - An ingress, which manages external access to your Kubernetes cluster’s services. It is implemented by the
istio-ingressgatewayandistio-pilotcharms, both needed to configure theistio-gatewaycharm.
These three components participate in the OIDC flow:
Some important aspects to highlight:
- The Istio Gateway is configured by an EnvoyFilter, which enforces authentication by forwarding every request made to the Gateway to an AuthService (
oidc-gatekeeper).
- The
EnvoyFiltertemplate is rendered and applied byistio-pilotwhen integrated withoidc-gatekeepervia theingress-authinterface where the latter provides the following data:
service - oidc-gatekeeper: service name to forward all ingress traffic to.port: port of theservice - oidc-gatekeeper.allowed-request-headers: a list of allowed headers to configure theEnvoyFilter authorisation_requestvalue, which is always set to:
"allowed-request-headers": [
"cookie",
"X-Auth-Token",
],
allowed-response-headers: a list of allowed headers to configure theEnvoyFilter authorisation_responsevalue, which is always set to:
"allowed-response-headers": ["kubeflow-userid"]
userIDheaders are added by theAuthServiceto the original request and are used later in the authorisation process.- Dex has a built-in connector that allows the creation of static users. In CKF, this is used for easy access to the dashboard and in development and testing scenarios.
Programmatic access with the ingress and AuthService can be configured. See this guide for more details.
CKF ingress
The following diagram showcases the CKF ingress flow:
- A user request from outside the cluster is sent, targeting
component-a. - The request is first intercepted by a
LoadBalancer, only if set up, or theServicethat is right at the edge of the Istio Service Mesh. - The request is forwarded to the
Istio Ingress Gateway, this is theistio-ingressgateway Service. - The request reaches the
istio-ingressgatewayPod at the listening port, which is configured by theGatewayresource. See Gateway for more details. - The route from the
istio-ingressgatewayPod to the desired component is configured by aVirtualService. See VirtualService for more details.
This flow does not consider authentication and authorisation.
Some important aspects to highlight:
- A
Gatewaygets created automatically by theistio-pilotcharm. TheGatewayCustom Resource (CR) configures the traffic received by theistio-ingressgateway-xxxxPod with:servers.hosts: exposed by the Gateway and re-routed to their respective hosts based on the request.- TLS: when enabled either via the integration of a TLS certificate provider charm or passing
certandkeyvalues via a Juju secret. See this guide for more details.
The Gateway template is rendered and applied by the istio-pilot charm.
VirtualServicesare created to define a set of traffic routes to apply when a host is addressed. In the picture above, whenever a request handled by thekubeflow-gatewaycontainscomponent-ain the request, it gets routed to thecomponent-aServicebased on theVirtualServicerouting rules.
A charm that requires a VirtualService, for instance, jupyter-ui or kfp-ui, integrates with istio-pilot via the ingress interface.
The ingress interface is not the same as this ingress interface.
The requirer charm shares the following data:
prefix: prefix-based URI to match.rewrite: used to rewrite the prefix portion of the URI.service: theServiceused as the destination of the request.port: the port of theServiceused as the destination.
The VirtualService template is rendered and applied by the istio-pilot charm in the namespace where Istio is deployed. The VirtualService always uses the kubeflow-gateway as the spec.gateways value. This is not configurable.
- Kubeflow utilises path-based routing for reaching inside each components APIs, so most components expect the requests to have the format
/<rewrite>/<some>/<route>, meaning that the request should be forwarded to the component without being prefixed with anything different than what’s defined in theVirtualService. For example:
curl -v [kubeflow.io/pipeline](http://kubeflow.io/pipelines) -H <some header>
# or from browser [kubeflow.io/pipeline](http://kubeflow.io/pipelines)
# Should be routed as
GET /pipeline/ -H <some header>
- The
istio-ingressgatewayDeploymentandServiceare created by theistio-gatewaycharm.