Skip to content

guicassolato/odh-authorino

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Open Data Hub protected with Authorino Ext-Authz

This is a Proof of Concept of protecting Open Data Hub with Authorino external authorization on an OpenShift cluster.

Target architecture

Architecture

Try

Requirements

  • OpenShift cluster with the following operators installed:
    • Kiali
    • Jaeger
    • OpenShift Service Mesh (OSSM)
    • Open Data Hub
    • Authorino
  • CLI tools
    • kubectl
    • oc
    • jq

Setup

① Clone the repo
git clone [email protected]:guicassolato/odh-authorino.git && cd odh-authorino
② Store the OpenShift cluster domain in the shell

⚠️ This step is important as well for other parts of the tutorial further below. Do not skip it.

export CLUSTER_DOMAIN=gui-rhods.2hfs.s1.devshift.org
③ Login to the cluster
oc login --token=... --server=https://api.$CLUSTER_DOMAIN:6443
④ Configure the service mesh control plane
make smcp | kubectl apply -f -
sleep 4 # to prevent kubectl wait from failing
kubectl wait --for condition=Ready smcp/basic --timeout 300s -n istio-system
⑤ Deploy Authorino
export AUTH_NS=authorino
make authorino | kubectl apply -f -

Patch the service mesh configuration to register the new external authorization provider:

kubectl patch smcp/basic -n istio-system --type merge -p "{\"spec\":{\"techPreview\":{\"meshConfig\":{\"extensionProviders\":[{\"name\":\"auth-provider\",\"envoyExtAuthzGrpc\":{\"service\":\"authorino-authorino-authorization.$AUTH_NS.svc.cluster.local\",\"port\":50051}}]}}}}"

(Optional) Avoid injecting the sidecar proxy in the Authorino container:

kubectl wait --for condition=Available deployment/authorino --timeout 300s -n authorino
kubectl patch deployment/authorino -n authorino --type merge -p "{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"sidecar.istio.io/inject\":\"false\"}}}}}"
⑥ Store useful OAuth endpoints in the shell

⚠️ This step is important for other parts of the tutorial further below. Do not skip it.

endpoint=$(kubectl -n default run oidc-config --attach --rm --restart=Never -q --image=curlimages/curl -- https://kubernetes.default.svc/.well-known/oauth-authorization-server -sS -k)

export AUTH_ENDPOINT=$(echo $endpoint | jq -r .authorization_endpoint)
export TOKEN_ENDPOINT=$(echo $endpoint | jq -r .token_endpoint)

Try with a sample application first

① Deploy the sample application (Talker API)
make talker-api | kubectl apply -f -
② Test endpoints of the Talker API protected behind Authorino

Try the API without an access token:

curl http://talker-api.apps.$CLUSTER_DOMAIN -I
# HTTP/1.1 302 Found
# location: https://oauth-openshift.apps....

Try the API as the same user logged in to OpenShift cluster in the terminal:

The expected result is 403 Forbidden because the token does not have the required scope, nor the user is bound to a role that grants permission.

curl -H "Authorization: Bearer $(oc whoami -t)" http://talker-api.apps.$CLUSTER_DOMAIN -I
# HTTP/1.1 403 Forbidden

(Optional) Inspect the token:

kubectl create -o json -f -<<EOF
apiVersion: authentication.k8s.io/v1
kind: TokenReview
spec:
  token: $(oc whoami -t)
EOF

Check that the callback endpoint skips the authorization:

This will be useful in another step further below, when simulating a webapp (frontend + backend for frontend) that consumes the API.

curl http://talker-api.apps.$CLUSTER_DOMAIN/oauth/callback -I
# HTTP/1.1 200 OK
③ Try the API as a webapp that also runs inside the cluster

The Talker API itself will be used as the backend for frontend of the webapp, and the Internet browser and terminal as the frontend. The codes 🅱 and 🅵 will be used to identify in the commands below which of these components respectively the command simulates.


Request a protected endpoint of the API in the browser:

open http://talker-api.apps.$CLUSTER_DOMAIN

Login as a user of the OpenShift cluster and delegate powers to the service account.

🅱 Finish the OAuth flow in the terminal:

export OAUTH_CLIENT_SECRET=$(kubectl get $(kubectl get secrets -n talker-api -o name | grep talker-api-bff-token) -n talker-api -o jsonpath='{.data.token}' | base64 -d)
export ACCESS_TOKEN=$(curl -S -d client_id=system:serviceaccount:talker-api:talker-api-bff \
    -d client_secret=$OAUTH_CLIENT_SECRET \
    -d redirect_uri=http://talker-api.apps.${CLUSTER_DOMAIN}/oauth/callback \
    -d grant_type=authorization_code \
    -d code=… \
    -d state=… \
    $TOKEN_ENDPOINT | jq -r .access_token)

🅵 Send a request to the API as the webapp:

curl -H "Authorization: Bearer $ACCESS_TOKEN" http://talker-api.apps.$CLUSTER_DOMAIN -I
# HTTP/1.1 200 OK

(Optional) Inspect the token:

kubectl create -o json -f -<<EOF
apiVersion: authentication.k8s.io/v1
kind: TokenReview
spec:
  token: $ACCESS_TOKEN
EOF
④ Try the API as the talker-api-bff SA itself (without delegation)

Request a short-lived token for the SA:

This step could be replaced by other methods for the application to obtain the token, such as volume projection.

export SA_TOKEN=$(kubectl create --raw /api/v1/namespaces/talker-api/serviceaccounts/talker-api-bff/token -f -<<EOF | jq -r .status.token
{ "apiVersion": "authentication.k8s.io/v1", "kind": "TokenRequest", "spec": { "expirationSeconds": 600 } }
EOF
)

Send a GET request to the API:

curl -H "Authorization: Bearer $SA_TOKEN" http://talker-api.apps.$CLUSTER_DOMAIN -I
# HTTP/1.1 200 OK

Send a POST request to the API:

curl -H "Authorization: Bearer $SA_TOKEN" http://talker-api.apps.$CLUSTER_DOMAIN -I -X POST
# HTTP/1.1 403 Forbidden

(Optional) Inspect the token:

kubectl create -o json -f -<<EOF
apiVersion: authentication.k8s.io/v1
kind: TokenReview
spec:
  token: $SA_TOKEN
EOF
jq -R 'split(".") | .[0],.[1] | @base64d | fromjson' <<< $(echo "$SA_TOKEN")

Try the Open Data Hub protected with Authorino

TODO(@guicassolato)

Cleanup

make authorino | kubectl delete -f -
make talker-api | kubectl delete -f -
make smcp | kubectl delete -f -

About

PoC of protecting Open Data Hub with Authorino

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published