Chapter 9. Configuring access to Knative services 9.1. Configuring JSON Web Token authentication for Knative services OpenShift Serverless does not currently have user-defined authorization features. To add user-defined authorization to your deployment, you must integrate OpenShift Serverless with Red Hat OpenShift Service Mesh, and then configure JSON Web Token (JWT) authentication and sidecar injection for Knative services. 9.2. Using JSON Web Token authentication with Service Mesh 2.x You can use JSON Web Token (JWT) authentication with Knative services by using Service Mesh 2.x and OpenShift Serverless. To do this, you must create authentication requests and policies in the application namespace that is a member of the ServiceMeshMemberRoll object. You must also enable sidecar injection for the service. 9.2.1. Configuring JSON Web Token authentication for Service Mesh 2.x and OpenShift Serverless Important Adding sidecar injection to pods in system namespaces, such as knative-serving and knative-serving-ingress , is not supported when Kourier is enabled. For OpenShift Container Platform, if you require sidecar injection for pods in these namespaces, see the OpenShift Serverless documentation on Integrating Service Mesh with OpenShift Serverless natively . Prerequisites You have installed the OpenShift Serverless Operator, Knative Serving, and Red Hat OpenShift Service Mesh on your cluster. Install the OpenShift CLI ( oc ). You have created a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform. Procedure Add the sidecar.istio.io/inject="true" annotation to your service: Example service apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2 ... 1 Add the sidecar.istio.io/inject="true" annotation. 2 You must set the annotation sidecar.istio.io/rewriteAppHTTPProbers: "true" in your Knative service, because OpenShift Serverless versions 1.14.0 and higher use an HTTP probe as the readiness probe for Knative services by default. Apply the Service resource: USD oc apply -f <filename> Create a RequestAuthentication resource in each serverless application namespace that is a member in the ServiceMeshMemberRoll object: apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: <namespace> spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/jwks.json Apply the RequestAuthentication resource: USD oc apply -f <filename> Allow access to the RequestAuthenticaton resource from system pods for each serverless application namespace that is a member in the ServiceMeshMemberRoll object, by creating the following AuthorizationPolicy resource: apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allowlist-by-paths namespace: <namespace> spec: action: ALLOW rules: - to: - operation: paths: - /metrics 1 - /healthz 2 1 The path on your application to collect metrics by system pod. 2 The path on your application to probe by system pod. Apply the AuthorizationPolicy resource: USD oc apply -f <filename> For each serverless application namespace that is a member in the ServiceMeshMemberRoll object, create the following AuthorizationPolicy resource: apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-jwt namespace: <namespace> spec: action: ALLOW rules: - from: - source: requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"] Apply the AuthorizationPolicy resource: USD oc apply -f <filename> Verification If you try to use a curl request to get the Knative service URL, it is denied: Example command USD curl http://hello-example-1-default.apps.mycluster.example.com/ Example output RBAC: access denied Verify the request with a valid JWT. Get the valid JWT token: USD TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode - Access the service by using the valid token in the curl request header: USD curl -H "Authorization: Bearer USDTOKEN" http://hello-example-1-default.apps.example.com The request is now allowed: Example output Hello OpenShift! 9.3. Using JSON Web Token authentication with Service Mesh 1.x You can use JSON Web Token (JWT) authentication with Knative services by using Service Mesh 1.x and OpenShift Serverless. To do this, you must create a policy in the application namespace that is a member of the ServiceMeshMemberRoll object. You must also enable sidecar injection for the service. 9.3.1. Configuring JSON Web Token authentication for Service Mesh 1.x and OpenShift Serverless Important Adding sidecar injection to pods in system namespaces, such as knative-serving and knative-serving-ingress , is not supported when Kourier is enabled. For OpenShift Container Platform, if you require sidecar injection for pods in these namespaces, see the OpenShift Serverless documentation on Integrating Service Mesh with OpenShift Serverless natively . Prerequisites You have installed the OpenShift Serverless Operator, Knative Serving, and Red Hat OpenShift Service Mesh on your cluster. Install the OpenShift CLI ( oc ). You have created a project or have access to a project with the appropriate roles and permissions to create applications and other workloads in OpenShift Container Platform. Procedure Add the sidecar.istio.io/inject="true" annotation to your service: Example service apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2 ... 1 Add the sidecar.istio.io/inject="true" annotation. 2 You must set the annotation sidecar.istio.io/rewriteAppHTTPProbers: "true" in your Knative service, because OpenShift Serverless versions 1.14.0 and higher use an HTTP probe as the readiness probe for Knative services by default. Apply the Service resource: USD oc apply -f <filename> Create a policy in a serverless application namespace which is a member in the ServiceMeshMemberRoll object, that only allows requests with valid JSON Web Tokens (JWT): Important The paths /metrics and /healthz must be included in excludedPaths because they are accessed from system pods in the knative-serving namespace. apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: default namespace: <namespace> spec: origins: - jwt: issuer: testing@secure.istio.io jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/jwks.json" triggerRules: - excludedPaths: - prefix: /metrics 1 - prefix: /healthz 2 principalBinding: USE_ORIGIN 1 The path on your application to collect metrics by system pod. 2 The path on your application to probe by system pod. Apply the Policy resource: USD oc apply -f <filename> Verification If you try to use a curl request to get the Knative service URL, it is denied: USD curl http://hello-example-default.apps.mycluster.example.com/ Example output Origin authentication failed. Verify the request with a valid JWT. Get the valid JWT token: USD TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode - Access the service by using the valid token in the curl request header: USD curl http://hello-example-default.apps.mycluster.example.com/ -H "Authorization: Bearer USDTOKEN" The request is now allowed: Example output Hello OpenShift!

Commands:
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: jwt-example namespace: <namespace> spec: jwtRules: - issuer: testing@secure.istio.io jwksUri: https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/jwks.json
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allowlist-by-paths namespace: <namespace> spec: action: ALLOW rules: - to: - operation: paths: - /metrics 1 - /healthz 2
oc apply -f <filename>
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-jwt namespace: <namespace> spec: action: ALLOW rules: - from: - source: requestPrincipals: ["testing@secure.istio.io/testing@secure.istio.io"]
oc apply -f <filename>
curl http://hello-example-1-default.apps.mycluster.example.com/
RBAC: access denied
TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode -
curl -H "Authorization: Bearer USDTOKEN" http://hello-example-1-default.apps.example.com
Hello OpenShift!
apiVersion: serving.knative.dev/v1 kind: Service metadata: name: <service_name> spec: template: metadata: annotations: sidecar.istio.io/inject: "true" 1 sidecar.istio.io/rewriteAppHTTPProbers: "true" 2
oc apply -f <filename>
apiVersion: authentication.istio.io/v1alpha1 kind: Policy metadata: name: default namespace: <namespace> spec: origins: - jwt: issuer: testing@secure.istio.io jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/jwks.json" triggerRules: - excludedPaths: - prefix: /metrics 1 - prefix: /healthz 2 principalBinding: USE_ORIGIN
oc apply -f <filename>
curl http://hello-example-default.apps.mycluster.example.com/
Origin authentication failed.
TOKEN=USD(curl https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/demo.jwt -s) && echo "USDTOKEN" | cut -d '.' -f2 - | base64 --decode -
curl http://hello-example-default.apps.mycluster.example.com/ -H "Authorization: Bearer USDTOKEN"
Hello OpenShift!