Skip to content

Commit 994250c

Browse files
authn-authz: fix CORS issue and refine doc (#419)
* authn-authz: fix CORS issue and refine doc * add cors policy in the configuration * reflect helm chart related changes * clearify the three options for authentication and authorization in readme Signed-off-by: Ruoyu Ying <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Signed-off-by: Ruoyu Ying <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent a339a87 commit 994250c

File tree

7 files changed

+89
-31
lines changed

7 files changed

+89
-31
lines changed

authN-authZ/auth-istio/README.md

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
In enterprise settings not only do we want to identify who is using a service but also what they are entitled to use. This is where authentication and authorization comes in. In contrast, API tokens provide full access by virtue of possession as long as they are valid/not expired. With that aside, we first provide the solution on AuthN and AuthZ in OPEA using Istio and JWT tokens. Another option is to leverage the oauth2-proxy with various OIDC providers for authentication and authorization. Using oauth2-proxy with Istio ensures secure, scalable access control, centralizes user management, and provides seamless single sign-on capabilities, improving overall security and user experience in complex microservices environments.
44

5-
Currently we provide three kinds of setups for authentication and authorization: via fake JWT token, via JWT token generated by OIDC providers and via oauth2-proxy and OIDC providers. And here we use the chatQnA pipeline as an example.
5+
Currently we provide three kinds of setups for authentication and authorization. Note: Please complete the steps in the [prerequisite](#prerequisite) before proceeding with these tasks. :
6+
7+
- [via fake JWT token with curl](#perform-authentication-and-authorization-via-fake-jwt-tokens)
8+
- [via JWT token generated by OIDC providers with curl](#perform-authentication-and-authorization-via-jwt-tokens-generated-by-oidc-provider)
9+
- [via oauth2-proxy and OIDC providers with UI](#perform-authentication-and-authorization-via-oauth2-proxy-and-oidc-provider-and-ui)
10+
11+
Here we use the chatQnA pipeline as an example.
612

713
## Prerequisite
814

@@ -15,7 +21,7 @@ Before composing an OPEA pipeline with authN & authZ, user need to install Istio
1521
# deploy ChatQnA pipeline. You can either leverage GMC or the ChatQnA helm chart.
1622
kubectl create ns chatqa
1723
# here's the command to leverage GMC custom resource for ChatQnA deployment.
18-
kubectl apply -f $(pwd)/../../microservices-connector/config/samples/ChatQnA/chatQnA_xeon.yaml
24+
kubectl apply -f $(pwd)/../../microservices-connector/config/samples/ChatQnA/chatQnA_dataprep_xeon.yaml
1925
# please refer the doc https://github.com/opea-project/GenAIInfra/tree/main/helm-charts/chatqna for deployment with helm chart.
2026
# and install under `chatqa` namespace
2127

@@ -211,6 +217,13 @@ kubectl apply -f $(pwd)/keycloak_install.yaml
211217
export HOST_IP=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' | cut -d '/' -f3 | cut -d ':' -f1)
212218
export KEYCLOAK_PORT=$(kubectl get svc keycloak -o jsonpath='{.spec.ports[0].nodePort}')
213219
export KEYCLOAK_ADDR=${HOST_IP}:${KEYCLOAK_PORT}
220+
221+
# set the url to access the backend services
222+
if [ "${DEPLOY_METHOD}" = "gmc-based" ]; then
223+
export URL="http://chatqna-ui.com:${INGRESS_PORT}"
224+
else
225+
export URL="http://chatqna-service.com:${INGRESS_PORT}"
226+
fi
214227
```
215228
216229
**Note:** Double check if the host ip captured is the correct ip.
@@ -223,7 +236,7 @@ The user management is done via Keycloak and the configuration steps look like t
223236
224237
![create realm](./docs/create_realm.png)
225238
226-
2. Create a new client called `chatqna` and set `Client authentication` to 'On'. Set "http://chatqna-ui.com:${INGRESS_PORT}/*" in the `Valid redirect URIs` part. Note that `INGRESS_PORT` and `INGRESS_HOST` shall be exported following the guide [here](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports). Under the Credentials tab you will now be able to locate `<your client's secret>`, which will be used in the oauth2-proxy configs.
239+
2. Create a new client called `chatqna` and set `Client authentication` to 'On'. Set the value of `$URL` with "/\* " (e.g. "http://chatqna-ui.com:${INGRESS_PORT}/*") in the `Valid redirect URIs` part. Note that `INGRESS_PORT` and `INGRESS_HOST` shall be exported following the guide [here](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports). Under the Credentials tab you will now be able to locate `<your client's secret>`, which will be used in the oauth2-proxy configs.
227240
228241
![create client 1](./docs/create_client_1.png)
229242
@@ -265,29 +278,28 @@ kubectl create ns oauth2-proxy
265278
envsubst < $(pwd)/oauth2_install.yaml | kubectl apply -f -
266279
```
267280
268-
**Expose the pipeline endpoint through Istio Ingressgateway and install chatQnA UI**
281+
**Expose the pipeline endpoint and UI through Istio Ingressgateway**
269282
270283
Here we expose the chatQnA endpoint through the ingress gateway and then install the chatQnA conversation UI.
284+
Notice that the instructions differs between helm chart based deployment and GMC based deployment. Please the instructions accordingly.
285+
286+
With GMC based deployment, export chatqna endpoint and install UI services:
271287
272288
```bash
273289
# expose chatqna endpoint
274290
kubectl apply -f $(pwd)/$DEPLOY_METHOD/chatQnA_router_gateway_oauth.yaml
275-
# build chatqna UI image if not exist on your machine
276-
git clone https://github.com/opea-project/GenAIExamples.git
277-
cd GenAIExamples/ChatQnA/docker/ui/
278-
docker build --no-cache -t opea/chatqna-conversation-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile.react .
279-
# inject image to containerd repo
280-
docker save -o ui.tar opea/chatqna-conversation-ui:latest
281-
sudo ctr -n k8s.io image import ui.tar
282291
# install chatqna conversation UI
283-
cd && cd GenAIInfra
284-
if [ "${DEPLOY_METHOD}" = "gmc-based" ]; then
285-
helm install chatqna-ui $(pwd)/helm-charts/common/chatqna-ui --set BACKEND_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/",DATAPREP_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/dataprep"
286-
else
287-
helm install chatqna-ui $(pwd)/helm-charts/common/chatqna-ui --set BACKEND_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/v1/chatqna",DATAPREP_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/v1/dataprep"
288-
fi
292+
cd ../../
293+
helm install chatqna-ui $(pwd)/helm-charts/common/ui --set BACKEND_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/",DATAPREP_SERVICE_ENDPOINT="http://chatqna-service.com:${INGRESS_PORT}/dataprep"
289294
# expose ui service outside
290-
kubectl apply -f $(pwd)/chatQnA_ui_gateway.yaml
295+
cd authN-authZ/auth-istio
296+
kubectl apply -f $(pwd)/$DEPLOY_METHOD/chatQnA_ui_gateway.yaml
297+
```
298+
299+
With helm chart based deployment, the UI already deployed as part of the pipeline. So expose endpoints like this:
300+
301+
```bash
302+
kubectl apply -f $(pwd)/$DEPLOY_METHOD/chatQnA_router_gateway_oauth.yaml
291303
```
292304
293305
**Add authentication and authorization rules to the pipeline through Istio Ingress Gateway**
@@ -303,7 +315,7 @@ kubectl rollout restart deployment/istiod -n istio-system
303315
# apply the authentication and authorization rule
304316
# these files will restrict user access with valid token (with valid group and role)
305317
envsubst < $(pwd)/chatQnA_authN_oauth.yaml | kubectl apply -f -
306-
envsubst < $(pwd)/chatQnA_authZ_oauth.yaml | kubectl apply -f -
318+
envsubst < $(pwd)/$DEPLOY_METHOD/chatQnA_authZ_oauth.yaml | kubectl apply -f -
307319
```
308320
309321
**Validate authentication and authorization with UI service**
@@ -315,4 +327,6 @@ sudo sed -i '1i\127.0.0.1 chatqna-service.com' /etc/hosts
315327
sudo sed -i '1i\127.0.0.1 chatqna-ui.com' /etc/hosts
316328
```
317329
318-
Open browser with address "chatqna-ui.com:${INGRESS_PORT}". Login with user `bob` and its credentials shall return a 403 error. Login with user `mary` and its credentials shall able to access the ChatQnA service.
330+
Open browser with address `"chatqna-ui.com:${INGRESS_PORT}"` if using GMC based deployment. Otherwise, open the browser with address `"chatqna-service.com:${INGRESS_PORT}"`.
331+
332+
Login with user `bob` and its credentials shall return a 403 error. Login with user `mary` and its credentials shall able to access the ChatQnA service.

authN-authZ/auth-istio/chatQnA_authZ_oauth.yaml renamed to authN-authZ/auth-istio/gmc-based/chatQnA_authZ_oauth.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ spec:
1313
rules:
1414
- to:
1515
- operation:
16+
hosts:
17+
- chatqna-ui.com:${INGRESS_PORT}
1618
notPaths:
1719
- /realms/*
1820
selector:

authN-authZ/auth-istio/gmc-based/chatQnA_router_gateway_oauth.yaml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,20 @@ spec:
2929
hosts:
3030
- chatqna-service.com
3131
http:
32-
- match:
32+
- corsPolicy:
33+
allowCredentials: true
34+
allowHeaders:
35+
- content-type
36+
- authorization
37+
allowMethods:
38+
- POST
39+
- GET
40+
- OPTIONS
41+
- PUT
42+
- DELETE
43+
allowOrigins:
44+
- regex: http://chatqna-ui.com:.*
45+
match:
3346
- uri:
3447
prefix: /
3548
route:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
apiVersion: security.istio.io/v1
5+
kind: AuthorizationPolicy
6+
metadata:
7+
name: chatqna-ext-authz
8+
namespace: istio-system
9+
spec:
10+
action: CUSTOM
11+
provider:
12+
name: oauth2-proxy
13+
rules:
14+
- to:
15+
- operation:
16+
hosts:
17+
- chatqna-service.com:${INGRESS_PORT}
18+
notPaths:
19+
- /realms/*
20+
selector:
21+
matchLabels:
22+
istio: ingressgateway

authN-authZ/auth-istio/helm-chart-based/chatQnA_router_gateway_oauth.yaml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,22 @@ spec:
3434
prefix: /v1/chatqna
3535
route:
3636
- destination:
37-
host: chatqna.chatqa.svc.cluster.local
37+
host: chatqna-nginx.chatqa.svc.cluster.local
3838
port:
39-
number: 8888
39+
number: 80
4040
- match:
4141
- uri:
4242
prefix: /v1/dataprep
4343
route:
4444
- destination:
45-
host: chatqna-data-prep.chatqa.svc.cluster.local
45+
host: chatqna-nginx.chatqa.svc.cluster.local
4646
port:
47-
number: 6007
47+
number: 80
48+
- match:
49+
- uri:
50+
prefix: /
51+
route:
52+
- destination:
53+
host: chatqna-nginx.chatqa.svc.cluster.local
54+
port:
55+
number: 80

authN-authZ/auth-istio/oauth2_install.yaml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,13 @@ data:
3131
session_store_type="redis"
3232
redis_connection_url="redis://redis-service:6379"
3333
# Redirect url
34-
redirect_url="http://chatqna-ui.com:${INGRESS_PORT}/oauth2/callback"
34+
redirect_url="${URL}/oauth2/callback"
3535
#extra attributes
3636
reverse_proxy = true
3737
auth_logging = true
38+
request_logging = true
39+
silence_ping_logging = true
40+
standard_logging = true
3841
cookie_httponly = true
3942
cookie_refresh = "2m"
4043
cookie_expire = "3m"
@@ -43,15 +46,11 @@ data:
4346
pass_authorization_header = true
4447
pass_basic_auth = true
4548
pass_user_headers = true
46-
request_logging = true
4749
set_authorization_header = true
4850
set_xauthrequest = true
49-
silence_ping_logging = true
5051
skip_provider_button = true
51-
skip_auth_strip_headers = false
52+
skip_auth_preflight = true
5253
skip_jwt_bearer_tokens = true
53-
ssl_insecure_skip_verify = true
54-
standard_logging = true
5554
kind: ConfigMap
5655
metadata:
5756
name: oauth2-proxy-config

0 commit comments

Comments
 (0)