-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
authN-authZ: update documentation and policy
* Add more descriptions for the authentication and authorization part * change the sample authorization to perform on role Signed-off-by: Ruoyu Ying <[email protected]>
- Loading branch information
Showing
2 changed files
with
27 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
# Use GMC and Istio to compose an OPEA Pipeline with authentication and authorization enabled | ||
|
||
Authentication and authorization are essential measures that ensure the secure operation of our GenAI workload. Currently we provide two options to implement the task : via bearer JWT token and via keycloak. | ||
And here we use the chatQnA pipeline as an example. | ||
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, lets dive into how we can accomplish AuthN and AuthZ in OPEA using Istio and JWT tokens. | ||
|
||
Currently we provide two options to implement the task : via fake JWT token and via JWT token generated by OIDC providers. And here we use the chatQnA pipeline as an example. | ||
|
||
## Prerequisite | ||
|
||
|
@@ -30,6 +31,10 @@ kubectl patch deployment -n chatqa router-server --patch '{ | |
|
||
## Perform authentication and authorization via fake JWT tokens | ||
|
||
Here provides the case of authentication and authorization using fake JWT tokens. Fake JWT tokens are generated through a sample script provided by Istio community. | ||
|
||
In this example, we setup rules that only users with JWT token issued by "[email protected]" and with claim "groups" equal to "group1" can access the chatQnA workload. | ||
|
||
**Apply authentication and authorization policies to the pipeline endpoint based on raw JWT tokens** | ||
|
||
```sh | ||
|
@@ -78,17 +83,17 @@ kubectl exec -it -n chatqa $CLIENT_POD -- curl -X POST $accessUrl -d '{"text":"W | |
# try with an invalid token. Shall get response: "RBAC: access denied 403" | ||
kubectl exec -it -n chatqa $CLIENT_POD -- 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 $TOKEN1" -H 'Content-Type: application/json' -w " %{http_code}\n" | ||
|
||
# try with the valid token. Shall get the correct response | ||
kubectl exec -it -n chatqa $CLIENT_POD -- 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 $TOKEN2" -H 'Content-Type: application/json' | ||
# try with the valid token. Shall get the correct response with http code | ||
kubectl exec -it -n chatqa $CLIENT_POD -- 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 $TOKEN2" -H 'Content-Type: application/json' -w " %{http_code}\n" | ||
``` | ||
|
||
## Perform authentication and authorization via JWT tokens generated by Keycloak | ||
## Perform authentication and authorization via JWT tokens generated by OIDC provider | ||
|
||
Keycloak is an open source identity and access management project to add authentication to applications and secure services with minimum effort. Here we leverage Keycloak to generate a JWT token. | ||
An OpenID Connect (OIDC) provider is the service that can help handle authentication and authorization. It provides identity information for users in the form of ID tokens, which contain claims about the user's identity (like their name, email, and user ID). In this example, we choose Keycloak, which is an open source identity and access management project to add authentication to applications and secure services with minimum effort to generate and manage JWT tokens. User can select the OIDC providers including Github, Google, Azure and etc according to their needs. | ||
|
||
In this sample, we are going to test with scenario that only privileged users can access our chatQnA service and ask questions. In this case, user `mary` who has the role `user` can access the chatQnA pipeline. And user `bob` with the role `viewer` will not be able to access the service. Of course, the other users without valid token cannot access the service. | ||
In this sample, we are going to test with the scenario that only privileged users can access our chatQnA service and ask questions. In this case, user `mary` who has the role `user` can access the chatQnA pipeline. And user `bob` with the role `viewer` will not be able to access the service. Of course, the other users without valid token cannot access the service. | ||
|
||
**Keycloak installation and configuration** | ||
**Sample OIDC provider installation and configuration: Keycloak** | ||
|
||
Install Keycloak in the kubernetes cluster for user management. **Note:** Replace the admin password as your own in the keycloak_install.yaml file. | ||
|
||
|
@@ -116,32 +121,34 @@ The user management is done via Keycloak and the configuration steps look like t | |
|
||
4. Create a new user name as `mary` and another user as `bob`. Set passwords for both users (set 'Temporary' to 'Off'). Select Role mapping on the top, assign the `user` role to `mary` and assign the `viewer` role to `bob`. | ||
|
||
**Apply authentication and authorization policies to the pipeline endpoint based on Keycloak** | ||
**Apply authentication and authorization policies to the pipeline endpoint based on OIDC provider** | ||
|
||
Use the commands to apply the authentication and authorization rules. | ||
|
||
```bash | ||
# export the router service through istio ingress gateway | ||
kubectl apply -f $(pwd)/config/authN-authZ/chatQnA_router_gateway.yaml | ||
|
||
# use 'envsubst' to substitute envs in yaml. | ||
# 'envsubst' is used to substitute envs in yaml. | ||
# use 'sudo apt-get install gettext-base' to install envsubst if it does not exist on your machine | ||
# apply the authentication and authorization rule | ||
# these files will restrict user access with valid token (with valid issuer, username and sub) | ||
# these files will restrict user access with valid token (with valid issuer, username and realm role) | ||
envsubst < $(pwd)/config/authN-authZ/chatQnA_authN_keycloak.yaml | kubectl -n chatqa apply -f - | ||
envsubst < $(pwd)/config/authN-authZ/chatQnA_authZ_keycloak.yaml | kubectl -n chatqa apply -f - | ||
``` | ||
|
||
User could customize the chatQnA_authZ_keycloak.yaml to reflect roles, groups or any other claims they defined in the OIDC provider for the user. | ||
|
||
**Validate authentication and authorization with different JWT tokens** | ||
|
||
Fetch ID tokens for the two different users. **Note:** Remember to replace the `password` in the curl url and turn off the all the 'Required actions' under the 'Authentication' section. | ||
Fetch access tokens for the two different users. **Note:** These commands are samples for Keycloak. And remember to replace the `password` in the curl url and turn off the all the 'Required actions' under the 'Authentication' section in Keycloak. | ||
|
||
```bash | ||
# get id token for mary. Please replace the password inside the url. | ||
export TOKENA=$(curl -X POST 'http://${KEYCLOAK_ADDR}/realms/istio/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'client_id=istio' --data-urlencode 'username=mary' -d 'password=${PASSWORD}' -d 'scope=openid' -d 'response_type=id_token' | jq -r .id_token) | ||
# get access token for mary. Please replace the password inside the url. | ||
export TOKENA=$(curl -X POST 'http://${KEYCLOAK_ADDR}/realms/istio/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'client_id=istio' --data-urlencode 'username=mary' -d 'password=${PASSWORD}' -d 'scope=openid' -d 'response_type=id_token' | jq -r .access_token) | ||
|
||
# get id token for bob. Please replace the password inside the url. | ||
export TOKENB=$(curl -X POST 'http://${KEYCLOAK_ADDR}/realms/istio/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'client_id=istio' --data-urlencode 'username=bob' -d 'password=${PASSWORD}' -d 'scope=openid' -d 'response_type=id_token' | jq -r .id_token) | ||
# get access token for bob. Please replace the password inside the url. | ||
export TOKENB=$(curl -X POST 'http://${KEYCLOAK_ADDR}/realms/istio/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' --data-urlencode 'grant_type=password' --data-urlencode 'client_id=istio' --data-urlencode 'username=bob' -d 'password=${PASSWORD}' -d 'scope=openid' -d 'response_type=id_token' | jq -r .access_token) | ||
``` | ||
|
||
Access the istio ingress gateway to reach the chatQnA service with different tokens. Follow the istio guide [here](https://istio.io/latest/docs/tasks/traffic-management/ingress/ingress-control/#determining-the-ingress-ip-and-ports) to determine the ingress IP and ports. | ||
|
@@ -156,6 +163,6 @@ curl -X POST $accessUrl -d '{"text":"What is the revenue of Nike in 2023?","para | |
# try with token of bob. Shall get response: "RBAC: access denied 403" | ||
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 $TOKENB" -H 'Content-Type: application/json' -w " %{http_code}\n" | ||
|
||
# try with the valid token from mary. Shall get the correct response from LLM | ||
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 $TOKENA" -H 'Content-Type: application/json' | ||
# try with the valid token from mary. Shall get the correct response from LLM with http code | ||
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 $TOKENA" -H 'Content-Type: application/json' -w " %{http_code}\n" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters