## 4.3.5  Exposing and Securing Workloads with a JWT
Learn how to expose a workload and secure it with a JSON Web Token (JWT). To get the token, create a client credentials application using SAP Cloud Identity Services - Identity Authentication.
## Prerequisites
- You have the Istio and API Gateway modules added. See Adding and Deleting a Kyma Module [page 3157].
- You have access to Kyma dashboard. Alternatively, to use CLI instructions, you must install kubectl and configure it to communicate with your Kyma runtime instance. See Access a Kyma Instance Using kubectl [page 2018].
- You have installed curl .
- You have a deployed workload.
##  Note
To expose a workload using APIRule in version v2 , the workload must be a part of the Istio service mesh. See Enabling Istio Sidecar Proxy Injection [page 1783].
- You have an SAP Cloud Identity Services - Identity Authentication tenant and you have created an OpenID Connect Application in it. See Create OpenID Connect Application and Configure OpenID Connect Application for JWT Bearer Flow.
- You have configured a Secret for API Authentication and saved the values of Client ID and Client Secret. See Configure Secrets for API Authentication.
- You have set up your custom domain . Alternatively, you can use the default domain of your Kyma cluster and the default Gateway kyma-system/kyma-gateway .
##  Note
Because the default Kyma domain is a wildcard domain, which uses a simple TLS Gateway, it is recommended that you set up your custom domain for use in a production environment.
##  Tip
To learn what the default domain of your Kyma cluster is, run the following command:
```
kubectl get gateway -n kyma-system kyma-gateway -o jsonpath='{.spec.servers[0].hosts}'
```
## Context
To interact with a workload that is secured using an API Rule of the JWT type, you need an access token. Follow these steps to obtain a JWT using an Identity Authentication tenant. Then, use either kubectl or Kyma dashboard to expose and secure your workload.
## Procedure
- To obtain a JWT token, you must use curl. To create an APIRule custom resource (CR), you can use either Kyma dashboard or kubectl.
- Use Kyma dashboard.
- a. Export the name of your Identity Authentication instance and your client credentials as environment variables:
- b. Encode your client credentials and export them as an environment variable:
- c. Get values of the token\_endpoint , jwks\_uri , and issuer parameters:
```
export
```
```
IDENTITY_AUTHENTICATION_INSTANCE={YOUR_IDENTITY_AUTHENTICATION_INSTANCE_NAM E} export CLIENT_ID={YOUR_CLIENT_ID} export CLIENT_SECRET={YOUR_CLIENT_SECRET}
```
```
export ENCODED_CREDENTIALS=$(echo -n "$CLIENT_ID:$CLIENT_SECRET" | base64)
```
```
curl -s https://$IDENTITY_AUTHENTICATION_INSTANCE.accounts400.ondemand.com/.well-
```
known/openid-configuration
##  Note
You need the values of the jwks\_uri and issuer parameters to secure your workload using an APIRule of the JWT type.
- d. Export the value of the token\_endpoint parameter as an environment variable:
- e. Get the JWT:
- f. Go to the namespace in which you want to create an APIRule custom resource.
```
export TOKEN_ENDPOINT={YOUR_TOKEN_ENDPOINT}
```
```
curl -X POST "$TOKEN_ENDPOINT" -d "grant_type=client_credentials" -d "client_id=$CLIENT_ID" -H "Content-Type: application/x-www-formurlencoded" -H "Authorization: Basic $ENCODED_CREDENTIALS"
```
The namespace must have Istio sidecar proxy injection enabled. See Enabling Istio Sidecar Proxy Injection [page 1783].
- g. Go to Discovery and Network → API Rules and select Create .
- h. Provide all the required configuration details, such as APIRule CR's name, the name and port of the Service you want to expose, the Gateway's name, and the host in the format {SUBDOMAIN}. {YOUR\_DOMAIN} .
- i. Add a rule with the following configuration:
- j. Select Create .
- k. To call the endpoint, send a GET request to the Service:
| Option          | Description                                                                               |
|-----------------|-------------------------------------------------------------------------------------------|
| Access Strategy | jwt In the JWT section, add an authentication with your issuer and JSON Web Key Set URIs. |
| Methods         | GET                                                                                       |
| path            | /*                                                                                        |
curl -ik -X GET https://{SUBDOMAIN}.{DOMAIN\_NAME}/headers
You get the error 401 Unauthorized .
- l. Now, access the secured workload using the correct JWT.
curl -ik -X GET https://{SUBDOMAIN}.{DOMAIN\_NAME}/headers --header "Authorization:Bearer $ACCESS\_TOKEN"
If successful, you get the code 200 OK in response.
- Use kubectl.
- a. Export the name of your Identity Authentication instance and your client credentials as environment variables:
## export
IDENTITY\_AUTHENTICATION\_INSTANCE={YOUR\_IDENTITY\_AUTHENTICATION\_INSTANCE\_NAM E}
export CLIENT\_ID={YOUR\_CLIENT\_ID}
export CLIENT\_SECRET={YOUR\_CLIENT\_SECRET}
- b. Encode your client credentials and export them as an environment variable:
export ENCODED\_CREDENTIALS=$(echo -n "$CLIENT\_ID:$CLIENT\_SECRET" | base64)
- c. Get values of the token\_endpoint , jwks\_uri , and issuer parameters:
curl -s https://$IDENTITY\_AUTHENTICATION\_INSTANCE.accounts400.ondemand.com/.wellknown/openid-configuration
##  Note
You need the values of the jwks\_uri and issuer parameters to secure your workload using an APIRule of the JWT type.
- d. Export the value of the token\_endpoint parameter as an environment variable:
export TOKEN\_ENDPOINT={YOUR\_TOKEN\_ENDPOINT}
- e. Get the JWT:
- f. Export the JWT as an environment variable:
- g. To expose and secure your Service, replace all placeholders and create the following APIRule:
- h. To call the endpoint, send a GET request to the Service
```
curl -X POST "$TOKEN_ENDPOINT" -d "grant_type=client_credentials" -d "client_id=$CLIENT_ID" -H "Content-Type: application/x-www-formurlencoded" -H "Authorization: Basic $ENCODED_CREDENTIALS"
```
```
export ACCESS_TOKEN={YOUR_ACCESS_TOKEN}
```
```
cat <<EOF | kubectl apply -f apiVersion: gateway.kyma-project.io/v2 kind: APIRule metadata: name: {APIRULE_NAME} namespace: {APIRULE_NAMESPACE} spec: hosts: - {SUBDOMAIN}.{DOMAIN_NAME} service: name: {SERVICE_NAME} port: {SERVICE_PORT} rules: - jwt: authentications: -  issuer: {ISSUER} jwksUri: {JWKS_URI} methods: - GET path: /*
```
```
gateway: {GATEWAY_NAME}/{GATEWAY_NAMESPACE} EOF
```
```
curl -ik -X GET https://{SUBDOMAIN}.{DOMAIN_NAME}/headers
```
You get the error 401 Unauthorized .
- i. Now, access the secured workload using the correct JWT.
```
curl -ik -X GET https://{SUBDOMAIN}.{DOMAIN_NAME}/headers --header "Authorization:Bearer $ACCESS_TOKEN"
```
If successful, you get the code 200 OK in response.