// Module included in the following assemblies:
//
// * serverless/knative-serving/config-access/serverless-ossm-with-kourier-jwt.adoc

:_mod-docs-content-type: PROCEDURE
[id="serverless-ossm-v2x-jwt_{context}"]
= Configuring JSON Web Token authentication for {SMProductShortName} 2.x and {ServerlessProductName}

[IMPORTANT]
====
Adding sidecar injection to pods in system namespaces, such as `knative-serving` and `knative-serving-ingress`, is not supported when Kourier is enabled.

ifdef::openshift-enterprise[]
If you require sidecar injection for pods in these namespaces, see the {ServerlessProductName} documentation on _Integrating {SMProductShortName} with {ServerlessProductName} natively_.
endif::[]
====

.Prerequisites

* You have installed the {ServerlessOperatorName}, Knative Serving, and {SMProductName} 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 {product-title}.

.Procedure

. Add the `sidecar.istio.io/inject="true"` annotation to your service:
+
.Example service
[source,yaml]
----
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 {ServerlessProductName} versions 1.14.0 and higher use an HTTP probe as the readiness probe for Knative services by default.

. Apply the `Service` resource:
+
[source,terminal]
----
$ oc apply -f <filename>
----

. Create a `RequestAuthentication` resource in each serverless application namespace that is a member in the `ServiceMeshMemberRoll` object:
+
[source,yaml]
----
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:
+
[source,terminal]
----
$ 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:
+
[source,yaml]
----
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:
+
[source,terminal]
----
$ oc apply -f <filename>
----

. For each serverless application namespace that is a member in the `ServiceMeshMemberRoll` object, create the following `AuthorizationPolicy` resource:
+
[source,yaml]
----
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:
+
[source,terminal]
----
$ oc apply -f <filename>
----

.Verification

. If you try to use a `curl` request to get the Knative service URL, it is denied:
+
.Example command
[source,terminal]
----
$ curl http://hello-example-1-default.apps.mycluster.example.com/
----
+
.Example output
[source,terminal]
----
RBAC: access denied
----

. Verify the request with a valid JWT.
.. Get the valid JWT token:
+
[source,terminal]
----
$ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.8/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
----
.. Access the service by using the valid token in the `curl` request header:
+
[source,terminal]
----
$ curl -H "Authorization: Bearer $TOKEN"  http://hello-example-1-default.apps.example.com
----
+
The request is now allowed:
+
.Example output
[source,terminal]
----
Hello OpenShift!
----
