Logging in to Kubeflow programmatically

Bhagat Khemchandani
2 min readSep 16, 2021

--

Recently I have been working with Kubeflow pipelines for orchestrating machine learning workflows. This involves setting up kubeflow on a Kubernetes cluster and defining pipelines.

Out of the box, kubeflow comes with Dex OpenID Connect Identity (OIDC) for authenticating users. You need to be logged in to Dex before interacting with Kubeflow APIs.

As for my use case, it was a requirement to interact with kubeflow programmatically, and invoke pipelines as desired.

Although logging in to Kubeflow from browser is really straightforward, it is slightly complicated when it comes to logging in programmatically as it involves several redirections in the authentication flow.

Here are the steps to login using curl

1) CLUSTER_IP=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.clusterIP}')

2) curl -v http://${CLUSTER_IP}
Response:
>> <a href="/dex/auth?client_id=kubeflow-oidc-authservice&amp;redirect_uri=%2Flogin%2Foidc&amp;response_type=code&amp;scope=profile+email+groups+openid&amp;state=STATE_VALUE">Found</a>.

STATE=STATE_VALUE

3) curl -v "http://${CLUSTER_IP}/dex/auth?client_id=kubeflow-oidc-authservice&redirect_uri=%2Flogin%2Foidc&response_type=code&scope=profile+email+groups+openid&amp;state=${STATE}"
Response:
>> <a href="/dex/auth/local?req=REQ_VALUE">Found</a>

REQ=REQ_VALUE
4) curl -v "http://${CLUSTER_IP}/dex/auth/local?req=${REQ}" -H 'Content-Type: application/x-www-form-urlencoded' --data 'login=admin%40kubeflow.org&password=12341234'

5) curl -v "http://${CLUSTER_IP}/dex/approval?req=${REQ}"

Response:
>> <a href="/login/oidc?code=CODE_VALUE&amp;state=STATE_VALUE">See Other</a>.

CODE=CODE_VALUE

6) curl -v "http://${CLUSTER_IP}/login/oidc?code=${CODE}&amp;state=${STATE}"

Response:
>> set-cookie authservice_session=SESSION

SESSION=SESSION

Login using python code
Here we are using requests package which follows redirections, hence we need to call 2 API explicitly, which involves 4 redirections under the hood

import requests as requests
import re


response = requests.get(f"http://{CLUSTER_IP}")
response_text = response.text
//Extract the request token REQ_VALUE as done in step 3req_token = re.search('req=(.+)">', response_text).group(1)creds={'login':'user@example.com','password':'12341234'}
response = requests.post(f"http://{CLUSTER_IP}/dex/auth/local?req={req_token}",data=creds,headers={'Content-Type': 'application/x-www-form-urlencoded'})
// Cookie was set in the last redirection, hence we need to fetch that from response.history
cookie = "authservice_session="+response.history[2].cookies.get('authservice_session')
print(cookie)
// This is the desired cookie

--

--