From ee907d6b0846b1cb39e94f43409ad9d8732b3fc2 Mon Sep 17 00:00:00 2001 From: ckhened Date: Wed, 11 Sep 2024 00:30:45 -0700 Subject: [PATCH] Enable OIDC based Authentication with apisix (#312) * Enable OIDC based Authentication with apisix Signed-off-by: Chaitanya Khened * Update README.md Signed-off-by: Chaitanya Khened * incorporating review comments for apisix installation and updating directory structure Signed-off-by: Chaitanya Khened * Adding more details in README and some cleanup in values files Signed-off-by: Chaitanya Khened * Adding in new directory structure and incorporating some review comments Signed-off-by: Chaitanya Khened * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updating READMEs Signed-off-by: Chaitanya Khened * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Chaitanya Khened Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- authN-authZ/README.md | 4 + authN-authZ/auth-apisix/Chart.yaml | 7 ++ authN-authZ/auth-apisix/README.md | 115 ++++++++++++++++++ .../templates/apisix-chatqna-route.yaml | 35 ++++++ authN-authZ/auth-apisix/values.yaml | 20 +++ authN-authZ/auth-apisix/values_apisix_gw.yaml | 18 +++ 6 files changed, 199 insertions(+) create mode 100644 authN-authZ/auth-apisix/Chart.yaml create mode 100644 authN-authZ/auth-apisix/README.md create mode 100644 authN-authZ/auth-apisix/templates/apisix-chatqna-route.yaml create mode 100644 authN-authZ/auth-apisix/values.yaml create mode 100644 authN-authZ/auth-apisix/values_apisix_gw.yaml diff --git a/authN-authZ/README.md b/authN-authZ/README.md index 57145013..1acf243c 100644 --- a/authN-authZ/README.md +++ b/authN-authZ/README.md @@ -7,3 +7,7 @@ Here we provide different options for user to implement authentication and autho ## Istio based implementation for cloud native environments Utilize Istio, a well-known and widely adopted cloud-native tool, to enhance authentication and authorization processes. This ensures secure, efficient, and reliable enterprise operations by managing access controls effectively. This solution can integrate directly with OIDC providers like Keycloak or utilize an authentication proxy such as oauth2-proxy, enhancing its flexibility and scalability. We provide support for both helm chart and GMC based GenAI workload deployment to handle the authentication and authorization with either strict or flexible policies, adapting to various security requirements and operational needs. Please refer the documentation [here](./auth-istio/README.md) for more information. + +## APISIX based implementation for cloud native environments + +Apache APISIX is an open-source, dynamic, scalable, and high-performance cloud-native API gateway. It serves as a traffic management solution for APIs and microservices, offering a wide range of features and capabilities. Apache APISIX offers robust support for OpenID Connect (OIDC) authentication through its openid-connect plugin and can integrate with any OIDC provider. Another powerful feature of APISIX is the support for developing custom plugins to extend its functionality. Please refer the documentation [here](./auth-apisix/README.md) for more information on deploying and configuring apisix through helm charts. diff --git a/authN-authZ/auth-apisix/Chart.yaml b/authN-authZ/auth-apisix/Chart.yaml new file mode 100644 index 00000000..2a107845 --- /dev/null +++ b/authN-authZ/auth-apisix/Chart.yaml @@ -0,0 +1,7 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: v2 +name: auth-apisix-crds +description: A Helm chart for publishing secure OPEA app APIs +version: 0.1.0 diff --git a/authN-authZ/auth-apisix/README.md b/authN-authZ/auth-apisix/README.md new file mode 100644 index 00000000..bf46a0db --- /dev/null +++ b/authN-authZ/auth-apisix/README.md @@ -0,0 +1,115 @@ +# Authentication and Authorization with APISIX and OIDC based Identity provider (Keycloak) + +Follow the steps to enable authentication and authorization of OPEA services using APISIX api gateway and Identity provider like keycloak + +## Prerequisites + +1. Make sure ChatQnA service is running and accessible locally + +2. Run keycloak, setup a realm with OIDC based authentication and add users with passwords for each user. + +Steps to start keycloak from official keycloak helm chart + +```sh +# Prerequisite: Create a PersistentVolume of 9Gi for keycloak-postgress with RWO access (to persist updated keycloak configuration) +# Below is a reference to create PersistentVolume which will be used by keycloak-postgress +kubectl apply -f - < +export accessUrl=http://$NODE_IP:$NODE_PORT/ + + +``` + +
+Apisix helm chart provides configs to change the service type to other options like LoadBalancer (apisix.service.type) and externalTrafficPolicy to 'local'(apisix.service.externalTrafficPolicy). These can be added in values_apisix_gw.yaml

+While accessing the published APIs, the HTTP Authorization header of the request should contain the Access token provided by Identity provider as 'Bearer <Access Token>'.

+The access token, refresh token, userinfo, user roles and OIDC scopes assigned to user can be obtained by invoking OIDC auth endpoint through UI or token endpoint through curl and providing user credentials.

+ +Below steps can be followed to get access token from keycloak and access the APISIX published ChatQnA API through curl + +```sh +# Get access token for specified user from keycloak +export USER= +export PASSWORD= +export KEYCLOAK_ADDR= +export KEYCLOAK_REALM= +export KEYCLOAK_CLIENT_ID= +export KEYCLOAK_CLIENT_SECRET= + +#Invoke Keycloak's OIDC token endpoint to get access token, refresh token and expirt times. (Only Access token is used in the example below) +export TOKEN=$(curl -X POST http://${KEYCLOAK_ADDR}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token -H 'Content-Type: application/x-www-form-urlencoded' -d "grant_type=password&client_id=${KEYCLOAK_CLIENT_ID}&client_secret=${KEYCLOAK_CLIENT_SECRET}&username=${USER}&password=${PASSWORD}" | jq -r .access_token) + +# follow instructions above to fetch the NODE_IP and NODE_PORT +export accessUrl="http://$NODE_IP:$NODE_PORT/chatqna-oidc" + +# try without token. Shall get response: "Authorization required 401 error" +curl -X POST $accessUrl -d '{"text":"What is the revenue of Nike in 2023?","parameters":{"max_new_tokens":17, "do_sample": true}}' -sS -H 'Content-Type: application/json' -w " %{http_code}\n" + +# try with token. Shall get the correct response from ChatQnA with http code 200 +curl -X POST $accessUrl -d '{"text":"What is the revenue of Nike in 2023?","parameters":{"max_new_tokens":17, "do_sample": true}}' -sS -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -w " %{http_code}\n" + +``` + +## Uninstall + +```sh +# Uninstall apisix +helm uninstall auth-apisix-crds --namespace auth-apisix +helm uninstall auth-apisix --namespace auth-apisix +``` + +The crds installed by apisix won't be deleted by helm uninstall. Need to manually delete those crds
+All APISIX specific crds can be obtained by 'kubectl get crds | grep apisix'
+Each crd can be manually deleted by 'kubectl delete crd/\'
diff --git a/authN-authZ/auth-apisix/templates/apisix-chatqna-route.yaml b/authN-authZ/auth-apisix/templates/apisix-chatqna-route.yaml new file mode 100644 index 00000000..61658f88 --- /dev/null +++ b/authN-authZ/auth-apisix/templates/apisix-chatqna-route.yaml @@ -0,0 +1,35 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +apiVersion: apisix.apache.org/v2 +kind: ApisixRoute +metadata: + name: chatqna-authenticated-endpoints + namespace: {{ .Values.chatqna.namespace }} +spec: + http: + - name: chatqna-query + match: + hosts: + - {{ .Values.chatqna.hostname }} + paths: + - {{ .Values.chatqna.query_api.path }} + backends: + - serviceName: {{ .Values.chatqna.query_api.backend_service }} + servicePort: {{ .Values.chatqna.query_api.service_port }} + plugins: + - name: openid-connect + enable: true + config: + client_id: {{ .Values.oidc.client_id }} + client_secret: {{ .Values.oidc.client_secret }} + discovery: {{ .Values.oidc.discovery }} + introspection_endpoint: {{ .Values.oidc.introspection_endpoint }} + introspection_endpoint_auth_method: client_secret_basic + scope: openid profile email + bearer_only: true + realm: myrealm + - name: proxy-rewrite + enable: true + config: + uri: {{ .Values.chatqna.query_api.service_path }} diff --git a/authN-authZ/auth-apisix/values.yaml b/authN-authZ/auth-apisix/values.yaml new file mode 100644 index 00000000..0589ced5 --- /dev/null +++ b/authN-authZ/auth-apisix/values.yaml @@ -0,0 +1,20 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Identity provider OIDC config +oidc: + realm: your-OIDC-provider-realm # replace with your realm name for OPEA apps + client_id: your-OIDC-provider-client-id # replace with your oidc client id + client_secret: your-OIDC-provider-client-secret # your oidc client secret + discovery: your-OIDC-provider-openid-configuration # replace with your oidc discovery endpoint + introspection_endpoint: your-OIDC-provider-introspection-endpoint # replace with your oidc introspection endpoint> + +# APISIX chatqna api config +chatqna: + namespace: default # namespace in which your chatqna service is running + hostname: your-hostname # 'Host' HTTP header from incoming request should match this. Wildcards like '*' allowed too + query_api: + path: /chatqna-oidc # This is the path that will be published in apisix and this should be used by UI to access the chatqna service + backend_service: router-service # your kubernetes service name to access chatqna megaservice or gmc without ..svc.cluster.local + service_port: 8080 # port on which chatqna mega service or gmc is running + service_path: "/" # path to access chatqna mega service or gmc backend diff --git a/authN-authZ/auth-apisix/values_apisix_gw.yaml b/authN-authZ/auth-apisix/values_apisix_gw.yaml new file mode 100644 index 00000000..fa1f7430 --- /dev/null +++ b/authN-authZ/auth-apisix/values_apisix_gw.yaml @@ -0,0 +1,18 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +# APISIX Helm chart configs +version: 2.8.1 +enabled: true +ingress-controller: + enabled: true + config: + apisix: + serviceName: auth-apisix-admin + serviceNamespace: auth-apisix +etcd: + replicaCount: 1 + persistence: + enabled: false +dashboard: + enabled: false