diff --git a/.spelling b/.spelling
index b10f7a0525ef..37e496612486 100644
--- a/.spelling
+++ b/.spelling
@@ -228,6 +228,8 @@ Cernich
CFP
Chaomeng
Chavali
+CheckRequest
+CheckResponse
checksum
Chircop
Chrony
@@ -750,6 +752,7 @@ Kumar
Kustomization
Kustomize
kustomize
+Kyverno
kyzy
L2-L4
L3-4
diff --git a/content/en/docs/ops/integrations/kyverno-authz-server/dynamic-metadata.svg b/content/en/docs/ops/integrations/kyverno-authz-server/dynamic-metadata.svg
new file mode 100644
index 000000000000..e86d327e6181
--- /dev/null
+++ b/content/en/docs/ops/integrations/kyverno-authz-server/dynamic-metadata.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/en/docs/ops/integrations/kyverno-authz-server/filters-chain.svg b/content/en/docs/ops/integrations/kyverno-authz-server/filters-chain.svg
new file mode 100644
index 000000000000..b59f7756dc97
--- /dev/null
+++ b/content/en/docs/ops/integrations/kyverno-authz-server/filters-chain.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/content/en/docs/ops/integrations/kyverno-authz-server/index.md b/content/en/docs/ops/integrations/kyverno-authz-server/index.md
new file mode 100644
index 000000000000..955e44d03a4e
--- /dev/null
+++ b/content/en/docs/ops/integrations/kyverno-authz-server/index.md
@@ -0,0 +1,464 @@
+---
+title: Kyverno Authz Server
+description: How to integrate with Kyverno Authz Server.
+weight: 33
+keywords: [integration,kyverno,policy,authorization]
+owner: istio/wg-environments-maintainers
+test: no
+---
+
+The [Kyverno Authz Server](https://kyverno.github.io/kyverno-envoy-plugin) is a GRPC authorization server implementing the [Envoy's External Authorization protocol](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto).
+
+Istio and the Kyverno Authz Server is a solid option to deliver policy quickly and transparently to application team everywhere in the business, while also providing the data the security teams need for audit and compliance.
+
+## Try it out
+
+This guide shows how to enforce access control policies for a simple microservices application.
+
+### Prerequisites
+
+- A Kubernetes cluster with Istio installed.
+- The `istioctl` command-line tool installed.
+
+Install Istio and configure your [mesh options](/docs/reference/config/istio.mesh.v1alpha1/) to enable Kyverno:
+
+{{< text bash >}}
+$ istioctl install -y -f - <}}
+
+Notice that in the configuration, we define an `extensionProviders` section that points to the Kyverno Authz Server installation:
+
+{{< text yaml >}}
+[...]
+ extensionProviders:
+ - name: kyverno-authz-server
+ envoyExtAuthzGrpc:
+ service: kyverno-authz-server.kyverno.svc.cluster.local
+ port: '9081'
+[...]
+{{< /text >}}
+
+#### Deploy the Kyverno Authz Server
+
+The Kyverno Authz Server is a GRPC server capable of processing Envoy External Authorization requests.
+
+It is configurable using Kyverno `AuthorizationPolicy` resources, either stored in-cluster or provided externally.
+
+{{< text bash >}}
+$ kubectl create ns kyverno
+{{< /text >}}
+
+{{< text bash >}}
+$ kubectl label namespace kyverno istio-injection=enabled
+{{< /text >}}
+
+{{< text bash >}}
+$ helm install kyverno-authz-server --namespace kyverno --wait --repo https://kyverno.github.io/kyverno-envoy-plugin kyverno-authz-server
+{{< /text >}}
+
+#### Deploy the sample application
+
+httpbin is a well-known application that can be used to test HTTP requests and helps to show quickly how we can play with the request and response attributes.
+
+{{< text bash >}}
+$ kubectl create ns my-app
+{{< /text >}}
+
+{{< text bash >}}
+$ kubectl label namespace my-app istio-injection=enabled
+{{< /text >}}
+
+{{< text bash >}}
+$ kubectl apply -f {{< github_file >}}/samples/httpbin/httpbin.yaml -n my-app
+{{< /text >}}
+
+#### Deploy an Istio AuthorizationPolicy
+
+An `AuthorizationPolicy` defines the services that will be protected by the Kyverno Authz Server.
+
+{{< text bash >}}
+$ kubectl apply -f - <}}
+
+Notice that in this resource, we define the Kyverno Authz Server `extensionProvider` you set in the Istio configuration:
+
+{{< text yaml >}}
+[...]
+ provider:
+ name: kyverno-authz-server
+[...]
+{{< /text >}}
+
+#### Label the app to enforce the policy
+
+Let’s label the app to enforce the policy. The label is needed for the Istio `AuthorizationPolicy` to apply to the sample application pods.
+
+{{< text bash >}}
+$ kubectl patch deploy httpbin -n my-app --type=merge -p='{
+ "spec": {
+ "template": {
+ "metadata": {
+ "labels": {
+ "ext-authz": "enabled"
+ }
+ }
+ }
+ }
+}'
+{{< /text >}}
+
+#### Deploy a Kyverno AuthorizationPolicy
+
+A Kyverno `AuthorizationPolicy` defines the rules used by the Kyverno Authz Server to make a decision based on a given Envoy [CheckRequest](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#service-auth-v3-checkrequest).
+
+It uses the [CEL language](https://github.com/google/cel-spec) to analyze an incoming `CheckRequest` and is expected to produce a [CheckResponse](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto#service-auth-v3-checkresponse) in return.
+
+The incoming request is available under the `object` field, and the policy can define `variables` that will be made available to all `authorizations`.
+
+{{< text bash >}}
+$ kubectl apply -f - <
+ variables.allowed
+ ? envoy.Allowed().Response()
+ : envoy.Denied(403).Response()
+EOF
+{{< /text >}}
+
+Notice that you can build the `CheckResponse` by hand or use [CEL helper functions](https://kyverno.github.io/kyverno-envoy-plugin/latest/cel-extensions/) like `envoy.Allowed()` and `envoy.Denied(403)` to simplify creating the response message:
+
+{{< text yaml >}}
+[...]
+ - expression: >
+ variables.allowed
+ ? envoy.Allowed().Response()
+ : envoy.Denied(403).Response()
+[...]
+{{< /text >}}
+
+## How it works
+
+When applying the `AuthorizationPolicy`, the Istio control plane (istiod) sends the required configurations to the sidecar proxy (Envoy) of the selected services in the policy.
+Envoy will then send the request to the Kyverno Authz Server to check if the request is allowed or not.
+
+{{< image width="75%" link="./overview.svg" alt="Istio and Kyverno Authz Server" >}}
+
+The Envoy proxy works by configuring filters in a chain. One of those filters is `ext_authz`, which implements an external authorization service with a specific message. Any server implementing the correct protobuf can connect to the Envoy proxy and provide the authorization decision; The Kyverno Authz Server is one of those servers.
+
+{{< image link="./filters-chain.svg" alt="Filters" >}}
+
+Reviewing [Envoy's Authorization service documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/service/auth/v3/external_auth.proto), you can see that the message has these attributes:
+
+- Ok response
+
+ {{< text json >}}
+ {
+ "status": {...},
+ "ok_response": {
+ "headers": [],
+ "headers_to_remove": [],
+ "response_headers_to_add": [],
+ "query_parameters_to_set": [],
+ "query_parameters_to_remove": []
+ },
+ "dynamic_metadata": {...}
+ }
+ {{< /text >}}
+
+- Denied response
+
+ {{< text json >}}
+ {
+ "status": {...},
+ "denied_response": {
+ "status": {...},
+ "headers": [],
+ "body": "..."
+ },
+ "dynamic_metadata": {...}
+ }
+ {{< /text >}}
+
+This means that based on the response from the authz server, Envoy can add or remove headers, query parameters, and even change the response body.
+
+We can do this as well, as documented in the [Kyverno Authz Server documentation](https://kyverno.github.io/kyverno-envoy-plugin).
+
+## Testing
+
+Let's test the simple usage (authorization) and then let's create a more advanced policy to show how we can use the Kyverno Authz Server to modify the request and response.
+
+Deploy an app to run curl commands to the httpbin sample application:
+
+{{< text bash >}}
+$ kubectl apply -n my-app run -f {{< github_file >}}/samples/curl/curl.yaml
+{{< /text >}}
+
+Apply the policy:
+
+{{< text bash >}}
+$ kubectl apply -f - <
+ variables.allowed
+ ? envoy.Allowed().Response()
+ : envoy.Denied(403).Response()
+EOF
+{{< /text >}}
+
+The simple scenario is to allow requests if they contain the header `x-force-authorized` with the value `enabled` or `true`.
+If the header is not present or has a different value, the request will be denied.
+
+In this case, we combined allow and denied response handling in a single expression. However it is possible to use multiple expressions, the first one returning a non null response will be used by the Kyverno Authz Server, this is useful when a rule doesn't want to make a decision and delegate to the next rule:
+
+{{< text yaml >}}
+[...]
+ authorizations:
+ # allow the request when the header value matches
+ - expression: >
+ variables.allowed
+ ? envoy.Allowed().Response()
+ : null
+ # else deny the request
+ - expression: >
+ envoy.Denied(403).Response()
+[...]
+{{< /text >}}
+
+### Simple rule
+
+The following request will return `403`:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get
+{{< /text >}}
+
+The following request will return `200`:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get -H "x-force-authorized: true"
+{{< /text >}}
+
+### Advanced manipulations
+
+Now the more advanced use case, apply the second policy:
+
+{{< text bash >}}
+$ kubectl apply -f - < 401
+ - expression: >
+ variables.force_unauthenticated
+ ? envoy
+ .Denied(401)
+ .WithBody("Authentication Failed")
+ .Response()
+ : null
+ # if force_authorized -> 200
+ - expression: >
+ variables.force_authorized
+ ? envoy
+ .Allowed()
+ .WithHeader("x-validated-by", "my-security-checkpoint")
+ .WithoutHeader("x-force-authorized")
+ .WithResponseHeader("x-add-custom-response-header", "added")
+ .Response()
+ .WithMetadata(variables.metadata)
+ : null
+ # else -> 403
+ - expression: >
+ envoy
+ .Denied(403)
+ .WithBody("Unauthorized Request")
+ .Response()
+EOF
+{{< /text >}}
+
+In that policy, you can see:
+
+- If the request has the `x-force-unauthenticated: true` header (or `x-force-unauthenticated: enabled`), we will return `401` with the "Authentication Failed" body
+- Else, if the request has the `x-force-authorized: true` header (or `x-force-authorized: enabled`), we will return `200` and manipulate request headers, response headers and inject dynamic metadata
+- In all other cases, we will return `403` with the "Unauthorized Request" body
+
+The corresponding CheckResponse will be returned to the Envoy proxy from the Kyverno Authz Server. Envoy will use those values to modify the request and response accordingly.
+
+#### Change returned body
+
+Let's test the new capabilities:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get
+{{< /text >}}
+
+Now we can change the response body.
+
+With `403` the body will be changed to "Unauthorized Request", running the previous command, you should receive:
+
+{{< text plain >}}
+Unauthorized Request
+http_code=403
+{{< /text >}}
+
+#### Change returned body and status code
+
+Running the request with the header `x-force-unauthenticated: true`:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get -H "x-force-unauthenticated: true"
+{{< /text >}}
+
+This time you should receive the body "Authentication Failed" and error `401`:
+
+{{< text plain >}}
+Authentication Failed
+http_code=401
+{{< /text >}}
+
+#### Adding headers to request
+
+Running a valid request:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -w "\nhttp_code=%{http_code}" httpbin:8000/get -H "x-force-authorized: true"
+{{< /text >}}
+
+You should receive the echo body with the new header `x-validated-by: my-security-checkpoint` and the header `x-force-authorized` removed:
+
+{{< text plain >}}
+[...]
+ "X-Validated-By": [
+ "my-security-checkpoint"
+ ]
+[...]
+http_code=200
+{{< /text >}}
+
+#### Adding headers to response
+
+Running the same request but showing only the header:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -I -w "\nhttp_code=%{http_code}" httpbin:8000/get -H "x-force-authorized: true"
+{{< /text >}}
+
+You will find the response header added during the Authz check `x-add-custom-response-header: added`:
+
+{{< text plain >}}
+HTTP/1.1 200 OK
+[...]
+x-add-custom-response-header: added
+[...]
+http_code=200
+{{< /text >}}
+
+### Sharing data between filters
+
+Finally, you can pass data to the following Envoy filters using `dynamic_metadata`.
+
+This is useful when you want to pass data to another `ext_authz` filter in the chain or you want to print it in the application logs.
+
+{{< image link="./dynamic-metadata.svg" alt="Metadata" >}}
+
+To do so, review the access log format you set earlier:
+
+{{< text plain >}}
+[...]
+ accessLogFormat: |
+ [KYVERNO DEMO] my-new-dynamic-metadata: "%DYNAMIC_METADATA(envoy.filters.http.ext_authz)%"
+[...]
+{{< /text >}}
+
+`DYNAMIC_METADATA` is a reserved keyword to access the metadata object. The rest is the name of the filter that you want to access.
+
+In our case, the name `envoy.filters.http.ext_authz` is created automatically by Istio. You can verify this by dumping the Envoy configuration:
+
+{{< text bash >}}
+$ istioctl pc all deploy/httpbin -n my-app -oyaml | grep envoy.filters.http.ext_authz
+{{< /text >}}
+
+You will see the configurations for the filter.
+
+Let's test the dynamic metadata. In the advance rule, we are creating a new metadata entry: `{"my-new-metadata": "my-new-value"}`.
+
+Run the request and check the logs of the application:
+
+{{< text bash >}}
+$ kubectl exec -n my-app deploy/curl -- curl -s -I httpbin:8000/get -H "x-force-authorized: true"
+{{< /text >}}
+
+{{< text bash >}}
+$ kubectl logs -n my-app deploy/httpbin -c istio-proxy --tail 1
+{{< /text >}}
+
+You will see in the output the new attributes configured by the Kyverno policy:
+
+{{< text plain >}}
+[...]
+[KYVERNO DEMO] my-new-dynamic-metadata: '{"my-new-metadata":"my-new-value","ext_authz_duration":5}'
+[...]
+{{< /text >}}
+
+## Wrap Up
+
+In this guide, we have shown how to integrate Istio and the Kyverno Authz Server to enforce policies for a simple microservices application.
+We also showed how to use policies to modify the request and response attributes.
diff --git a/content/en/docs/ops/integrations/kyverno-authz-server/overview.svg b/content/en/docs/ops/integrations/kyverno-authz-server/overview.svg
new file mode 100644
index 000000000000..dfd06e4a01a5
--- /dev/null
+++ b/content/en/docs/ops/integrations/kyverno-authz-server/overview.svg
@@ -0,0 +1 @@
+
\ No newline at end of file