diff --git a/assets/agw-docs/snippets/agentgateway/helm.md b/assets/agw-docs/snippets/agentgateway/helm.md
index 9b6a12312..07bb2b46c 100644
--- a/assets/agw-docs/snippets/agentgateway/helm.md
+++ b/assets/agw-docs/snippets/agentgateway/helm.md
@@ -38,7 +38,7 @@
3. Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart.
- 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings]({{< link-hextra path="/advanced">}}).
+ 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings]({{< link-hextra path="/install/advanced/">}}).
```sh
helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}}
diff --git a/assets/docs/examples/httpbin.yaml b/assets/docs/examples/httpbin.yaml
deleted file mode 100644
index dbe8679ab..000000000
--- a/assets/docs/examples/httpbin.yaml
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright Istio Authors
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-##################################################################################################
-# httpbin service
-##################################################################################################
-apiVersion: v1
-kind: ServiceAccount
-metadata:
- name: httpbin
----
-apiVersion: v1
-kind: Service
-metadata:
- name: httpbin
- labels:
- app: httpbin
- service: httpbin
-spec:
- ports:
- - name: http
- port: 8000
- targetPort: 8080
- - name: tcp
- port: 9000
- selector:
- app: httpbin
----
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- name: httpbin
-spec:
- replicas: 1
- selector:
- matchLabels:
- app: httpbin
- version: v1
- template:
- metadata:
- labels:
- app: httpbin
- version: v1
- spec:
- serviceAccountName: httpbin
- containers:
- - image: docker.io/mccutchen/go-httpbin:v2.6.0
- imagePullPolicy: IfNotPresent
- name: httpbin
- command: [ go-httpbin ]
- args:
- - "-port"
- - "8080"
- - "-max-duration"
- - "600s" # override default 10s
- ports:
- - containerPort: 8080
- # Include curl container for e2e testing, allows sending traffic mediated by the proxy sidecar
- - name: curl
- image: curlimages/curl:7.83.1
- resources:
- requests:
- cpu: "100m"
- limits:
- cpu: "200m"
- imagePullPolicy: IfNotPresent
- command:
- - "tail"
- - "-f"
- - "/dev/null"
- - name: hey
- image: gcr.io/solo-public/docs/hey:0.1.4
- imagePullPolicy: IfNotPresent
\ No newline at end of file
diff --git a/assets/docs/examples/petstore.yaml b/assets/docs/examples/petstore.yaml
deleted file mode 100644
index 2f2adf338..000000000
--- a/assets/docs/examples/petstore.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-##########################
-# #
-# Example #
-# Service #
-# #
-# #
-##########################
-# petstore service
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- labels:
- app: petstore
- name: petstore
- namespace: default
-spec:
- selector:
- matchLabels:
- app: petstore
- replicas: 1
- template:
- metadata:
- labels:
- app: petstore
- spec:
- containers:
- - image: soloio/petstore-example:latest
- name: petstore
- ports:
- - containerPort: 8080
- name: http
----
-apiVersion: v1
-kind: Service
-metadata:
- name: petstore
- namespace: default
- labels:
- service: petstore
-spec:
- ports:
- - name: http
- port: 8080
- protocol: TCP
- selector:
- app: petstore
\ No newline at end of file
diff --git a/assets/docs/pages/about/architecture.md b/assets/docs/pages/about/architecture.md
deleted file mode 100644
index 423906bff..000000000
--- a/assets/docs/pages/about/architecture.md
+++ /dev/null
@@ -1,83 +0,0 @@
-Learn more about the components that make up the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control and data plane. These components work together to provide traffic management, security, and resiliency for your apps.
-
-## Component architecture
-
-The following image shows the different components that make up the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} and {{< gloss "Data Plane" >}}data plane{{< /gloss >}}. These components work together to translate gateway custom resources into gateway {{< gloss "Proxy" >}}proxy{{< /gloss >}} configuration. The gateway proxy configuration controls the behavior of the gateway proxies that serve your apps.
-
-{{< reuse-image src="img/agw-control-plane-components.svg" caption="Component architecture" >}}
-{{< reuse-image-dark srcDark="img/agw-control-plane-components-dark.svg" caption="Component architecture" >}}
-
-
-
-1. The config and secret watcher components in the `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}` pod watch the cluster for new Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources, such as Gateways, HTTPRoutes, or TrafficPolicies.
-2. When the config or secret watcher detect new or updated resources, it sends the resource configuration to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Translation" >}}translation{{< /gloss >}} engine.
-3. The translation engine translates Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources into gateway proxy configuration. All gateway proxy configuration is consolidated into an xDS snapshot.
-4. The reporter receives a status report for every resource that is processed by the translator.
-5. The reporter writes the resource status back to the etcd data store.
-6. The xDS snapshot is provided to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} xDS server component in the `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}` pod.
-7. Gateway proxies in the cluster pull the latest gateway proxy configuration from the {{< reuse "/agw-docs/snippets/kgateway.md" >}} xDS server.
-8. Clients send a request to the IP address or hostname that the gateway proxy is exposed on.
-9. The gateway proxy uses the listener and route-specific configuration that was provided in the xDS snapshot to perform routing decisions and forward requests to destinations in the cluster.
-
-### Config watcher
-
-The config watcher component is part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and watches the cluster for new or updated Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources, such as Gateways, HTTPRoutes, and Backends. When the config watcher detects new or updated resources, it sends the Kubernetes configuration to the {{< reuse "/agw-docs/snippets/kgateway.md" >}} translation engine.
-
-### Secret watcher
-
-The secret watcher component is part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and watches a secret store for updates to secrets. For example, you might use a Kubernetes Secret to store the AWS access key and secret key credentials for a Backend to access an AWS Lambda. However, you can configure {{< reuse "/agw-docs/snippets/kgateway.md" >}} to also watch other secret stores.
-
-
-
-### Translation engine
-
-The {{< reuse "/agw-docs/snippets/kgateway.md" >}} translator receives snapshots of all the Kubernetes Gateway API, Kubernetes API, and {{< reuse "/agw-docs/snippets/kgateway.md" >}} resources that you create or update. The translator starts a new translation loop for each update to translate these resources into valid gateway proxy configuration. The gateway proxy configuration is stored in an xDS snapshot.
-
-The following image shows the different stages of a translation cycle for the gateway proxy.
-
-
-
-{{< reuse-image src="img/agw-translation-loop.svg" caption="Agentgateway translation cycle" >}}
-{{< reuse-image-dark srcDark="img/agw-translation-loop-dark.svg" caption="Agentgateway translation cycle" >}}
-
-1. When the agentgateway feature is enabled for {{< reuse "/agw-docs/snippets/kgateway.md" >}}, the agentgateway syncer component is created as part of the control plane.
-
-2. The agentgateway syncer sets up the initial configuration, including the `agentgateway` GatewayClass name that Gateways can use to automatically create agentgateway proxies. The agentgateway syncer also builds the initial krt collections based on the Gateway API and kgateway resources in the cluster.
-
-3. The translation cycle starts by collecting all of the resources that are needed to create agentgateway proxy config. These various collections include:
- * Core collections of the Kubernetes, Gateway API, and kgateway resources that are defined in the cluster, such as namespaces, services, gateways, routes, policies, backends, and plugins for AI, MCP, and A2A-specific backends.
- * Agentgateway data plane resource building that consist of information translated from the core collection into the format that agentgateway expects, such as bind, port, listener, route, backend, target, and policy configuration for agentgateway. For more information, see the [agentgateway about topic](../../agentgateway/about/#resources).
- * Address collections of the service and workloads that are included in service discovery and endpoint resolution.
- * The translation order ensures that dependencies are resolved correctly: `binds → listeners → routes → policies`, with backends and addresses processed separately and added to the final configuration.
-
-4. The next step in the translation process is to build the xDS collection. This step merges all of the resource config of agentgateway data plane resources together with the address collections to create the config for each agentgateway proxy. It also builds status reports for the resources, tracks attached routes, and determines attached policies.
-
-5. Finally, the information from the resource and xDS collections are turned into an xDS snapshot of the agentgateway proxy config. The snapshot is sent to the xDS server. The agentgateway proxies in your cluster watch the xDS server for new config. When new config is detected, the config is pulled into the agentgateway proxy via gRPC.
-
-### Reporter
-
-The reporter component receives a validation report for every {{< reuse "/agw-docs/snippets/kgateway.md" >}} resource that was processed by the translator. Any invalid configuration is reported back to the user through the Kubernetes storage layer. Invalid resources are marked as `rejected` and an error message is captured in the resource configuration.
-
-### xDS server
-
-The xDS server sends the xDS snapshot to the gateway proxies in the data plane.
-
-{{< icon "agentgateway" >}} **Agentgateway proxy**: Updates the agentgateway proxy with agentgateway-specific configuration, including MCP and A2A protocol support, to match the desired state.
-
-
-
diff --git a/assets/docs/pages/about/backendconfigpolicy.md b/assets/docs/pages/about/backendconfigpolicy.md
deleted file mode 100644
index b752bca52..000000000
--- a/assets/docs/pages/about/backendconfigpolicy.md
+++ /dev/null
@@ -1,80 +0,0 @@
-Use a BackendConfigPolicy resource to configure connection settings for a backend.
-
-## Policy attachment {#policy-attachment-backendconfigpolicy}
-
-You can apply BackendConfigPolicies to individual Kubernetes services, any backend that matches a specific label, or a global service in your ambient mesh.
-
-{{< callout type="info" >}}
-By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide.
-{{< /callout >}}
-
-### Individual backend {#attach-to-backend}
-
-You can use the `spec.targetRefs` section in the BackendConfigPolicy resource to apply policies to a specific backend, such as a Kubernetes Service or a {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
-The following example BackendConfigPolicy resource specifies connection settings for the `httpbin` service.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy
- namespace: httpbin
-spec:
- targetRefs:
- - name: httpbin
- group: ""
- kind: Service
- connectTimeout: 5s
- perConnectionBufferLimitBytes: 1024
-```
-
-### Backends with specific label {#label-selector}
-
-Instead of applying the policy to a specific service or {{< reuse "agw-docs/snippets/backend.md" >}}, you can also use a label selector to apply the policy to all services or {{< reuse "agw-docs/snippets/backend.md" >}}s that match the label.
-
-The following example shows a BackendConfigPolicy resource that applies connection settings to all Kubernetes services that have the `app: httpbin` and `service: httpbin` labels.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy
- namespace: httpbin
-spec:
- targetSelectors:
- - group: networking.istio.io
- kind: Service
- matchLabels:
- app: httpbin
- service: httpbin
- connectTimeout: 5s
- commonHttpProtocolOptions:
- maxHeadersCount: 15
- maxRequestsPerConnection: 100
-```
-
-### Global service {#istio-global}
-
-If you use {{< reuse "agw-docs/snippets/kgateway.md" >}} with an Istio ambient mesh and you exposed services across multiple clusters by using the `solo.io/service-scope=global` label, Istio automatically creates ServiceEntry resources in each of your clusters that use the same global hostname. You can then use the global hostname to send and load balance requests across multiple clusters.
-
-To apply connection settings to all service instances that are exposed by this global hostname, you can apply a BackendConfigPolicy to an Istio hostname as shown in the following example.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy-alias
- namespace: gwtest
-spec:
- targetSelectors:
- - group: networking.istio.io
- kind: Hostname
- matchLabels:
- app: httpbin
- service: httpbin
- connectTimeout: 5s
- commonHttpProtocolOptions:
- maxHeadersCount: 15
- maxRequestsPerConnection: 100
-```
diff --git a/assets/docs/pages/about/custom-resources.md b/assets/docs/pages/about/custom-resources.md
deleted file mode 100644
index d45eb98d9..000000000
--- a/assets/docs/pages/about/custom-resources.md
+++ /dev/null
@@ -1,76 +0,0 @@
-Learn about the custom resources that make up {{< reuse "/agw-docs/snippets/kgateway.md" >}} and how they interact with each other.
-
-## Custom resource overview
-
-{{< reuse "agw-docs/snippets/cr-ov.md" >}}
-
-
-
-## Kubernetes Gateway API resources {#k8s}
-
-Review the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} resources that you use to set up gateway proxies and configure routing for your apps.
-
-For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} introduction](https://gateway-api.sigs.k8s.io/#introduction).
-
-### Gateway and GatewayClass
-
-The [Gateway](https://gateway-api.sigs.k8s.io/api-types/gateway/) custom resource is a network abstraction that defines a point of access at which traffic can be forwarded to a backend in a {{< gloss "Cluster (Kubernetes)" >}}Kubernetes cluster{{< /gloss >}}. A Gateway defines the listeners that you want to open, including the ports, protocols, and hostnames that you want to listen on for incoming traffic. You can also specify how incoming, encrypted traffic is handled. For example, encrypted traffic can be terminated at the gateway or passed through to a backend in the cluster.
-
-To spin up a Gateway and manage its lifecycle, a gateway controller is used. The gateway controller is defined in the [GatewayClass](https://gateway-api.sigs.k8s.io/api-types/gatewayclass/) resource and manages the underlying infrastructure to ensure that traffic to endpoints is routed accordingly. When you install kgateway, a GatewayClass resource is automatically created that points to the kgateway controller. For more information, see [GatewayClass]({{< link-hextra path="/setup/default/#gatewayclass" >}}).
-
-### HTTPRoute and TCPRoute {#httproute}
-
-To configure routing, the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides several routing resources, such as an HTTPRoute and TCPRoute. These routes attach to a Gateway resource and define how incoming traffic is matched and forwarded to a backing destination.
-
-* [HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/): The most commonly used route resource, that configures traffic routing for HTTP and HTTPS traffic.
-* [TCPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute): A resource to route TCP requests.
-
-While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} provides the functionality for basic request matching, redirects, rewrites, and header manipulation, it is missing more complex traffic management, resiliency, and security features, such as transformations, access logging, or route delegation.
-
-You can extend the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} features by leveraging the [kgateway-native policy custom resources](#policies). Policies allow you to apply intelligent traffic management, resiliency, and security standards to an HTTPRoute or Gateway.
-
-### Kubernetes Services
-
-Kubernetes Services expose Kubernetes pods within and outside a Kubernetes cluster so that other network endpoints can communicate with them. In the context of the Kubernetes Gateway API, the Kubernetes Service represents an app within the cluster that you want to route traffic to from outside the cluster. The Service is referenced in the HTTPRoute resource, including the port that you want to send traffic to.
-
-If traffic matches the conditions that are defined in the HTTPRoute, the Gateway forwards traffic to the Kubernetes Service that is referenced in the HTTPRoute.
-
-### ReferenceGrant
-
-A [ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) allows a Kubernetes Gateway API resource, such as an HTTPRoute, to reference resources that exist in other namespaces. For example, if you create an HTTPRoute resource in `namespace1`, but the Kubernetes Service or Backend that you want to route to is in `namespace2`, you must create a ReferenceGrant to allow communication between these resources.
-
-
-
-## Kgateway resources {#kgateway}
-
-Review the kgateway resources that you use to bootstrap, configure, and customize your gateway proxy, and the policies that you can leverage to add additional traffic management, resiliency, and security capabilities to your gateway and routes.
-
-### GatewayExtensions
-
-A {{< gloss "Gateway Extension" >}}GatewayExtension{{< /gloss >}} is a {{< reuse "/agw-docs/snippets/kgateway.md" >}} Custom Resource that serves as a configuration bridge between {{< reuse "/agw-docs/snippets/kgateway.md" >}} and external services that extend a Gateway's functionality. These external services provide additional capabilities like authentication (`extAuth`), rate limiting (`rateLimit`), and request processing (`extProc`). TrafficPolicies can then refer to the GatewayExtension with the external service that the policy needs to be enforced. For more information, see the [API docs]({{< link-hextra path="/reference/api/#gatewayextension" >}}).
-
-### {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
-
-When you create a Gateway resource, a [default gateway proxy template](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}{{< reuse "agw-docs/versions/github-kgateway-deployment.md" >}}) is used to automatically spin up and bootstrap a gateway proxy deployment and service in your cluster. The template includes Envoy configuration that binds the gateway proxy deployment to the Gateway resource that you created. In addition, the settings in the {{< gloss "GatewayParameters" >}}{{< reuse "agw-docs/snippets/gatewayparameters.md" >}}{{< /gloss >}} resource are used to configure the gateway proxy.
-
-To learn more about the default gateway setup and how these resource interact with each other, see [Default gateway proxy setup]({{< link-hextra path="/setup/default/" >}}).
-
-### Policies
-
-While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} allows you to do simple routing, such as to match, redirect, or rewrite requests, you might want additional capabilities in your API gateway, such as access logging or transformations. [Policies]({{< link-hextra path="/about/policies/" >}}) allow you to apply intelligent traffic management, resiliency, and security standards to HTTPRoutes or Gateways.
-
-Kgateway uses the following custom resources to attach policies to routes and gateway listeners:
-
-* [**DirectResponse**]({{< link-hextra path="/traffic-management/direct-response/" >}}): Directly respond to incoming requests with a custom HTTP response code and body.
-* [**HTTPListenerPolicy**]({{< link-hextra path="/about/policies/httplistenerpolicy/" >}}): Apply policies to all HTTP and HTTPS listeners.
-* [**TrafficPolicy**](https://kgateway.dev/docs/envoy/main/about/policies/trafficpolicy/): Attach policies to routes in an HTTPRoute resource.
-
-### {{< reuse "agw-docs/snippets/backend.md" >}}s
-
-For workloads within your cluster, you can can route incoming traffic to their Kubernetes Service. But what if you have external services such as static hostnames or AWS Lambda functions that you want to route traffic to?
-
-You can use a {{< reuse "agw-docs/snippets/backend.md" >}} resource to accomplish this task. Similar to using Kubernetes Services, you reference the {{< reuse "agw-docs/snippets/backend.md" >}} in your HTTPRoute resource. For more information, see [{{< reuse "agw-docs/snippets/backend.md" >}}s]({{< link-hextra path="/traffic-management/destination-types/backends/" >}}).
diff --git a/assets/docs/pages/about/deployment-patterns.md b/assets/docs/pages/about/deployment-patterns.md
deleted file mode 100644
index 5b36deb1d..000000000
--- a/assets/docs/pages/about/deployment-patterns.md
+++ /dev/null
@@ -1,79 +0,0 @@
-Learn how you can deploy gateway proxies to ensure proper traffic routing, security, and isolation for your apps.
-
-The flexibility of {{< reuse "/agw-docs/snippets/kgateway.md" >}} allows you to deploy it in a way that best serves your environment. Review the following recommended deployment patterns to choose how to set up gateway proxies.
-
-## API Gateway and ingress controller
-
-Use the gateway proxy as a fast and flexible Kubernetes-native ingress controller and next-generation API gateway to aggregate and provide uniform access to your APIs.
-
-### Simple ingress
-
-The following image shows a gateway proxy that serves as a single ingress API gateway to the workloads in a Kubernetes cluster. The gateway is centrally managed by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and configured to match and forward traffic based on the traffic management, resiliency, and security rules that you define.
-
-{{% reuse-image src="img/pattern-simple-ingress.svg" width="400px" caption="Simple ingress" %}}
-{{% reuse-image-dark srcDark="img/pattern-simple-ingress.svg" width="400px" caption="Simple ingress" %}}
-
-
-
-This setup is a great way to get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}, and is suitable for smaller environments where all workloads run in a single cluster and traffic is balanced between services. However, in larger environments or environments where you have both high traffic and low traffic services, consider adding [multiple gateway proxies to distribute traffic load more evenly](#sharded-gateway).
-
-### Sharded gateway {#sharded-gateway}
-
-In larger environments or environments where you have both high traffic and low traffic services, you can isolate services from each other and protect against noisy neighbors by using a sharded gateway. With a sharded gateway architecture, you typically have multiple gateway proxies that split up the traffic for different services in the cluster as depicted in the following image.
-
-{{% reuse-image src="img/pattern-sharded-gateway.svg" width="400px" caption="Sharded gateway" %}}
-{{% reuse-image-dark srcDark="img/pattern-sharded-gateway.svg" width="400px" caption="Sharded gateway" %}}
-
-
-
-All gateway proxies are managed by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane. However, one gateway proxy manages traffic for the workloads in the `foo` and `bar` namespaces. The second gateway proxy is a dedicated API gateway for the workloads in the `extra` namespace. Both gateway proxies are exposed directly on the edge.
-
-While this setup is great to split up and load balance traffic across apps, you might not want the gateway proxies to be exposed directly on the edge. Instead, you might want a central ingress gateway proxy that applies common traffic management, resiliency, and security rules, and that forwards traffic to other gateway proxies that are dedicated to certain apps, teams, or namespaces. To learn more about this deployment pattern, see [Sharded gateway with central ingress](#sharded-gatway-with-central-ingress).
-
-
-### Sharded gateway with central ingress {#sharded-gatway-with-central-ingress}
-
-The following image shows a gateway proxy that serves as the main ingress endpoint for all traffic. The gateway proxy can be configured to apply common traffic management, resiliency, and security rules to all traffic that enters the cluster. For example, you can set header manipulation policies on that gateway before you forward traffic to a second layer of gateway proxies. This is useful if you need a central IP address and DNS name for the gateway that serves all your traffic.
-
-The second layer of gateway proxies can apply additional traffic management, resiliency, and security policies to incoming traffic for specific apps. You also shard the second layer of proxies to better account for high and low traffic services to avoid noisy neighbor problems. All gateway proxies are managed by the same {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane.
-
-{{% reuse-image src="img/pattern-central-ingress-gloo.svg" width="600px" %}}
-{{% reuse-image-dark srcDark="img/pattern-central-ingress-gloo.svg" width="600px" %}}
-
-
-
-Depending on your existing setup, you might want to use a different type of proxy as your central ingress endpoint. For example, you might have an HAProxy or AWS NLB/ALB instance that all traffic must go through. Kgateway can be paired with these types of proxies as depicted in the following image.
-
-{{% reuse-image src="img/pattern-central-ingress-any.svg" width="600px" %}}
-{{% reuse-image-dark srcDark="img/pattern-central-ingress-any.svg" width="600px" %}}
-
-
-
-## Service mesh gateway
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} integrates seamlessly with your Istio service mesh so that you can control and manage ingress, egress, and mesh-internal traffic.
-
-### Ambient mesh
-
-You can deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an ingress, egress, or waypoint proxy gateway for the workloads in an Istio ambient mesh. An ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed.
-
-The following image shows a gateway proxy that is exposed on the edge and serves traffic for the ambient mesh. Services in the mesh communicate with each other via mutual TLS (mTLS).
-
-{{% reuse-image src="img/ambient-ingress.svg" width="600px" %}}
-{{% reuse-image-dark srcDark="img/ambient-ingress.svg" width="600px" %}}
-
-
-
-For more information, see the guides for using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an [ingress gateway](../../integrations/istio/ambient/ambient-ingress/) or [waypoint proxy](../../integrations/istio/ambient/waypoint/) for your ambient mesh.
-
-### Sidecar mesh
-
-You can deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} with an Istio sidecar to route traffic to services in an Istio sidecar mesh. The following image shows a gateway proxy that is exposed on the edge and serves traffic for the sidecar mesh. Services in the mesh communicate with each other via mutual TLS (mTLS) by using the istio-proxy sidecar that is injected into the app. The sidecar is represented with the Envoy logo in the image.
-
-{{< reuse-image src="img/sidecar-ingress.svg" width="800px" >}}
-{{< reuse-image-dark srcDark="img/sidecar-ingress.svg" width="800px" >}}
-
-
-
-For more information, see the guide for using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an [ingress gateway](../../integrations/istio/sidecar/ingress/) to your sidecar mesh.
-
diff --git a/assets/docs/pages/about/httplistenerpolicy.md b/assets/docs/pages/about/httplistenerpolicy.md
deleted file mode 100644
index 0f402d11e..000000000
--- a/assets/docs/pages/about/httplistenerpolicy.md
+++ /dev/null
@@ -1,122 +0,0 @@
-You can use an HTTPListenerPolicy resource to attach policies to HTTP or HTTPS listeners on the gateway.
-
-{{< callout type="info" >}}
-By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide.
-{{< /callout >}}
-
-## Policy attachment {#policy-attachment-listeneroption}
-
-
-
-You can apply a policy to all HTTP and HTTPS listeners that are defined on the gateway by using the `spec.targetRefs` section in the HTTPListenerPolicy resource.
-
-The following HTTPListenerPolicy resource configures access logs on a Gateway that is named `http`. The policy applies to all the HTTP and HTTPS listeners that are defined on the gateway.
-
-```yaml {hl_lines=[7,8,9,10]}
-apiVersion: gateway.kgateway.dev/v1alpha1
-kind: HTTPListenerPolicy
-metadata:
- name: access-logs
- namespace: kgateway-system
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- accessLog:
- - fileSink:
- path: /dev/stdout
- jsonFormat:
- start_time: "%START_TIME%"
- method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%"
- path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
- protocol: "%PROTOCOL%"
- response_code: "%RESPONSE_CODE%"
- response_flags: "%RESPONSE_FLAGS%"
- bytes_received: "%BYTES_RECEIVED%"
- bytes_sent: "%BYTES_SENT%"
- total_duration: "%DURATION%"
- resp_backend_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
- req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%"
- user_agent: "%REQ(USER-AGENT)%"
- request_id: "%REQ(X-REQUEST-ID)%"
- authority: "%REQ(:AUTHORITY)%"
- backendHost: "%UPSTREAM_HOST%"
- backendCluster: "%UPSTREAM_CLUSTER%"
-```
-
-
-
-## Conflicting policies
-
-If you create multiple HTTPListenerPolicy resources that define the same type of top-level policy, and attach them to the same gateway by using the `targetRefs` option, only the HTTPListenerPolicy that was last applied is enforced.
-
-
\ No newline at end of file
diff --git a/assets/docs/pages/about/overview.md b/assets/docs/pages/about/overview.md
deleted file mode 100644
index 15b15afa2..000000000
--- a/assets/docs/pages/about/overview.md
+++ /dev/null
@@ -1,103 +0,0 @@
-{{< reuse "agw-docs/snippets/kgateway-about.md" >}}
-
-In this topic, you learn about the basics of API gateways for microservices, the extensions that {{< reuse "/agw-docs/snippets/kgateway.md" >}} provides beyond typical API gateway functionality, and the default API gateway proxy setup.
-
-{{< callout icon="agentgateway" >}}
-Looking for an AI gateway to connect agents, MCP tools, and LLMs? Check out the [agentgateway data plane docs](../../agentgateway/). {{< reuse "agw-docs/snippets/control-plane-note.md" >}}
-{{< /callout >}}
-
-## API gateway {#api-gateway}
-
-The {{< reuse "/agw-docs/snippets/kgateway.md" >}} data plane is a feature-rich, fast, and flexible Kubernetes-native [ingress controller](#what-is-an-ingress) and next-generation [API gateway](#what-is-an-api-gateway) that is built on top of [Envoy proxy](https://www.envoyproxy.io/) and the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api).
-
-### What is an ingress?
-
-An ingress, edge router, or application gateway, is a service that is accessible to the Internet, and routes traffic to services running inside a Kubernetes environment. Traditionally, this service was managed by a Kubernetes object also called an `Ingress`, and as such “ingress” in a Kubernetes context normally refers to an operator configuration where a control plane configures a hardware or software proxy server. The traffic can include API traffic, but can also include general traffic like web pages and images.
-
-Examples of Kubernetes ingresses include ingress-nginx and Contour.
-
-Kgateway includes full Kubernetes ingress functionality, providing its own control plane, using the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api) as its configuration language and Envoy as its proxy server.
-
-### What are the components of an ingress?
-
-There are three major components that make up any ingress solution:
-
-* control plane
-* data plane
-* configuration language
-
-The [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}](#what-is-the-kubernetes-gateway-api) is a project designed to standardize the configuration language, replacing the legacy `Ingress` API with an extensible API.
-
-Ingress projects therefore differentiate on their data plane — there are solutions built on top of Envoy, HAProxy, NGINX, Traefik and more — and the performance, scalability and features of their control plane.
-
-
-
-### What is an API?
-
-An application programming interface (API) is a method to allow a machine to talk to a machine. Contrast APIs with user interfaces (UIs), which allow a human to talk to a machine.
-
-Today, an API most commonly refers to a web API, a method using HTTP (or a derivative like gRPC) to provide access to machine readable data in a format like JSON or XML. Web APIs are sometimes referred to as web services, which is where Amazon Web Services (AWS) gets its name.
-
-As an example, take a look at the API for NASA's popular [Astronomy Picture of the Day](https://apod.nasa.gov/apod/astropix.html) service. The most common way that humans access this service is through the UI that is the NASA website. However, if you want a machine to use this service, you can also use the API.
-
-To start, you [generate an API key](https://api.nasa.gov/) that gives access to the API. Then, you set up your program to perform an HTTP GET request to the API endpoint: `https://api.nasa.gov/planetary/apod?api_key=$YOUR_API_KEY`.
-
-As with most APIs, the Astronomy Picture of the Day API also includes parameters that you can use in the request to get back more specific responses, such as the date. Typically, parameters have default values if you don't include them, such as today's date. To find out the available parameters and more, you use the [API documentation](https://github.com/nasa/apod-api?tab=readme-ov-file#docs-).
-
-### What is an API gateway?
-
-An API gateway is a service that provides centralized gateway functionality for API traffic. The concept that took off as microservices architectures were growing in popularity in the 2005-2015 era, with early vendors such as 3scale, WSO2 and Apigee targeting backends that were run on Java. As Kubernetes became popular, the need arose to offer API gateway functionality that integrated with it. This led to the launch of Gloo, which is the original name of kgateway.
-
-In the NASA example, recall that you had to provide an API key to access the service. This is a way of identifying you to the API, which can then be used to enable decision-making.
-
-Some functions an API gateway might perform include:
-
-* **Routing and aggregation**: Similar to an ingress, make APIs from different backend services (including serverless functions) available at a single endpoint, behind a single API key.
-* **Load balancing**: Send requests to backend services, based on their load.
-* **Rate limiting:** Limit the number of users that can call certain APIs, based on parameters such as identity, load, or cost.
-* **Security**: Provide authentication and authorization, and Web Application Firewall functionality.
-* **Logging and monitoring**: Track and display usage in order to provide visibility into the system to help with use cases such as API management, debugging, and accurate billing data.
-
-### Are ingresses API gateways?
-
-Although a necessary component, ingress functionality by itself is not sufficient for a project to be considered an API gateway.
-
-Traditionally an ingress primarily handles routing and aggregation, with Kubernetes providing load balancing. If you hear the phrase “application gateway,” it’s probably acting as a gateway for the website UI. Although APIs are web traffic and are often published through an ingress, you don’t have the full range of features in a UI-focused application gateway as you would in an API gateway.
-
-### What is the Kubernetes Gateway API?
-
-The {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} is a common, extensible standard for traffic management in Kubernetes. It is quickly becoming the standard interface for defining routing and policy for cloud native networking, addressing many shortcomings of its predecessor, the Ingress API, and unifying best practices that have evolved through real-world usage.
-
-[Learn about the history of the Gateway API](/blog/introduction-to-kubernetes-gateway-api/), or [watch our in-depth video series](/resources/videos/).
-
-Kgateway is fully conformant with the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} and extends its functionality with custom extension APIs, such as TrafficPolicies, ListenerPolicies, and Backends. These custom resources help to centrally configure advanced traffic management, security, and resiliency rules for an HTTPRoute or Gateway listener.
-
-### Is the Gateway API an API gateway?
-
-No, but this demonstrates why [naming things](https://www.karlton.org/2017/12/naming-things-hard/) is hard!
-
-The Gateway API is an API which can be used to program an ingress or an API gateway.
-
-## Extensions
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} provides the following extensions on top of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} to configure advanced routing, security, and resiliency capabilities.
-
-{{< cards >}}
- {{< card link="../../security/access-logging/" title="Access logging" tag="Security" >}}
- {{< card link="../../integrations/aws-elb/" title="AWS ALB and NLB" tag="Traffic" >}}
- {{< card link="../../traffic-management/destination-types/backends/lambda" title="AWS Lambda" tag="Traffic" >}}
- {{< card link="../../traffic-management/route-delegation/" title="Delegation" tag="Traffic" >}}
- {{< card link="../../traffic-management/direct-response/" title="Direct responses" tag="Traffic" >}}
- {{< card link="../../traffic-management/ext/" title="Direct responses" tag="Traffic" >}}
- {{< card link="../../setup/customize/" title="Gateway customization" tag="Setup" >}}
- {{< card link="../../integrations/" title="Integrations" tag="Setup" >}}
- {{< card link="../../resiliency/mirroring/" title="Mirroring" tag="Resiliency" >}}
- {{< card link="../../traffic-management/transformations/" title="Transformations" tag="Traffic" >}}
- {{< card link="../../traffic-management/weighted-routes/" title="Weighted routing" tag="Traffic" >}}
-{{< /cards >}}
-
-## Default gateway proxy setup
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} automatically spins up, bootstraps, and manages gateway proxy deployments when you create a Kubernetes Gateway resource. To do that, a combination of kgateway and Kubernetes resources are used, such as GatewayClass, GatewayParameters, and a gateway proxy template that includes the Envoy configuration that each proxy is bootstrapped with.
-
-To learn more about the default setup and how these resources interact with each other, see the [Default gateway proxy setup]({{< link-hextra path="/setup/default/" >}}).
diff --git a/assets/docs/pages/about/policies-index.md b/assets/docs/pages/about/policies-index.md
deleted file mode 100644
index b571348d1..000000000
--- a/assets/docs/pages/about/policies-index.md
+++ /dev/null
@@ -1,41 +0,0 @@
-Learn more about the custom resources that you can use to apply policies in kgateway.
-
-
-While the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} allows you to do simple routing, such as to match, redirect, or rewrite requests, you might want additional capabilities in your API gateway, such direct responses, local rate limiting, or request and response transformations. Policies allow you to apply intelligent traffic management, resiliency, and security standards to an HTTPRoute or Gateway.
-
-## Policy CRDs
-
-Kgateway uses the following custom resources to attach policies to routes and gateway listeners.
-
-
-{{< cards >}}
- {{< card link="../policies/backendconfigpolicy/" title="BackendConfigPolicy" subtitle="Configure connection settings to an upstream service." >}}
- {{< card link="../../traffic-management/direct-response/" title="Direct response" subtitle="Directly respond to incoming requests with a custom HTTP response code and body." >}}
- {{< card link="../policies/httplistenerpolicy/" title="HTTPListenerPolicy" subtitle="Apply policies to all HTTP and HTTPS listeners." >}}
- {{< card link="../policies/trafficpolicy/" title="TrafficPolicy" subtitle="Attach policies to routes in an HTTPRoute or Gateway resource." >}}
-{{< /cards >}}
-
-
-
-## Supported policies {#supported-policies}
-
-Review the policies that you can configure in kgateway and the level at which you can apply them.
-
-| Policy | Applied via |
-| -- | -- |
-| [Access logging](../../security/access-logging) | HTTPListenerPolicy |
-| [Buffering](../../traffic-management/buffering)| {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
-| [CSRF](../../security/csrf)| {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
-| [Direct response](../../traffic-management/direct-response/) | DirectResponse |
-| [Dynamic Forward Proxy (DFP)](../../traffic-management/dfp)| Backend and HTTPRoute |
-| [External authorization](../../security/external-auth) | GatewayExtension and {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
-| [External processing (ExtProc)](../../traffic-management/extproc/) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
-| [Health checks for the Gateway](../../traffic-management/health-checks/gateway)| HTTPListenerPolicy |
-| [Health checks for the Backends](../../traffic-management/health-checks/backend)| BackendConfigPolicy |
-| [HTTP connection settings](../../resiliency/connection)| BackendConfigPolicy |
-| [Outlier detection](../../resiliency/outlier-detection)| BackendConfigPolicy |
-| [Rate limiting](../../security/ratelimit/) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
-| [Session affinity - Simple load balancing](../../traffic-management/session-affinity/loadbalancing/) | BackendConfigPolicy |
-| [Session affinity - Consistent hashing](../../traffic-management/session-affinity/consistent-hashing/) | BackendConfigPolicy |
-| [TCP keepalive](../../resiliency/tcp-keepalive/) | BackendConfigPolicy |
-| [Transformations](../../traffic-management/transformations) | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
\ No newline at end of file
diff --git a/assets/docs/pages/about/policy-merging.md b/assets/docs/pages/about/policy-merging.md
deleted file mode 100644
index d86cb85e5..000000000
--- a/assets/docs/pages/about/policy-merging.md
+++ /dev/null
@@ -1,86 +0,0 @@
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} lets you define how policies are merged when they are applied to a parent and child resource.
-
-## About
-
-Parent-child hierarchies might be:
-
-* Resources that target or serve other resources, such as Gateway > ListenerSet > HTTPRoute > Route rule.
-* Routes that are delegated, such as Parent HTTPRoute A > Child HTTPRoute B > Grandchild HTTPRoute C.
-
-Policy merging applies to the following policies:
-
-* Native Kubernetes Gateway API policies, such as rewrites, timeouts, or retries.
-* {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
-
-Resources that are higher in the parent-child hierarchy can use a special annotation to define how child resources inherit policies. This way, parent resources such as a Gateway or HTTPRoute can decide whether child resources can override the parent policies or not.
-
-## Merging annotation {#merging-annotation}
-
-The annotation on the parent resource is: `kgateway.dev/inherited-policy-priority`.
-
-You can use the following values for the annotation:
-
-- `ShallowMergePreferChild` (default): Child policies take precedence over parent policies and the policies are shallow merged.
-- `ShallowMergePreferParent`: Parent policies take precedence over child policies and the policies are shallow merged.
-
-**Shallow merging** means that the policies are merged at the top level. Only the top-level fields of the policies are considered for merging. If a field is present in both parent and child policies, the value from the higher priority policy is used. Priority is typically determined by specificity and creation time. The more specific (such as HTTPRoute rule over all the routes in the HTTPRoute) and older (created-first) policy takes precedence. Consider the following shallow merge scenario:
-
-* Parent policy adds a `x-season=summer` header.
-* Child policy adds `x-season=winter` and `x-holiday=christmas` headers.
-* Merging annotation is the default value, `ShallowMergePreferChild`.
-
-Resulting merged policy: The parent's `x-season` header is not included in the merged policy because the strategy is `ShallowMergePreferChild`.
-
-| Header | Value | Source |
-| -- | -- | -- |
-| `x-season` | `winter` | Child |
-| `x-holiday` | `christmas` | Child |
-
-
-
-## Merging examples {#merging-examples}
-
-For more information, check out the following guides:
-
-* {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s [Policy priority and merging rules](../trafficpolicy/#policy-priority-and-merging-rules)
-* [Policy inheritance and overrides](../../../traffic-management/route-delegation/inheritance/) for both Kubernetes Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} policies.
\ No newline at end of file
diff --git a/assets/docs/pages/about/proxies.md b/assets/docs/pages/about/proxies.md
deleted file mode 100644
index 04c2a15d5..000000000
--- a/assets/docs/pages/about/proxies.md
+++ /dev/null
@@ -1,36 +0,0 @@
-Learn more about the gateway proxies that the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} supports.
-
-## About gateway proxies {#about}
-
-Gateway proxies are the {{< gloss "Data Plane" >}}data plane{{< /gloss >}} in your {{< reuse "/agw-docs/snippets/kgateway.md" >}} setup. The data plane handles traffic between clients and servers, or backend applications.
-
-The type of gateway proxy that you want to use depends on your use case, which is often related to the backend applications and the "direction" of the traffic.
-
-Backend applications are commonly accessed by clients through application programming interfaces (APIs). Hence, an "API gateway" is a common use case for a gateway proxy. For more information, see the [API gateway overview topic](../overview/#api-gateway). If the client is outside your cluster, you need an ingress gateway to handle this "north-south" traffic. If the client is within the cluster or service mesh, you need an "east-west" gateway. To control traffic that leaves your environment, you need an egress gateway.
-
-Increasingly, gateway proxies are designed to meet the challenges that are specific to artificial intelligence (AI) networking. In these scenarios, your backend applications might be cloud provider large language models (LLMs), your own LLMs and inferences, model context protocol (MCP) servers, agent-to-agent (A2A) servers, and similar AI use cases.
-
-The best gateway proxies offer you ways to configure advanced routing, load balancing, security enforcement, protocol translation, and more. They also generate metrics and logs that you can use to monitor and troubleshoot your traffic.
-
-## Architecture
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} is a control plane that manages the lifecycle of gateway proxies that adhere to the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io) spec.
-
-When you install {{< reuse "/agw-docs/snippets/kgateway.md" >}}, you automatically get GatewayClasses out of the box. When you create a Gateway resource based on one of these GatewayClasses, {{< reuse "/agw-docs/snippets/kgateway.md" >}} automatically spins up a gateway proxy for you. The gateway proxy controls the data plane that routes traffic to the backend services. {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} then configures the data plane based on the Gateway API and {{< reuse "/agw-docs/snippets/kgateway.md" >}} custom resources that you configure, such as HTTPRoutes and TrafficPolicies. This way, you can standardize the configuration of your gateway proxies with the same set of open source resources.
-
-For more information, see the other docs in this [About](../) section.
-
-## Supported gateway proxies {#supported}
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} supports the following gateway proxies. You can use both gateway proxies in the same Kubernetes cluster, depending on your use case.
-
-{{< reuse "agw-docs/snippets/control-plane-note.md" >}}
-
-| Gateway proxy | Primary use cases | Description |
-| --- | --- | --- |
-| {{< icon "kgateway" >}} kgateway | API, ingress, egress, service mesh | The kgateway project includes its own proxy that is based on Envoy, an L3/L4/L7 network proxy. Beyond Envoy, kgateway provides a set of extensions for advanced configuration, security, and traffic management features. You can also integrate kgateway with the Istio service mesh in sidecar and ambient modes. For more information, see the [kgateway FAQs](../../faqs/) and [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/intro/what_is_envoy). |
-| {{< icon "agentgateway" >}} agentgateway | AI, A2A, MCP, LLM, Inference Extension | Agentgateway is an enterprise-grade gateway data plane that provides AI connectivity for agents and tools in any environment.
For Kubernetes deployments, refer to [agentgateway.dev/docs/kubernetes/](https://agentgateway.dev/docs/kubernetes/)
For non-Kubernetes environments such as local or on-prem deployments, refer to [agentgateway.dev/docs/local/](https://agentgateway.dev/docs/local/)
|
-
-## Reserved ports
-
-{{< reuse "agw-docs/snippets/reserved-ports.md" >}}
\ No newline at end of file
diff --git a/assets/docs/pages/about/trafficpolicy.md b/assets/docs/pages/about/trafficpolicy.md
deleted file mode 100644
index 3cec25aeb..000000000
--- a/assets/docs/pages/about/trafficpolicy.md
+++ /dev/null
@@ -1,322 +0,0 @@
-Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to attach policies to one, multiple, or all routes in an HTTPRoute resource, or all the routes that a Gateway serves.
-
-## Policy attachment {#policy-attachment-TrafficPolicy}
-
-You can apply {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} to all routes in an HTTPRoute resource or only to specific routes.
-
-{{< callout type="info" >}}
-By default, you must attach policies to resources that are in the same namespace. To create global policies that can attach to resources in any namespace, see the [Global policy attachment](../global-attachment/) guide.
-{{< /callout >}}
-
-### All HTTPRoute routes {#attach-to-all-routes}
-
-You can use the `spec.targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to apply policies to all the routes that are specified in a particular HTTPRoute resource.
-
-The following example {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource specifies transformation rules that are applied to all routes in the `httpbin` HTTPRoute resource.
-
-```yaml {hl_lines=[7,8,9,10]}
-apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: transformation
- namespace: httpbin
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin
- transformation:
- response:
- set:
- - name: x-kgateway-response
- value: '{{ request_header("x-kgateway-request") }}'
-```
-
-You can also apply the same {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to multiple HTTPRoutes by referencing them in the `targetRefs` section, as shown in the following example.
-
-```yaml {hl_lines=[7,8,9,10,11,12,13,14,15,16]}
-apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: transformation
- namespace: httpbin
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: petstore
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: echo
- transformation:
- response:
- set:
- - name: x-kgateway-response
- value: '{{ request_header("x-kgateway-request") }}'
-```
-
-
-### Individual route {#attach-to-route}
-
-Instead of applying the policy to all routes that are defined in an HTTPRoute resource, you can apply them to specific routes by using the `ExtensionRef` filter in the HTTPRoute resource.
-
-{{< callout type="warning" >}}
-Attaching a policy via the `ExtensionRef` filter is legacy behavior and might be deprecated in a future release. Instead, use the [HTTPRoute rule attachment option](#attach-to-rule) to apply a policy to an individual route, which requires the Kubernetes Gateway API experimental channel version 1.3.0 or later. Also, the `ExtensionRef` filter is not supported for agentgateway proxies.
-{{< /callout >}}
-
-The following example shows a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource that defines a transformation rule. Note that the `spec.targetRef` field is not set. Because of that, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} does not apply until it is referenced in an HTTPRoute by using the `ExtensionRef` filter.
-
-```yaml
-apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: transformation
- namespace: httpbin
-spec:
- transformation:
- response:
- set:
- - name: x-kgateway-response
- value: '{{ request_header("x-kgateway-request") }}'
-```
-
-To apply the policy to a particular route, you use the `ExtensionRef` filter on the desired HTTPRoute route. In the following example, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} is applied to the `/anything/path1` route. However, it is not applied to the `/anything/path2` path.
-
-```yaml {hl_lines=[17,18,19,20,21,22]}
-apiVersion: gateway.networking.k8s.io/v1
-kind: HTTPRoute
-metadata:
- name: httpbin-policy
- namespace: httpbin
-spec:
- parentRefs:
- - name: http
- namespace: kgateway-system
- hostnames:
- - TrafficPolicy.example
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /anything/path1
- filters:
- - type: ExtensionRef
- extensionRef:
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- name: transformation
- backendRefs:
- - name: httpbin
- port: 8000
- - matches:
- - path:
- type: PathPrefix
- value: /anything/path2
- backendRefs:
- - name: httpbin
- port: 8000
-```
-
-### HTTPRoute rule {#attach-to-rule}
-
-{{< callout type="info" >}}
-To use this feature, you must install the Kubernetes Gateway API experimental channel version 1.3.0 or later.
-{{< /callout >}}
-
-Instead of using the `extensionRef` filter to apply a policy to a specific route, you can attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to an HTTPRoute rule by using the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s `targetRefs.sectionName` option.
-
-You can also use this attachment option alongside the `extensionRef` filter. However, policies that are attached via the `extensionRef` filter take precedence over policies that are attached via the `targetRefs.sectionName` option.
-
-The following HTTPRoute defines two HTTPRoute rules that both route traffic to the httpbin app.
-```yaml
-kubectl apply -f- <}} to a specific HTTPRoute rule (`rule1`), use the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}'s `targetRefs.sectionName` option as shown in the following example.
-
-```yaml
-kubectl apply -f- <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: local-ratelimit
- namespace: kgateway-system
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin
- sectionName: rule1
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
-EOF
-```
-
-### Gateway {#attach-to-gateway}
-
-Some policies, such as a local rate limiting policy, can be applied to all the routes that the Gateway serves. This way, you can apply gateway-level rules and do not have to keep track of new HTTPRoutes that are attached to the Gateway in your environment.
-
-To attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a Gateway, you simply use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to reference the Gateway you want the policy to apply to as shown in the following example.
-
-```yaml
-apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: local-ratelimit
- namespace: kgateway-system
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
-```
-
-### Gateway listener {#attach-to-listener}
-
-Instead of applying a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to all the routes that the Gateway serves, you can select specific Gateway listeners by using the `targetRefs.sectionName` option.
-
-The following Gateway resource defines two listeners, an HTTP (`http`) and HTTPS (`https`) listener.
-
-```yaml
-kind: Gateway
-apiVersion: gateway.networking.k8s.io/v1
-metadata:
- name: http
- namespace: kgateway-system
-spec:
- gatewayClassName: kgateway
- listeners:
- - name: http
- protocol: HTTP
- port: 8080
- allowedRoutes:
- namespaces:
- from: All
- - name: https
- port: 443
- protocol: HTTPS
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
-```
-
-To apply the policy to only the `https` listener, you specify the listener name in the `spec.targetRefs.sectionName` field in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource as shown in the following example.
-
-```yaml
-apiVersion: {{< reuse "agw-docs/snippets/trafficpolicy-apiversion.md" >}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: local-ratelimit
- namespace: kgateway-system
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- sectionName: https
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
-```
-
-## Policy priority and merging rules
-
-If you apply multiple {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} by using different attachment options, policies are merged based on specificy and priority.
-
-By default, the following rules apply. You can update the behavior by using the `kgateway.dev/inherited-policy-priority` annotation. For more information, see [Policy merging]({{< link-hextra path="/about/policies/merging/" >}}).
-
-* If you apply multiple {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} that define the same top-level policy, the policies are not merged and only the oldest policy is enforced. Policies with a later timestamp are ignored.
-* {{< reuse "agw-docs/snippets/trafficpolicies.md" >}} that define different top-level policies are merged and are enforced in combination.
-* In addition to the timestamp, the attachment option of a policy determines the policy priority. In general, more specific policy targets have higher priority and take precedence over less specific policies. For example, a policy targeting an individual route has higher priority than a policy targeting all the routes in an HTTPRoute resource. However, keep in mind that these rules might be different in a route delegation setup. For more information, see [Policy inheritance and overrides in delegation setups](#delegation).
-* Lower priority policies can augment higher priority policies by defining other top-level policies. For example, if you already attached a local rate limiting policy to a Gateway listener by using the `targetRefs.sectionName` option, you can add another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that defines a transformation policy and apply that policy to the entire Gateway.
-* Native Kubernetes Gateway API policies have higher priority than any kgateway-native policies that must be attached via the `targetRefs` or `extensionRef` option.
-
-### Priority order
-
-Review the following Gateway and HTTPRoute policy priorities, sorted from highest to lowest.
-
-**Gateway**:
-
-| Priority | Attachment option | Description |
-| -- | -- | -- |
-| 1 | [Gateway listener policy](#attach-to-listener) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that references a Gateway listener by using the `targetRefs.sectionName` field has the highest priority. Note that if you have multiple Gateway listener policies that define the same top-level policy, only the one with the oldest timestamp is applied. |
-| 2 | [Gateway policy](#attach-to-gateway) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that references a Gateway in the `targetRefs` section has the lowest priority. This policy can still augment any higher priority policies by defining different top-level policies. Note that if you have multiple Gateway policies that all define the same top-level policy, only the one with the oldest timestamp is applied. |
-
-**HTTPRoute**:
-
-| Priority | Attachment option | Description |
-| -- | -- | -- |
-| 1 | [Individual HTTPRoute policy](#attach-to-route) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to an individual route by using the `extensionRef` filter in the HTTPRoute has the highest priority. Note that if you have multiple HTTPRoute policies that are attached via the `extensionRef` option and all define the same top-level policy, only the one with the oldest timestamp is applied. |
-| 2 | [HTTPRoute rule policy](#attach-to-rule) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to an HTTPRoute rule by using the `targetRefs.sectionName` option has a lower priority. This policy can still augment any `extensionRef` policies by defining different top-level policies. Note that if you have multiple HTTPRoute rule policies and all define the same top-level policy, only the one with the oldest timestamp is applied. |
-| 3 | [All HTTPRoute routes policy](#attach-to-all-routes) | A {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that is attached to all routes in an HTTPRoute resource by using the `targetRefs` option has the lowest priority. You can still augment any higher priority policies by defining different top-level policies. If you have multiple HTTPRoute rule policies and they all specify the same top-level policy, only the one with the oldest timestamp is applied. |
-
-{{< callout type="info" >}}
-If you apply a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with the same top-level policy to a Gateway and an HTTPRoute, the policy on the HTTPRoute takes precedence and the one on the Gateway is ignored. For example, you might have two local rate limiting policies. One is applied to a Gateway and one is applied to the HTTPRoute. Because the same top-level policy is defined, the policy on the HTTPRoute is considered higher priority and therefore enforced.
-{{< /callout >}}
-
-### Policy inheritance and overrides in delegation setups {#delegation}
-
-The way policies are inherited along the route delegation chain depends on the type of policy that you want to apply.
-
-#### Native Gateway API policies
-
-{{< reuse "agw-docs/snippets/policy-inheritance-native.md" >}}
-
-For an example, see the policy inheritance guide for [Native Gateway API policies]({{< link-hextra path="/traffic-management/route-delegation/inheritance/native-policies/" >}}).
-
-#### Kgateway policies
-
-{{< reuse "agw-docs/snippets/policy-inheritance.md" >}}
-
-For an example, see the policy inheritance guide for [kgateway policies]({{< link-hextra path="/traffic-management/route-delegation/inheritance/kgateway-policies/" >}}).
-
diff --git a/assets/docs/pages/agentgateway/about.md b/assets/docs/pages/agentgateway/about.md
deleted file mode 100644
index df6e1f742..000000000
--- a/assets/docs/pages/agentgateway/about.md
+++ /dev/null
@@ -1,45 +0,0 @@
-{{< reuse "agw-docs/snippets/agentgateway/about.md" >}}
-
-Agentgateway supports many agent connectivity use cases, including the following:
-
-* Agent-to-agent (A2A)
-* Model Context Protocol (MCP)
-* REST APIs as agent-native tools
-* AI routing to cloud and local large language models (LLMs)
-* Support for the Gateway API Inference Extension project
-
-## Architecture
-
-For more information about how kgateway integrates with agentgateway, see the [Architecture](../../about/architecture/) topic.
-
-For more information about agentgateway resources, see the [Agentgateway upstream docs](https://agentgateway.dev/docs/about/).
-
-## Agentgateway resource configuration {#resources}
-
-Review the following table to understand how to configure agentgateway resources in {{< reuse "/agw-docs/snippets/kgateway.md" >}}.
-
-| Agentgateway resource | Description | Configured in {{< reuse "/agw-docs/snippets/kgateway.md" >}} by |
-| -- | -- | -- |
-| Bind | The set of port bindings that associate gateway listeners with specific network ports. The bind has a unique key in the format `port/namespace/name`, such as `8080/default/my-gateway` with the value being the port number, such as `8080`. | Created automatically based on the Gateway and each unique port across Gateway listeners or ListenerSets. |
-| Port | The port to listen on. Each port has a set of listeners that in turn have their own routes with policies and backends. | Ports in a Gateway or ListenerSet. |
-| Listener | Listener configuration for how agentgateway accepts and processes incoming requests.
Unique key for the listener
Name that maps to the section name from the Gateway listener
Bind key of the bind that the listener is part of
Gateway name
Hostname that the listener accepts traffic for
Protocol (HTTP, HTTPS, TCP, TLS)
TLS configuration details such as certificates and termination modes
Listeners can each have their own set of routes with policies and backends. | Listeners in a Gateway or ListenerSet. |
-| Route | Routing rules for how agentgateway routes incoming requests to the appropriate backend.
Unique key in the format: `namespace.name.rule.match`
Route name in the format: `namespace/name`
Listener key of the listener that the route is part of
Rule name from the source route
Traffic matching criteria (path, headers, method, query params) that are derived from the Gateway API routing resources
Filters that transform request and responses, such as header modification, redirects, rewrites, mirroring, and other policies
Target backend services with load balancing and health checking
Hostnames that the route serves traffic for
| Routing resources such as HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute. |
-| Backend | The backing destination where traffic is routed. Unlike other resources, backends are global resources (not per-gateway) that are applied to all Gateways that use agentgateway. Each backend has a unique name in the format: `namespace/name`. Backend types include AI for model-specific LLM provider configuration, static host or IP addresses, and virtual MCP servers, including A2A use cases. | Services and Backends. |
-| Target | The details of the backend, such as the tools in an MCP backend. | Services and Backends. |
-| Policies | Policies for how agentgateway processes incoming requests.
Request Header Modifier: Add, set, or remove HTTP request headers.
Response Header Modifier: Add, set, or remove HTTP response headers.
Request Redirect: Redirect incoming requests to a different scheme, authority, path, or status code.
URL Rewrite: Rewrite the authority or path of requests before forwarding.
Request Mirror: Mirror a percentage of requests to an additional backend for testing or analysis.
CORS: Configure Cross-Origin Resource Sharing (CORS) settings for allowed origins, headers, methods, and credentials.
A2A: Enable agent-to-agent (A2A) communication features.
Backend Auth: Set up authentication for backend services such as passthrough, key, GCP, AWS, and so on.
Timeout: Set request and backend timeouts.
Retry: Configure retry attempts, backoff, and which response codes should trigger retries.
| Policies in HTTPRoutes and Backends. |
-
-
-
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/agent/a2a.md b/assets/docs/pages/agentgateway/agent/a2a.md
deleted file mode 100644
index a3bb65ef7..000000000
--- a/assets/docs/pages/agentgateway/agent/a2a.md
+++ /dev/null
@@ -1,236 +0,0 @@
-With {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can route to agent-to-agent (A2A) servers and expose their tools securely.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-
-
-## Step 1: Deploy an A2A server {#a2a-server}
-
-Deploy an A2A server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. Notice that the Service uses the `appProtocol: kgateway.dev/a2a` setting. This way, {{< reuse "agw-docs/snippets/kgateway.md" >}} configures the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy to use the A2A protocol.
-
-```yaml
-kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: a2a-agent
- port: 9090
-EOF
-```
-
-## Step 3: Verify the connection {#verify}
-
-1. Get the agentgateway address.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. As a user, send a request to the A2A server. As an assistant, the agent echoes back the message that you sent.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -X POST http://$INGRESS_GW_ADDRESS/ \
- -H "Content-Type: application/json" \
- -v \
- -d '{
- "jsonrpc": "2.0",
- "id": "1",
- "method": "tasks/send",
- "params": {
- "id": "1",
- "message": {
- "role": "user",
- "parts": [
- {
- "type": "text",
- "text": "hello gateway!"
- }
- ]
- }
- }
- }' | jq
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- curl -X POST http://localhost:8080/ \
- -H "Content-Type: application/json" \
- -v \
- -d '{
- "jsonrpc": "2.0",
- "id": "1",
- "method": "tasks/send",
- "params": {
- "id": "1",
- "message": {
- "role": "user",
- "parts": [
- {
- "type": "text",
- "text": "hello gateway!"
- }
- ]
- }
- }
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```json
- {
- "jsonrpc": "2.0",
- "id": "1",
- "result": {
- "id": "1",
- "message": {
- "role": "assistant",
- "parts": [
- {
- "type": "text",
- "text": "hello gateway!"
- }
- ]
- }
- }
- }
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete Deployment a2a-agent
-kubectl delete Service a2a-agent
-kubectl delete HTTPRoute a2a
-```
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/agent/about.md b/assets/docs/pages/agentgateway/agent/about.md
deleted file mode 100644
index f83e68d82..000000000
--- a/assets/docs/pages/agentgateway/agent/about.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Learn about what agents are and how they work.
-
-## About A2A
-
-Agent-to-agent, or [A2A](https://github.com/a2aproject/A2A), is an open protocol that enables communication and interoperability between opaque agentic applications. Developed by Google, A2A defines a common language that enables agents to show their capabilities and help them negotiate how they interact with the user, such as via text, forms, or bidirectional audio or video, irrespective of the framework or vendor they are built on.
-
-With A2A, agents can:
-
-* Discover each other's capabilities.
-* Negotiate interaction modalities (text, forms, media).
-* Securely collaborate on long running tasks.
-* Operate without exposing their internal state, memory, or tools.
-
-## What are agents?
-
-An artificial intelligence (AI) agent is an application that can interact with users in natural language. Agents use LLM to generate responses to user queries and decide whether to call external tools to execute actions on behalf of the user.
-
-LLMs are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, consider the following question:
-
-> What's the weather today?
-
-The LLM has to know several pieces of real-time information that it was not trained on:
-
-* The user's location
-* The current date
-* The weather forecast for that date and location
-
-With agents and tools, you can extend the capabilities of the LLM with your own external APIs, apps, and data. First, you create _tools_ that extend the capabilities of the LLM with a function, such as `get_weather`. These functions can include _parameters_, or inputs, that are needed to execute the function. For example, the `get_weather` function needs the date and location to get the current weather forecast. The _name_ and _description_ of the tool function and parameters help the LLM decide when to call the tool.
-
-Next, when forwarding user requests to the LLM, you can include the set of tools that the LLM can leverage to answer the user. Based on the user's question, the LLM can respond directly or suggest a tool to call to help answer the question. To get the required parameters for the tool call, the LLM might ask the end user or call other functions like `get_location` or `get_date`, which in turn might pull that information based on system settings on the end user's device.
-
-### Agent sequence diagram {#diagram}
-
-Consider the following sequence diagram that shows how agents and tools work.
-
-```mermaid
-sequenceDiagram
- autonumber
- User->>+Agent: "What's the weather in Columbus?"
- Agent->>+LLM: Forward user request along with tool list
- LLM-->>-Agent: Suggest tool call (get_weather)
- Agent-->>+App: Send tool suggestion
- App->>-App: Execute tool (get_weather)
- App->>+Agent: Send tool result
- Agent->>+LLM: Forward tool result
- LLM-->>+Agent: Generate final response
- Agent-->>-User: "The weather in Columbus is 15°C and cloudy."
-```
-
-1. The User asks about the weather today. The request includes a list of tools that the LLM can use to answer the question.
-
-2. The agent sends the request with the tool list to the LLM.
-
-3. Based on the conversation, the LLM suggests to call the get_weather tool and includes the required parameters to use that tool. The LLM might get these parameters by using the chat history, asking the end user to provide them, or by suggesting other tools to call before calling the get_weather function.
-
-4. The agent invokes the get_weather tool by sending a request to the App. The request includes the required parameters to execute the tool.
-
-5. The App executes the get_weather tool with the required parameters to get the current weather in the location, such as Columbus, OH.
-
-6. The App returns the tool result to the agent.
-
-7. The agent returns the tool result to the LLM.
-
-8. The LLM uses the real-time tool result from the App in a natural language response and returns this response to the agent.
-
-9. The agent then forwards the natural language response to the User.
diff --git a/assets/docs/pages/agentgateway/configuration.md b/assets/docs/pages/agentgateway/configuration.md
deleted file mode 100644
index b7f33013e..000000000
--- a/assets/docs/pages/agentgateway/configuration.md
+++ /dev/null
@@ -1,208 +0,0 @@
-Customize your agentgateway proxy with {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}.
-
-## About customizing your proxy {#upstream-configuration}
-
-In upstream agentgateway, you can manage [configuration](https://agentgateway.dev/docs/configuration/overview/) via a YAML or JSON file. The configuration features of agentgateway are captured in the [schema of the agentgateway codebase](https://github.com/agentgateway/agentgateway/tree/main/schema).
-
-Unlike in the upstream agentgateway project, you do not configure these features in a raw configuration file in the agentgateway proxy. Instead, you configure them in a Kubernetes Gateway API-native way as explained in the guides throughout this doc set.
-
-However, you still might want to pass in custom configuration to your agentgateway proxy. This can be useful in the following use cases:
-
-- Migrating from upstream to {{< reuse "/agw-docs/snippets/agw-kgw.md" >}}.
-- Using a feature that is not yet exposed via the Kubernetes Gateway or {{< reuse "/agw-docs/snippets/agw-kgw.md" >}} APIs.
-
-
-
-You can choose between the following options to provide custom configuration to your agentgateway proxy.
-
-* **Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} CRD directly (recommended)**: You can add your custom configuration to the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom resource directly. This way, your configuration is validated when you apply the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource in your cluster. Keep in mind that not all upstream configuration options, such as `binds`, are currently supported in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. For supported options, see the [API reference]({{< link-hextra path="/reference/api/#agentgatewayparametersspec" >}}).
-* **`rawConfig`**: For configuration that cannot be embedded into the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource directly, or if you prefer to pass in raw upstream configuration, you can use the `rawConfig` option in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource instead. Note that configuration is not automatically validated. If configuration is malformatted or includes unsupported fields, the agentgateway proxy does not start. You can run `kubectl logs deploy/agentgateway-proxy -n agentgateway-system` to view the logs of the proxy and find more information about why the configuration could not be applied.
-
-
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}).
-
-## Step 1: Create agentgateway configuration {#agentgateway-configuration}
-
-
-
-
-Choose between the following options to provide your agentgateway configuration:
-
-* [Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}](#embed)
-* [`rawConfig`](#rawconfig)
-
-### Embed in {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} {#embed}
-
-You can add your custom configuration to the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom resource directly. This way, your configuration is validated when you apply the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource in your cluster.
-
-1. Create an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with your custom configuration. The following example changes the logging format from `text` to `json`.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- metadata:
- name: agentgateway-config
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- logging:
- format: json
- EOF
- ```
-
-2. Create a Gateway resource that sets up an agentgateway proxy that uses your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: agentgateway-config
- group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - name: http
- port: 3030
- protocol: HTTP
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-3. Check the pod logs to verify that the agentgateway logs are displayed in JSON format.
- ```sh
- kubectl logs deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```
- {"level":"info","time":"2025-12-16T15:58:18.245219Z","scope":"agent_core::readiness","message":"Task 'agentgateway' complete (2.378042ms), still awaiting 1 tasks"}
- {"level":"info","time":"2025-12-16T15:58:18.245221Z","scope":"agentgateway::management::hyper_helpers","message":"listener established","address":"127.0.0.1:15000","component":"admin"}
- {"level":"info","time":"2025-12-16T15:58:18.245231Z","scope":"agentgateway::management::hyper_helpers","message":"listener established","address":"[::]:15020","component":"stats"}
- {"level":"info","time":"2025-12-16T15:58:18.248025Z","scope":"agent_xds::client","message":"Stream established","xds":{"id":1}}
- {"level":"info","time":"2025-12-16T15:58:18.248081Z","scope":"agent_xds::client","message":"received response","type_url":"type.googleapis.com/agentgateway.dev.workload.Address","size":44,"removes":0,"xds":{"id":1}}
- ```
-
-### `rawConfig`
-
-Use the `rawConfig` option to pass in raw upstream configuration to your agentgateway proxy. Note that the configuration is not automatically validated. If configuration is malformatted or includes unsupported fields, the agentgateway proxy does not start. You can run `kubectl logs deploy/agentgateway-proxy -n agentgateway-system` to view the logs of the proxy and find more information about why the configuration could not be applied.
-
-1. Create an {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with your custom configuration. The following example sets up a simple direct response listener on port 3000 that returns a `200 OK` response with the body `"hello!"` for requests to the `/direct` path.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- metadata:
- name: agentgateway-config
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- rawConfig:
- binds:
- - port: 3000
- listeners:
- - protocol: HTTP
- routes:
- - name: direct-response
- matches:
- - path:
- pathPrefix: /direct
- policies:
- directResponse:
- body: "hello!"
- status: 200
- EOF
- ```
-
-2. Create a Gateway resource that sets up an agentgateway proxy that uses your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}. Set the port to a dummy value like `3030` to avoid conflicts with the binds defined in your {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: agentgateway-config
- group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - name: http
- port: 3030
- protocol: HTTP
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-3. Check the pod logs to verify that agentgateway loaded the configuration from the ConfigMap, such as by searching for the port binding.
-
- ```bash
- kubectl logs deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep 3000
- ```
-
- Example output:
-
- ```
- 2025-10-28T13:47:01.116095Z info proxy::gateway started bind bind="bind/3000"
- ```
-
-4. Send a test request.
-
- * **Cloud Provider LoadBalancer**:
- 1. Get the external address of the gateway proxy and save it in an environment variable.
-
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-config -o=jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
-
- 2. Send a request along the `/direct` path to the agentgateway proxy through port 3000.
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:3000/direct
- ```
- * **Port-forward for local testing**
- 1. Port-forward the `agentgateway-config` pod on port 3000.
- ```sh
- kubectl port-forward deployment/agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}} 3000:3000
- ```
-
- 2. Send a request to verify that you get back the expected response from your direct response configuration.
- ```sh
- curl -i localhost:3000/direct
- ```
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- content-length: 6
- date: Tue, 28 Oct 2025 14:13:48 GMT
-
- hello!
- ```
-
-{{< /version>}}
-
-
-## Clean up
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```bash
-kubectl delete Gateway agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} agentgateway-config -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
diff --git a/assets/docs/pages/agentgateway/gateway-api.md b/assets/docs/pages/agentgateway/gateway-api.md
deleted file mode 100644
index b057dbb8a..000000000
--- a/assets/docs/pages/agentgateway/gateway-api.md
+++ /dev/null
@@ -1,70 +0,0 @@
-Agentgateway is based on the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/).
-Gateway API is an official Kubernetes project that focuses on managing L4 and L7 traffic routing in Kubernetes environments.
-Along with core functionality, Gateway API provides a rich set of extension points for advanced use cases.
-Agentgateway uses these extension points to provide functionality beyond what is provided by the core Kubernetes API.
-
-## Conformance
-
-Unlike other implementations of Gateway API, agentgateway is the only data plane designed from the ground up for
-Kubernetes.
-As a result, agentgateway offers some of the most comprehensive support for the Gateway API.
-
-You can review the conformance test results by version in the [Gateway API docs](https://gateway-api.sigs.k8s.io/implementations/#conformance-levels). For example, as of the time of this writing, agentgateway is the only implementation of Gateway API that passes all conformance tests for Gateway API v1.3.
-
-In addition to supporting all Core and Extended Gateway API features, Gateway API has a number of "experimental"
-features that are in development.
-Agentgateway supports many of these experimental features, as shown in the following table.
-
-| Feature | GEP | Status |
-|---------------------------------------------------------------------------|-----------------------------------------------------------|-----------------------------------------|
-| Client Certificate Validation for TLS terminating at the Gateway Listener | [GEP-91](https://gateway-api.sigs.k8s.io/geps/gep-91) | ✅ Supported |
-| HTTP Auth | [GEP-1494](https://gateway-api.sigs.k8s.io/geps/gep-1494) | ✅ Supported |
-| Session Persistence | [GEP-1619](https://gateway-api.sigs.k8s.io/geps/gep-1619) | ❌ Unsupported |
-| ListenerSets | [GEP-1713](https://gateway-api.sigs.k8s.io/geps/gep-1713) | ✅ Supported |
-| HTTPRoute Retries | [GEP-1731](https://gateway-api.sigs.k8s.io/geps/gep-1731) | ✅ Supported |
-| Gateway API Interaction with Multi-Cluster Services | [GEP-1748](https://gateway-api.sigs.k8s.io/geps/gep-1748) | ❌ Unsupported |
-| CORS Filter | [GEP-1767](https://gateway-api.sigs.k8s.io/geps/gep-1767) | ✅ Supported |
-| TLS based passthrough Route / TLSRoute | [GEP-2643](https://gateway-api.sigs.k8s.io/geps/gep-2643) | ✅ Supported |
-| Complete Backend mutual TLS Configuration | [GEP-3155](https://gateway-api.sigs.k8s.io/geps/gep-3155) | ❌ Unsupported (supported via extension) |
-| Retry Budgets | [GEP-3388](https://gateway-api.sigs.k8s.io/geps/gep-3388) | ❌ Unsupported |
-| Gateway TLS Updates for HTTP/2 Connection Coalescing | [GEP-3567](https://gateway-api.sigs.k8s.io/geps/gep-3567) | ✅ Supported |
-
-## Extensions
-
-To add functionality that is missing in the core Gateway API, agentgateway provides a number of extensions.
-Some of these add completely novel functionality, such as support for the MCP protocol, while others provide more rich
-functionality for existing features.
-
-This section describes the extensions that overlap with the core Gateway API.
-For a full list of extensions, refer to the rest of the documentation.
-
-When a feature is implemented in both the core Gateway API and an extension, you have the choice to use either API.
-- If you value building on the portable standard and do not require the additional functionality, then use the core Gateway API.
-- If you require the additional functionality, or want the ability to expand to use additional functionality in the future without requiring a migration, then use the agentgateway extension.
-
-| Feature | Gateway API | Agentgateway extension | Differences |
-|-----------------------------|------------------------------------------------------------------------------------------------------|------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Originating TLS to backends | [BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) | `AgentgatewayPolicy` `.backend.tls` | Agentgateway supports mutual TLS (mTLS), automatic SNI and SAN validation, ALPN customization, and the ability to (optionally) disable TLS verification. |
-| Header manipulation | [HTTPRoute header modifier](https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional) | `AgentgatewayPolicy` `.traffic.transformation` | Agentgateway supports setting headers based on CEL expressions, rather than just static values. |
-| External Authorization | [HTTPRoute ExternalAuth filter](https://gateway-api.sigs.k8s.io/geps/gep-1494/) | `AgentgatewayPolicy` `.traffic.extAuth` | Agentgateway supports more advanced configuration, such as automatic redirects (to sign-in pages), and more control over request and response processing. |
-| HTTP Filters | [Filters inline in HTTPRoute](https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional) | `AgentgatewayPolicy` `.traffic` | Agentgateway allows all policies to be either configured as inline HTTPRoute filters, or as standalone policies attached to objects like Gateway and HTTPRoute, allowing more flexibility and re-use. |
-
-## Comparison with other implementations {#implementations}
-
-The Kubernetes Gateway API has more than 40 [implementations](https://gateway-api.sigs.k8s.io/implementations/) at the time of this writing.
-If you are in the process of evaluating a Gateway API implementation, consider the following factors:
-
-
-
-**Conformance level**: Is the implementation up to date? The Gateway API docs [set three levels of conformance](https://gateway-api.sigs.k8s.io/implementations/#conformance-levels), depending on the level of commitment to the Gateway API by version.
-- Prefer conformant implementations that pass tests for the past two releases of the Gateway API, such as kgateway with agentgateway.
-- Review the release version-specific conformance reports. If an implementation is not listed, then it might be stale. Many implementations have not been updated for years, making them incompatible with the latest API.
-- Confirm that the implementation is generally available. Some implementations might be in beta or alpha, and not yet ready for production use.
-
-**Feature coverage**: Is the implementation correctly implementing the Gateway API specification for features that you use?
-- Evaluate each implementation's conformance report for the version that you want to use. Unlike other conformance programs, Gateway API conformance **does not require passing all (or any) tests**, and instead lets implementations skip features.
-- Confirm that basic functionality like HTTP Method matching, request timeouts, and so forth are supported by the implementation. Remember that because implementations can skip features, even a "passing" conformance report does not indicate basic functionality.
-
-**Real-world performance**: Does the implementation behave well in real world scenarios?
-- Consider that the conformance reports evaluate the correctness of an implementation in a simple environment. They do not test whether the implementation can scale up to thousands of routes, handle rapidly changing configuration, or gracefully handle changes without downtime.
-- Review the unofficial [Gateway API Benchmarks](https://github.com/howardjohn/gateway-api-bench) as a starting point for evaluating the behavior of a Gateway API implementation. Agentgateway is featured in [Part 2](https://github.com/howardjohn/gateway-api-bench/blob/main/README-v2.md)!
diff --git a/assets/docs/pages/agentgateway/guardrails.md b/assets/docs/pages/agentgateway/guardrails.md
deleted file mode 100644
index 8e149d8e3..000000000
--- a/assets/docs/pages/agentgateway/guardrails.md
+++ /dev/null
@@ -1,419 +0,0 @@
-Use the Guardrail Webhook API to set up your own custom guardrail controls for {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## About guardrails {#about}
-
-Guardrails are control mechanisms that help ensure safe, consistent, and compliant interactions with large language models (LLMs) by validating both input and output content.
-
-### Benefits of guardrails {#about-benefits}
-
-Because LLMs generate text based on probability calculations and training data that is outside your control and business context, their responses can vary widely. LLMs might hallucinate, generate harmful or unhelpful content, leak sensitive data, or otherwise return unexpected responses that are not aligned with your organization's standards.
-
-Guardrails mitigate such risks by letting you take action on:
-
-* Input, or the content before sending requests to the LLM.
-* Output, or the content before delivering responses to the user.
-
-For example, a guardrail might:
-
-* Scan input and mask sensitive data patterns before they reach the LLM, such as employee IDs or other personally identifiable information (PII).
-* Verify that LLM responses follow a required JSON structure before returning them to users.
-
-By applying guardrails to both input and output, you can:
-
-* Reject or mask harmful or unhelpful content.
-* Enforce desired formats, content boundaries, and safety rules.
-* Comply with regulatory requirements, industry standards, internal policies, style guides, and more.
-
-### Support for guardrails {#about-guardrail-support}
-
-{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} includes built-in [prompt guards](../../prompt-guards/) to reject, mask, or pass prompt data through a moderation endpoint.
-
-However, you might want to bring your own guardrails for situations such as:
-
-* Small language models (SMLs) that do not have a moderation endpoint but that you want to use to sanitize input or output.
-* Advanced guards and moderation rules that are not part of {{< reuse "agw-docs/snippets/agentgateway.md" >}} or the LLM provider's moderation endpoint.
-* Full control over safety and compliance logic.
-* Centralized enforcement across multiple models and providers.
-* The ability to update your policies without redeploying the gateway proxy or models.
-* Extra logging and auditing capabilities that are built into your own guardrail implementation.
-
-To support such advanced scenarios, {{< reuse "agw-docs/snippets/agentgateway.md" >}} includes a Guardrail Webhook API that you can use to bring your own guardrails. This way, your webhook server can integrate with {{< reuse "agw-docs/snippets/agentgateway.md" >}} to process requests synchronously before they reach the LLM and responses before they return to the user. This architecture allows for flexible integration with your existing security and compliance tools.
-
-### Example diagram {#example-diagram}
-
-The following diagram shows a simple sequence of how the Guardrail Webhook API lets your webhook server integrate with {{< reuse "agw-docs/snippets/agentgateway.md" >}} to process LLM requests and responses.
-
-```mermaid
-sequenceDiagram
- participant Client
- participant Gateway as Agentgateway
- participant Webhook as Guardrail Webhook
- participant LLM
-
- Client->>Gateway: Send prompt
- Gateway->>Webhook: Pre-request guardrail check
- Webhook-->>Gateway: Allow/Modify/Reject
-
- alt Request Allowed
- Gateway->>LLM: Forward prompt
- LLM-->>Gateway: Generate response
- Gateway->>Webhook: Post-response guardrail check
- Webhook-->>Gateway: Allow/Modify/Reject
- Gateway-->>Client: Return response
- else Request Rejected
- Webhook-->>Gateway: Return rejection
- Gateway-->>Client: Forward rejection
- end
-```
-
-1. The client sends a request to the LLM.
-2. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} receives the request and passes it to the webhook server for a pre-request guardrail check.
-3. If the request is allowed, {{< reuse "agw-docs/snippets/agentgateway.md" >}} forwards the request to the LLM. The LLM generates a response that the webhook server can modify before {{< reuse "agw-docs/snippets/agentgateway.md" >}} returns the response to the client.
-4. If the request is rejected by the Guardrail Webhook, {{< reuse "agw-docs/snippets/agentgateway.md" >}} forwards the rejection to the client.
-
-### Considerations for using guardrails {#about-considerations}
-
-When implementing a guardrail webhook server, consider the following performance, implementation, and operational factors.
-
-* **Performance impact**: Each guardrail check adds latency to the request-response cycle. Plan accordingly, such as deploying the webhook server close to the gateway proxy to minimize latency and implementing resiliency best practices such as timeouts and horizontal scaling.
-* **Implementation challenges**: Your webhook server must handle requests synchronously and respond quickly to avoid user experience degradation. The requests might be streaming or non-streaming.
-* **Operational responsibilities**: You are responsible for developing, integrating, and operating your own guardrail webhook server.
-
-### Optimize guardrail webhook performance {#optimize-performance}
-
-To optimize guardrail webhook performance, you can update the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} for {{< reuse "agw-docs/snippets/agentgateway.md" >}} with the following settings.
-
-* `GUARDRAIL_WEBHOOK_MAX_CONNECTIONS`: The maximum number of concurrent connections that the gateway can open to the webhook server. A value of `0` means no limit. The default value is `100`. Higher values allow for greater concurrency, which is good for high-throughput systems, such as when many user requests trigger requests to the webhook server. Lower values help reduce resource usage and the risk of overwhelming the webhook server.
-* `GUARDRAIL_WEBHOOK_KEEPALIVE_SECONDS`: The number of seconds to keep an idle connection alive. The default value is `300`. Higher values help avoid delays to setup and teardown connections when requests are intermittent. Lower values help free up unused connections faster, which can help if the webhook server does not handle idle connections well.
-
-Example configuration file:
-
-
-
-
-```yaml
-kubectl apply -f- <}}
-kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
-metadata:
- name: agw-override
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- env:
- - name: GUARDRAIL_WEBHOOK_MAX_CONNECTIONS
- value: "50"
- - name: GUARDRAIL_WEBHOOK_KEEPALIVE_SECONDS
- value: "60"
-EOF
-```
-
-
-
-### More information
-
-* [Example scenario](#example-scenario) of a simple Python webhook server that integrates with the Guardrail Webhook API.
-* [Guardrail Webhook API reference docs](../openapi-spec/).
-
-## Example scenario
-
-To learn how to implement your own guardrail webhook server, you can use the following sample Python webhook server. For the source code, see the [GitHub repository](https://github.com/solo-io/gloo-gateway-use-cases/tree/main/ai-guardrail-webhook-server).
-
-The webhook server is configured to take the following actions:
-
-* If the content has the word `block`, the request is rejected with a 403 Forbidden response.
-* If the response has the word `mask`, the gateway transforms the word `mask` to asterisks (`****`) in the body with a 200 response.
-
-{{< callout type="warning" >}}
-{{% reuse "agw-docs/snippets/demo-disclaimer.md" %}}
-{{< /callout >}}
-
-### Before you begin
-
-{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}}
-
-### Step 1: Deploy the webhook server to your cluster
-
-1. Deploy the webhook server. The example includes a Deployment based on the `gcr.io/solo-public/docs/ai-guardrail-webhook:latest` image and Service of type LoadBalancer that listens for incoming requests on port 8000. If the image does not work for your environment, you can build your own from the sample code in the [GitHub repository](https://github.com/solo-io/gloo-gateway-use-cases/tree/main/ai-guardrail-webhook-server).
-
- ```yaml
- kubectl apply -f - <}}
- labels:
- app: ai-guardrail
- spec:
- replicas: 2
- selector:
- matchLabels:
- app: ai-guardrail-webhook
- template:
- metadata:
- labels:
- app: ai-guardrail-webhook
- spec:
- containers:
- - name: webhook
- image: gcr.io/solo-public/docs/ai-guardrail-webhook:latest
- ports:
- - containerPort: 8000
- resources:
- requests:
- memory: "128Mi"
- cpu: "100m"
- limits:
- memory: "256Mi"
- cpu: "200m"
- ---
- apiVersion: v1
- kind: Service
- metadata:
- name: ai-guardrail-webhook
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- labels:
- app: ai-guardrail
- spec:
- selector:
- app: ai-guardrail-webhook
- ports:
- - port: 8000
- targetPort: 8000
- type: LoadBalancer
- EOF
- ```
-
-2. Verify that the webhook server is running.
-
- ```sh
- kubectl get deploy,svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ai-guardrail
- ```
-
- Example output:
-
- ```
- NAME READY UP-TO-DATE AVAILABLE AGE
- deployment.apps/ai-guardrail-webhook 2/2 2 2 88s
-
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- service/ai-guardrail-webhook LoadBalancer 172.xx.xxx.xx .us-east-2.elb.amazonaws.com 8000:30752/TCP 88s
- ```
-
-3. Save the address of the webhook server in an environment variable.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
-
- ```sh
- export WEBHOOK_SERVER_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} ai-guardrail-webhook -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $WEBHOOK_SERVER_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- If the webhook service is deployed in the same cluster as the gateway proxy, you can also use the Kubernetes DNS name of the service, such as `ai-guardrail-webhook.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local`.
- ```sh
- export WEBHOOK_SERVER_ADDRESS=ai-guardrail-webhook.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local
- echo $WEBHOOK_SERVER_ADDRESS
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-
-### Step 2: Configure the gateway proxy to use the webhook server {#ai-gateway}
-
-Configure a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to use the webhook server for prompt guarding.
-
-
-
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: openai-prompt-guard
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: openai
- backend:
- ai:
- promptGuard:
- request:
- - webhook:
- backendRef:
- kind: Service
- name: ai-guardrail-webhook
- port: 8000
- response:
- - webhook:
- backendRef:
- kind: Service
- name: ai-guardrail-webhook
- port: 8000
-EOF
-```
-
-{{% reuse "agw-docs/snippets/review-table.md" %}} For more prompt guard options such as custom responses, see the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} API docs for AI.
-
-| Setting | Description |
-|---------|-------------|
-| `targetRefs` | The HTTPRoute that you want to apply the guardrail to. This example uses the `openai` HTTPRoute that you created before you began. |
-| `backend.ai.promptGuard` | The AI prompt guarding configuration that you want to set up. In this example, you configure the webhook server for both request and response guardrails. |
-| `webhook.backendRef` | The reference to the webhook server service. The example webhook server is configured to use port 8000. |
-
-
-
-
-### Step 3: Test the webhook server {#test-webhook-server}
-
-1. Send a request through {{< reuse "agw-docs/snippets/agentgateway.md" >}} to the OpenAI provider. In the body, include the word `block` to trigger the 403 Forbidden response.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi "$INGRESS_GW_ADDRESS:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners."
- },
- {
- "role": "user",
- "content": "Write a method to block inappropriate content."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners."
- },
- {
- "role": "user",
- "content": "Write a method to block inappropriate content."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example response:
-
- ```
- HTTP/1.1 403 Forbidden
- ...
- request blocked
- ```
-
-2. Send another request. This time, include the word `mask` in the body to trigger the 200 response with the content masked.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal= "2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi "$INGRESS_GW_ADDRESS:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners."
- },
- {
- "role": "user",
- "content": "Explain masking to me briefly, and show me an example of masking the names of the people in this directory: Alice, Sr. Developer. Bob, Jr. Developer. Charlie, Manager."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "You are a skilled developer who is good at explaining basic programming concepts to beginners."
- },
- {
- "role": "user",
- "content": "Explain masking to me briefly, and show me an example of masking the names of the people in this directory: Alice, Sr. Developer. Bob, Jr. Developer. Charlie, Manager."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example response: Note that the response turns the word `mask` into asterisks (`****`).
-
- ```
- HTTP/1.1 200 OK
- ```
-
- ```json
- {
- "id": "chatcmpl-BMFO97jLVP4YOjf6CZEOL5sHSqhbn",
- "object": "chat.completion",
- "created": 1744642069,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Sure! In programming, we use the term \"****\" to refer to a process of hiding sensitive information such as names, passwords, or other personal data. This is done to protect privacy and prevent unauthorized access to the information. \n\nIn this context, if you want to hide the names of the people in the directory, you can replace them with placeholders like this:\n\n- ****, Sr. Developer\n- ****, Jr. Developer\n- ****, Manager\n\nThis way, you are concealing the actual names while still providing their job titles or roles in the directory.",
- "refusal": null,
- "annotations": []
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 55,
- "completion_tokens": 116,
- "total_tokens": 171,
- "prompt_tokens_details": {
- "cached_tokens": 0,
- "audio_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0,
- "audio_tokens": 0,
- "accepted_prediction_tokens": 0,
- "rejected_prediction_tokens": 0
- }
- },
- "service_tier": "default",
- "system_fingerprint": null
- }
- ```
-
-
-### Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the webhook server deployment and service.
-
- ```sh
- kubectl delete deploy,svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ai-guardrail
- ```
-
-2. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
-
- ```sh
- kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} openai-prompt-guard
- ```
diff --git a/assets/docs/pages/agentgateway/inference.md b/assets/docs/pages/agentgateway/inference.md
deleted file mode 100644
index 0b4d39d27..000000000
--- a/assets/docs/pages/agentgateway/inference.md
+++ /dev/null
@@ -1,37 +0,0 @@
-Use agentgateway proxies with the Kubernetes Gateway API Inference Extension project. This project extends the Gateway API so that you can route to AI inference workloads such as local Large Language Models (LLMs) that run in your Kubernetes environment.
-
-For more information, see the following resources.
-
-{{< cards >}}
- {{< card link="https://gateway-api-inference-extension.sigs.k8s.io/" title="Kubernetes Gateway API Inference Extension docs" icon="external-link">}}
- {{< card link="https://kgateway.dev/blog/deep-dive-inference-extensions/" title="Kgateway deep-dive blog on Inference Extension" icon="external-link">}}
-{{< /cards >}}
-
-## About Inference Extension {#about}
-
-The Inference Extension project extends the Gateway API with two key resources, an InferencePool and an InferenceModel, as shown in the following diagram.
-
-```mermaid
-graph TD
- InferencePool --> InferenceModel_v1["InferenceModel v1"]
- InferencePool --> InferenceModel_v2["InferenceModel v2"]
- InferencePool --> InferenceModel_v3["InferenceModel v3"]
-```
-
-The InferencePool groups together InferenceModels of LLM workloads into a routable backend resource that the Gateway API can route inference requests to. An InferenceModel represents not just a single LLM model, but a specific configuration including information such as as the version and criticality. The InferencePool uses this information to ensure fair consumption of compute resources across competing LLM workloads and share routing decisions to the Gateway API.
-
-### {{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} with Inference Extension {#integration}
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} integrates with the Inference Extension as a supported Gateway API provider. This way, a Gateway can route requests to InferencePools, as shown in the following diagram.
-
-{{< reuse "agw-docs/snippets/inference-diagram.md" >}}
-
-The Client sends an inference request to get a response from a local LLM workload. The Gateway receives the request and routes to the InferencePool as a backend. Then, the InferencePool selects a specific InferenceModel to route the request to, based on criteria such as the least-loaded model or highest criticality. The Gateway can then return the response to the Client.
-
-## Setup steps {#setup}
-
-Refer to the **Kgateway** tabs in the **Getting started** guide in the Inference Extension docs.
-
-{{< cards >}}
- {{< card link="https://gateway-api-inference-extension.sigs.k8s.io/guides/" title="Inference Extension getting started guide" icon="external-link">}}
-{{< /cards >}}
diff --git a/assets/docs/pages/agentgateway/llm/about.md b/assets/docs/pages/agentgateway/llm/about.md
deleted file mode 100644
index 0b8372730..000000000
--- a/assets/docs/pages/agentgateway/llm/about.md
+++ /dev/null
@@ -1,42 +0,0 @@
-{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} provides seamless integration with various Large Language Model (LLM) providers. This way, you can consume AI services through a unified interface while still maintain flexibility in the providers that you use.
-
-## What is an LLM?
-
-Large Language Model (LLMs) are very large, deep learning models that are pre-trained on massive amounts of unlabeled and self-supervised data, often containing billions of words. LLMs extract meanings from a sequence of text and can understand the relationship between words and phrases in it. Based on this understanding, the LLM can then predict and generate natural language, and perform related tasks, such as answering questions, summarizing text, translating between languages, or writing content. LLMs can be fine-tuned on a smaller, more specific data set so that it can perform a more specific task more accurately.
-
-While LLMs were originally designed to be trained on text and natural language, they are now becoming multimodal, supporting different media types, such as images and videos.
-
-## Common problems with LLM consumption
-
-When adopting an LLM on an enterprise-level, you typically run into the following issues:
-
-* **Data leakage and privacy**: When interacting with LLMs, it is essential to comply with federal laws and to not leak any PII (personally identifiable information) or other sensitive information in prompts. For example, users might enter personal credit card or customer related information, such as account numbers and names. Attackers might also trick the model into revealing previous user data that is still stored in the context. To prevent sensitive information from leaking to the LLM provider, prompt guards must be in place that help to fitler, block, monitor, and control LLM inputs and outputs to find offensive content, prevent misuse, and ensure ethical and responsible AI usage.
-
-* **Cost controls**: Compared to traditional APIs, LLM queries are long-running, meaning the LLM must parse through its large data set iteratively to compute one token at a time. All tokens must then be summarized to generate a prediction. Given the large amounts of data that the LLM parses, GPUs are required to run LLMs efficently, which are costly to run and maintain. Limiting the amount of tokens that can be used and monitoring token consumption are critical to keep costs to a minimum.
-
-* **Fan-out patterns**: LLMs are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, answering a simple question, such as `What is the weather today?` requires the LLM to have access to several real-time information, such as the location, time, and weather forecast. Integrating LLMs with other MCP servers and agents to perform these tasks becomes essential to accurately answer questions of this nature.
-
-* **Security**: To protect your LLM from being consumed by unauthorized users, you typically want to authenticate with the LLM before you start sending requests. Managing credentials, such as API keys, and monitoring the traffic to the LLM becomes essential to protect access to the LLM .
-
-* **Scalability and reliability**: When relying on an LLM to perform specific tasks in your environment, you must put measures in place that prevent your applications from failing, being overwhelmed, or performing inefficiently. This includes retries and timeouts, request rate limiting, and multi-model failovers.
-
-
-
-## Supported providers
-
-Review the following table for a list of supported LLM providers.
-
-
-| Provider | Chat Completions | Streaming |
-|---------------------------|:---------------:|:---------:|
-| [OpenAI](../providers/openai) | ✅ | ✅ |
-| [Vertex AI](../providers/vertex) | ✅ | ✅ |
-| [Gemini](../providers/gemini) | ✅ | ✅ |
-| [Amazon Bedrock](../providers/bedrock) | ✅ | ✅ |
-| [Anthropic](../providers/anthropic) | ✅ | ✅ |
-| [OpenAI compatible](../providers/openai-compatible) | ✅ | ✅ |
-| [Azue OpenAI](../providers/azureopenai) | ✅ | ✅ |
-
-* Chat Completions: support for the `/v1/chat/completions` API.
-* Streaming: support for streaming (`"stream": true` in the completions request)
-
diff --git a/assets/docs/pages/agentgateway/llm/api-keys.md b/assets/docs/pages/agentgateway/llm/api-keys.md
deleted file mode 100644
index 9f1c8c897..000000000
--- a/assets/docs/pages/agentgateway/llm/api-keys.md
+++ /dev/null
@@ -1,446 +0,0 @@
-Managing API keys is an important security mechanism to prevent unauthorized access to your LLM provider. If API keys are compromised, attackers can deliberately run expensive queries, such as large and recursive prompts, at your expense.
-
-Follow the instructions in this guide to learn how to use these different methods.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Manage API keys
-
-You can choose between the following options to provide an API key to agentgateway:
-* [Inline](#inline)
-* [Kubernetes secret](#api-key)
-* [Passthrough token](#passthrough)
-
-### Inline token {#inline}
-
-Provide the token directly in the configuration for the {{< reuse "agw-docs/snippets/backend.md" >}}. This option is the least secure. Only use this option for quick tests such as trying out AI Gateway.
-
-1. Get the token from your LLM provider, such as an API key to OpenAI.
-
- ```sh
- export TOKEN=
- ```
-
-
-2. Provide the token inline in the {{< reuse "agw-docs/snippets/backend.md" >}} configuration.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: gpt-3.5-turbo
- policies:
- auth:
- key: $TOKEN
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.openai` | Define the OpenAI provider. |
- | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. |
- | `policies.auth` | Configure the authentication token for the OpenAI API. The example uses an inline token.|
-
-3. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /openai
- backendRefs:
- - name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-4. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 39,
- "completion_tokens": 200,
- "total_tokens": 239,
- "prompt_tokens_details": {
- "cached_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0
- }
- },
- "system_fingerprint": null
- }
- ```
-
-### API key in a secret {#api-key}
-
-Store the API key in a Kubernetes secret. Then, refer to the secret in the {{< reuse "agw-docs/snippets/backend.md" >}} configuration. This option is more secure than an inline token, because the API key is encoded and you can restrict access to secrets through RBAC rules. Like the inline option, the API key and secret are fairly simple to create and set up. You might use this option in proofs of concept, controlled development and staging environments, or well-controlled prod environments that use secrets.
-
-1. [Create an API key to access the OpenAI API](https://platform.openai.com/api-keys). If you use another AI provider, create an API key for that provider's AI instead, and be sure to modify the example commands in these tutorials to use your provider's AI API instead.
-
-2. Save the API key in an environment variable.
-
- ```sh
- export OPENAI_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your AI API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $OPENAI_API_KEY
- EOF
- ```
-
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: gpt-3.5-turbo # Optional: specify default model
- # host: api.openai.com # Optional: custom host if needed
- # port: 443 # Optional: custom port
- policies:
- auth:
- secretRef:
- name: openai-secret
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.openai` | Define the OpenAI provider. |
- | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. |
- | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.|
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /openai
- backendRefs:
- - name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 39,
- "completion_tokens": 200,
- "total_tokens": 239,
- "prompt_tokens_details": {
- "cached_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0
- }
- },
- "system_fingerprint": null
- }
- ```
-
-### Passthrough token {#passthrough}
-
-Pass through an existing token directly from the client or a successful OpenID Connect (OIDC) connect flow before the request is sent to the {{< reuse "agw-docs/snippets/backend.md" >}}. This option is useful for environments where you set up federated identity for backend clients so that they are already authenticated to the LLM providers that you create {{< reuse "agw-docs/snippets/backend.md" >}}s for. Currently, the request must place the token in the `Authorization` header.
-
-1. Make sure that your client is set up as follows:
-
- * The client that sends a request to the {{< reuse "agw-docs/snippets/backend.md" >}} can authenticate to the LLM provider, such as through an OIDC flow or API key.
- * The authenticated token or API key is sent in requests to the {{< reuse "agw-docs/snippets/backend.md" >}} in an `Authorization` header.
-
-
-
-2. Configure the {{< reuse "agw-docs/snippets/backend.md" >}} to use passthrough auth.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: gpt-3.5-turbo
- policies:
- auth:
- passthrough: {}
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.openai` | Define the OpenAI provider. |
- | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. |
- | `policies.auth` | Configure the authentication token for OpenAI API. The example uses passthrough authentication.|
-
-3. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /openai
- backendRefs:
- - name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-4. Trigger your authenticated client to send a request to the {{< reuse "agw-docs/snippets/backend.md" >}}, and verify that you get back a successful response. For example, you might instruct your client to send a curl request through the AI Gateway. Note that the request includes the `Authorization` header, which is required for passthrough authentication.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H "Authorization: Bearer $TOKEN" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H "Authorization: Bearer $TOKEN" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }'
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it’s a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming’s domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 39,
- "completion_tokens": 200,
- "total_tokens": 239,
- "prompt_tokens_details": {
- "cached_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0
- }
- },
- "system_fingerprint": null
- }
- ```
-
diff --git a/assets/docs/pages/agentgateway/llm/failover.md b/assets/docs/pages/agentgateway/llm/failover.md
deleted file mode 100644
index 3beb0ba4a..000000000
--- a/assets/docs/pages/agentgateway/llm/failover.md
+++ /dev/null
@@ -1,260 +0,0 @@
-Prioritize the failover of requests across different models from an LLM provider.
-
-## About failover {#about}
-
-Failover is a way to keep services running smoothly by automatically switching to a backup system when the main one fails or becomes unavailable.
-
-For {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can set up failover for the models of the LLM providers that you want to prioritize. If the main model from one provider goes down, slows, or has any issue, the system quickly switches to a backup model from that same provider. This keeps the service running without interruptions.
-
-This approach increases the resiliency of your network environment by ensuring that apps that call LLMs can keep working without problems, even if one model has issues.
-
-## Before you begin
-
-1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-2. Set up [API access to each LLM provider]({{< link-hextra path="/llm/api-keys/" >}}) that you want to use. The example in this guide uses OpenAI.
-
-## Fail over to other models {#model-failover}
-
-You can configure failover across multiple models and providers by using priority groups. Each priority group represents a set of providers that share the same priority level. Failover priority is determined by the order in which the priority groups are listed in the {{< reuse "agw-docs/snippets/backend.md" >}}. The priority group that is listed first is assigned the highest priority. Models within the same priority group are load balanced (round-robin), not prioritized.
-
-1. Create or update the {{< reuse "agw-docs/snippets/backend.md" >}} for your LLM providers.
-
- {{< tabs tabTotal="2" items="OpenAI model priority,Cost-based priority across providers" >}}
- {{% tab tabName="OpenAI model priority" %}}
-
- In this example, you configure separate priority groups for failover across multiple models from the same LLM provider, OpenAI. The priority order of the models is as follows:
-
- 1. OpenAI `gpt-4.1` model (highest priority)
- 2. OpenAI `gpt-5.1` model (fallback)
- 3. OpenAI `gpt-3.5-turbo` model (lowest priority)
-
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: model-failover
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- groups:
- - providers:
- - name: openai-gpt-41
- openai:
- model: gpt-4.1
- policies:
- auth:
- secretRef:
- name: openai-secret
- - name: openai-gpt-5.1
- openai:
- model: gpt-5.1
- policies:
- auth:
- secretRef:
- name: openai-secret
- - name: openai-gpt-3.5-turbo
- openai:
- model: gpt-3.5-turbo
- policies:
- auth:
- secretRef:
- name: openai-secret
- EOF
- ```
-
-
-
- {{% /tab %}}
- {{% tab tabName="Cost-based priority across providers" %}}
-
- In this example, you configure failover across multiple providers with cost-based priority. The first priority group contains cheaper models. Responses are load-balanced across these models. In the event that both models are unavailable, requests fall back to the second priority group of more premium models.
- - Highest priority: Load balance across cheaper OpenAI `gpt-3.5-turbo` and Anthropic `claude-3-5-haiku-latest` models.
- - Fallback: Load balance across more premium OpenAI `gpt-4.1` and Anthropic `claude-opus-4-1` models.
-
- Make sure that you configured both Anthropic and OpenAI providers.
-
-
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: model-failover
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- groups:
- - providers:
- - name: openai-gpt-3.5-turbo
- openai:
- model: gpt-3.5-turbo
- policies:
- auth:
- secretRef:
- name: openai-secret
- - name: claude-haiku
- anthropic:
- model: claude-3-5-haiku-latest
- policies:
- auth:
- secretRef:
- name: anthropic-secret
- - providers:
- - name: openai-gpt-4.1
- openai:
- model: gpt-4.1
- policies:
- auth:
- secretRef:
- name: openai-secret
- - name: claude-opus
- anthropic:
- model: claude-opus-4-1
- policies:
- auth:
- secretRef:
- name: anthropic-secret
- EOF
- ```
-
-
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Create an HTTPRoute resource that routes incoming traffic on the `/model` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step. In this example, the URLRewrite filter rewrites the path from `/model` to the path of the API in the LLM provider that you want to use, such as `/v1/chat/completions` for OpenAI.
-
-
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /model
- backendRefs:
- - name: model-failover
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-3. Send a request to observe the failover. In your request, do not specify a model. Instead, the {{< reuse "agw-docs/snippets/backend.md" >}} automatically uses the model from the first priority group (highest priority).
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```bash
- curl -v "$INGRESS_GW_ADDRESS/model" -H content-type:application/json -d '{
- "messages": [
- {
- "role": "user",
- "content": "What is kubernetes?"
- }
- ]}' | jq
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```bash
- curl -v "localhost:8080/model" -H content-type:application/json -d '{
- "messages": [
- {
- "role": "user",
- "content": "What is kubernetes?"
- }
- ]}' | jq
- ```
- {{< /tab >}}
- {{< /tabs >}}
-
- Example output:
-
- {{< tabs tabTotal="2" items="OpenAI model priority,Cost-based priority across providers" >}}
- {{% tab tabName="OpenAI model priority" %}}
-
- Note the response is from the `gpt-4o` model, which is the first model in the priority order from the {{< reuse "agw-docs/snippets/backend.md" >}}.
-
- ```json {linenos=table,hl_lines=[5],linenostart=1,filename="model-response.json"}
- {
- "id": "chatcmpl-BFQ8Lldo9kLC56S1DFVbIonOQll9t",
- "object": "chat.completion",
- "created": 1743015077,
- "model": "gpt-4.1-2025-04-14",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Kubernetes is an open-source container orchestration platform designed to automate the deployment, scaling, and management of containerized applications. Originally developed by Google, it is now maintained by the Cloud Native Computing Foundation (CNCF).\n\nKubernetes provides a framework to run distributed systems resiliently. It manages containerized applications across a cluster of machines, offering features such as:\n\n1. **Automatic Bin Packing**: It can optimize resource usage by automatically placing containers based on their resource requirements and constraints while not sacrificing availability.\n\n2. **Self-Healing**: Restarts failed containers, replaces and reschedules containers when nodes die, and kills and reschedules containers that are unresponsive to user-defined health checks.\n\n3. **Horizontal Scaling**: Scales applications and resources up or down automatically, manually, or based on CPU usage.\n\n4. **Service Discovery and Load Balancing**: Exposes containers using DNS names or their own IP addresses and balances the load across them.\n\n5. **Automated Rollouts and Rollbacks**: Automatically manages updates to applications or configurations and can rollback changes if necessary.\n\n6. **Secret and Configuration Management**: Enables you to deploy and update secrets and application configuration without rebuilding your container images and without exposing secrets in your stack configuration and environment variables.\n\n7. **Storage Orchestration**: Allows you to automatically mount the storage system of your choice, whether from local storage, a public cloud provider, or a network storage system.\n\nBy providing these functionalities, Kubernetes enables developers to focus more on creating applications, while the platform handles the complexities of deployment and scaling. It has become a de facto standard for container orchestration, supporting a wide range of cloud platforms and minimizing dependencies on any specific infrastructure.",
- "refusal": null,
- "annotations": []
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- ...
- }
- ```
-
- {{% /tab %}}
- {{% tab tabName="Cost-based priority across providers" %}}
-
- Note the response is from the `claude-3-5-haiku-20241022` model. With the cost-based priority configuration, requests are load balanced across the cheaper models (OpenAI `gpt-3.5-turbo` and Anthropic `claude-3-5-haiku-latest`) in the first priority group.
-
- ```json {linenos=table,hl_lines=[2],linenostart=1,filename="model-response.json"}
- {
- "model": "claude-3-5-haiku-20241022",
- "usage": {
- "prompt_tokens": 11,
- "completion_tokens": 299,
- "total_tokens": 310
- },
- "choices": [
- {
- "message": {
- "content": "Kubernetes (often abbreviated as K8s) is an open-source container orchestration platform designed to automate the deployment, scaling, and management of containerized applications. Here's a comprehensive overview:\n\nKey Features:\n1. Container Orchestration\n- Manages containerized applications\n- Handles deployment and scaling\n- Ensures high availability\n\n2. Core Components\n- Cluster: Group of machines (nodes)\n- Master Node: Controls the cluster\n- Worker Nodes: Run containerized applications\n- Pods: Smallest deployable units\n- Containers: Isolated application environments\n\n3. Main Capabilities\n- Automatic scaling\n- Self-healing\n- Load balancing\n- Rolling updates\n- Service discovery\n- Configuration management\n\n4. Key Concepts\n- Deployments: Define desired application state\n- Services: Network communication between components\n- Namespaces: Logical separation of resources\n- ConfigMaps: Configuration management\n- Secrets: Sensitive data management\n\n5. Benefits\n- Portability across different environments\n- Efficient resource utilization\n- Improved scalability\n- Enhanced reliability\n- Simplified management of complex applications\n\n6. Popular Use Cases\n- Microservices architecture\n- Cloud-native applications\n- Continuous deployment\n- Distributed systems\n\nKubernetes has become the standard for container orchestration in modern cloud-native application development.",
- "role": "assistant"
- },
- "index": 0,
- "finish_reason": "stop"
- }
- ],
- "id": "msg_016PLweC4jgJnpwH7V1tZaqj",
- "created": 1762790436,
- "object": "chat.completion"
- }
- ```
-
- {{% /tab %}}
- {{< /tabs >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```shell
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} model-failover -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete httproute model-failover -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-## Next
-
-Explore other agentgateway features.
-
-* Pass in [functions](../functions/) to an LLM to request as a step towards agentic AI.
-* Set up [prompt guards](../prompt-guards/) to block unwanted requests and mask sensitive data.
-* [Enrich your prompts](../prompt-enrichment/) with system prompts to improve LLM outputs.
diff --git a/assets/docs/pages/agentgateway/llm/functions.md b/assets/docs/pages/agentgateway/llm/functions.md
deleted file mode 100644
index 3ad2520bc..000000000
--- a/assets/docs/pages/agentgateway/llm/functions.md
+++ /dev/null
@@ -1,321 +0,0 @@
-## About function calling {#about}
-
-Large Language Models (LLMs) are limited by static training data. This limitation can make seemingly simple questions difficult to answer. For example, consider the following question:
-
-> What's the weather today?
-
-The LLM has to know several pieces of real-time information that it was not trained on:
-
-* The user's location
-* The current date
-* The weather forecast for that date and location
-
-Function calling is a way for you as a developer to extend the capabilities of the LLM with your own external APIs, apps, and data. First, you create _tools_ that extend the capabilities of the LLM with a function, such as `get_weather`. These functions can include _parameters_, or inputs, that are needed to execute the function. For example, the `get_weather` function needs the date and location to get the current weather forecast. The _name_ and _description_ of the tool function and parameters help the LLM decide when to call the tool.
-
-Next, when forwarding user requests to the LLM, you can include the set of tools that the LLM can leverage to answer the user. Based on the user's question, the LLM can respond directly or suggest a tool to call to help answer the question. To get the required parameters for the tool call, the LLM might ask the end user or call other functions like `get_location` or `get_date`, which in turn might pull that information based on system settings on the end user's device.
-
-### Function calling sequence diagram {#diagram}
-
-Consider the following sequence diagram that shows how function calling works.
-
-```mermaid
-sequenceDiagram
- autonumber
- User->>+Gateway: "What's the weather in Columbus?" with tool list
- Gateway->>+LLM: Forward user request with tool list
- LLM-->>-User: Suggest function call (get_weather)
- User-->>+App: Send function suggestion
- App->>-App: Execute function (get_weather)
- App->>+User: Send function result
- User->>+LLM: Forward function result
- LLM-->>+Gateway: Generate final response
- Gateway-->>-User: "The weather in Columbus is 15°C and cloudy."
-```
-
-1. The User asks about the weather today. The request includes a list of tools that the LLM can use to answer the question.
-2. The Gateway routes the request with the tool list to the LLM.
-3. Based on the conversation, the LLM suggests to call the `get_weather` function and includes the required parameters to use that function. The LLM might get these parameters by using the chat history, asking the end user to provide them, or by suggesting other functions to call before calling the `get_weather` function. The Gateway returns this suggestion to the User.
-4. The User invokes the `get_weather` function by sending a request to the App. The request includes the required parameters to execute the function.
-5. The App executes the `get_weather` function with the required parameters to get the current weather in the location, such as Columbus, OH.
-6. The App returns the function result to the User.
-7. The User returns the function result to the LLM.
-8. The LLM uses the real-time function result from the App in a natural language response and returns this response to the Gateway.
-9. The Gateway then forwards the natural language response to the User.
-
-### Behavior with other AI features {#about-behavior}
-
-Keep in mind the following behaviors when using function calling with other agentgateway features. For more details about these features, see the [API docs]({{< link-hextra path="reference/api/#aitrafficpolicy" >}}).
-
-* Streaming responses: You can stream responses that call functions.
-* Semantic caching: Function calls are not cached.
-* Prompt guards: Prompt guards do not apply to function calls.
-
-### AI provider differences {#about-providers}
-
-Each AI provider has a different way of handling function calling. For example, OpenAI might expect an array of `functions`, while Anthropic expects individual `tools`. Or, the response formats might differ. The capabilities of function calling also differ across providers, with some providing more support for particular cloud providers, others focusing on response time optimization, or others offering more fine-grained control over the response structure. For more information, consult your AI provider's documentation.
-
-* [Anthropic](https://docs.anthropic.com/en/docs/build-with-claude/tool-use/overview)
-* [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/function-calling)
-* [Gemini](https://ai.google.dev/gemini-api/docs/function-calling)
-* [Mistral AI](https://docs.mistral.ai/capabilities/function_calling/)
-* [OpenAI](https://platform.openai.com/docs/guides/function-calling)
-* [Vertex AI](https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/FunctionDeclaration?hl=en)
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}}
-
-## Example of function calling {#function-call}
-
-Send a function call to an LLM through agentgateway. In the following steps, you use an example `get_weather` function with an OpenAI LLM.
-
-{{< callout type="info" >}}
-Keep in mind that for a real use case, you must develop your own app that is capable of sending requests to the LLM and executing a tool, such as to retrieve the latest weather information for a given location.
-{{< /callout >}}
-
-1. Send a request through the agentgateway proxy to the OpenAI LLM. In your request, include an example `get_weather` function call. Note that you can include other tools and functions that the app has access to. This way, your LLM can decide on the tool and the function that best answers the user's question. For more examples of creating a function, consult your [AI provider's documentation](#about-providers). The following example demonstrates a response that you might configure your app to send through the agentgateway proxy to the LLM.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "How is the current weather in Columbus?"
- }
- ],
- "parallel_tool_calls": false,
- "tools": [
- {
- "type": "function",
- "function": {
- "name": "get_weather",
- "description": "Get the current weather",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and country, eg. San Francisco, USA"
- },
- "format": { "type": "string", "enum": ["celsius", "fahrenheit", "rankine"] }
- },
- "required": ["location", "format"]
- }
- }
- }
- ],
- "stream": false
- }'
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "How is the current weather in Columbus?"
- }
- ],
- "parallel_tool_calls": false,
- "tools": [
- {
- "type": "function",
- "function": {
- "name": "get_weather",
- "description": "Get the current weather",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and country, eg. San Francisco, USA"
- },
- "format": { "type": "string", "enum": ["celsius", "fahrenheit", "rankine"] }
- },
- "required": ["location", "format"]
- }
- }
- }
- ],
- "stream": false
- }'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
- | Field | Description |
- |-------|-------------|
- | `$INGRESS_GW_ADDRESS/openai` | The address of the agentgateway proxy that you set up before you began, along with the path to your AI provider, such as `openai`. |
- | `model` | The model to use for the function call, such as `gpt-3.5-turbo`. |
- | `messages` | The messages to send to the model. The example shows a user message asking about the weather in Columbus. |
- | `parallel_tool_calls` | Whether to call multiple tools at the same time. |
- | `tools` | The tools to use for the function call. |
- | `function` | The information about the function to call. |
- | `name` | The name of the function. Often, this name matches the function in your app. Try to be as descriptive as possible so that the LLM can figure out what the function does.
- | `description` | Provide more context about the function that helps the LLM decide when to use this particular function as opposed to other functions. |
- | `parameters` | Include the required parameters that your app needs to execute the function. The example sets up two required parameters: `location` and `format`. |
- | `stream` | Whether to stream the response. If you set this to `true`, the response is streamed token-by-token to the client, which can speed up the response time. The example is set to `false`, which is better for functions that are part of a batch or have strict formatting response requirements.|
-
-2. Review the response from the LLM. If the LLM decides to call a tool, the response includes the information that your app needs to execute the function.
-
- ```json
- {
- "id": "chatcmpl-B7nLgGVMnDpc13CZ8tCBNZ8SPmcV9",
- "object": "chat.completion",
- "created": 1741197692,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": null,
- "tool_calls": [
- {
- "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU",
- "type": "function",
- "function": {
- "name": "get_weather",
- "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}"
- }
- }
- ],
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "tool_calls"
- }
- ],
- }
- ```
-
- | Field | Description |
- |-------|-------------|
- | `content` | This field is `null` because the model did not return a conversation message. Instead, the model suggests a tool call. |
- | `tool_calls` | The details of the function to call. Notice that the response includes an ID for the tool call, `call_iMGPsr4Xx1u0G5sOzFsTCbQU`. Also, the required parameters are part of the arguments. |
- | `finish_reason` | The `tool_calls` field indicates that the response is not final, but rather a function call that needs further handling. |
-
-3. Set up your app to receive the function call from the LLM and execute the function. For example, assume that your weather app returns the following result:
-
- ```json
- {
- "temperature": 15,
- "condition": "cloudy"
- }
- ```
-
-4. From the app, return the result of the function call to the LLM through the agentgateway proxy. Make sure that the app includes the `tool_call_id` for each tool call.
-
- * The following example sends another curl through the agentgateway proxy to the LLM to simulate a response that your app might send. Unlike the first request, this request does not suggest a tool call. Instead, you provide the results from executing the suggested function as part of the message, along with the assistant role that called the tool.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H "Content-Type: application/json" -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "How is the current weather in Columbus?"
- },
- {
- "role": "assistant",
- "content": null,
- "tool_calls": [
- {
- "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU",
- "type": "function",
- "function": {
- "name": "get_weather",
- "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}"
- }
- }
- ]
- },
- {
- "role": "tool",
- "tool_call_id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU",
- "name": "get_weather",
- "content": "{ \"temperature\": 15, \"condition\": \"Cloudy\" }"
- }
- ]
- }'
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H "Content-Type: application/json" -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "How is the current weather in Columbus?"
- },
- {
- "role": "assistant",
- "content": null,
- "tool_calls": [
- {
- "id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU",
- "type": "function",
- "function": {
- "name": "get_weather",
- "arguments": "{\"format\":\"celsius\",\"location\":\"Columbus, OH\"}"
- }
- }
- ]
- },
- {
- "role": "tool",
- "tool_call_id": "call_iMGPsr4Xx1u0G5sOzFsTCbQU",
- "name": "get_weather",
- "content": "{ \"temperature\": 15, \"condition\": \"Cloudy\" }"
- }
- ]
- }'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
-5. Review the response from the LLM.
-
- ```json
- {
- "id": "chatcmpl-B7opYdxULQAF0xN6SK6jCIZft75xG",
- "object": "chat.completion",
- "created": 1741203388,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "The current weather in Columbus is 15°C and cloudy.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- }
- ```
-
- | Field | Description |
- |-------|-------------|
- | `choices.message.content` | The response includes the content that answers the user's initial query about the weather. |
- | `choices.finish_reason` | The `stop` finish reason indicates that the response is complete. |
-
-
-
-
diff --git a/assets/docs/pages/agentgateway/llm/observability.md b/assets/docs/pages/agentgateway/llm/observability.md
deleted file mode 100644
index 3fcc844ee..000000000
--- a/assets/docs/pages/agentgateway/llm/observability.md
+++ /dev/null
@@ -1,43 +0,0 @@
-Review LLM-specific metrics and logs.
-
-## Before you begin
-
-Complete an LLM guide, such as an [LLM provider-specific guide]({{< link-hextra path="/llm/providers/" >}}). This guide sends a request to the LLM and receives a response. You can use this request and response example to verify metrics and logs.
-
-## View LLM metrics
-
-You can access the {{< reuse "agw-docs/snippets/agentgateway.md" >}} metrics endpoint to view LLM-specific metrics, such as the number of tokens that you used during a request or response.
-
-1. Port-forward the agentgateway proxy on port 15020.
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 15020
- ```
-2. Open the {{< reuse "agw-docs/snippets/agentgateway.md" >}} [metrics endpoint](http://localhost:15020/metrics).
-3. Look for the `agentgateway_gen_ai_client_token_usage` metric. This metric is a [histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) and includes important information about the request and the response from the LLM, such as:
- * `gen_ai_token_type`: Whether this metric is about a request (`input`) or response (`output`).
- * `gen_ai_operation_name`: The name of the operation that was performed.
- * `gen_ai_system`: The LLM provider that was used for the request/response.
- * `gen_ai_request_model`: The model that was used for the request.
- * `gen_ai_response_model`: The model that was used for the response.
-
-
-For more information, see the [Semantic conventions for generative AI metrics](https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/) in the OpenTelemetry docs.
-
-
-## View logs
-
-{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} automatically logs information to stdout. When you run {{< reuse "agw-docs/snippets/agentgateway.md" >}} on your local machine, you can view a log entry for each request that is sent to {{< reuse "agw-docs/snippets/agentgateway.md" >}} in your CLI output.
-
-To view the logs:
-```sh
-kubectl logs deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-Example for a successful request to the OpenAI LLM:
-```
-2025-12-12T21:56:02.809082Z info request gateway=agentgateway-system/agentgateway-proxy listener=http
-route=agentgateway-system/openai endpoint=api.openai.com:443 src.addr=127.0.0.1:60862 http.method=POST
-http.host=localhost http.path=/openai http.version=HTTP/1.1 http.status=200 protocol=llm gen_ai.
-operation.name=chat gen_ai.provider.name=openai gen_ai.request.model=gpt-3.5-turbo gen_ai.response.
-model=gpt-3.5-turbo-0125 gen_ai.usage.input_tokens=68 gen_ai.usage.output_tokens=298 duration=2488ms
-```
diff --git a/assets/docs/pages/agentgateway/llm/prompt-enrichment.md b/assets/docs/pages/agentgateway/llm/prompt-enrichment.md
deleted file mode 100644
index 6b363c098..000000000
--- a/assets/docs/pages/agentgateway/llm/prompt-enrichment.md
+++ /dev/null
@@ -1,317 +0,0 @@
-Effectively manage system and user prompts to improve LLM outputs.
-
-## About prompt enrichment
-
-Prompts are basic building blocks for guiding LLMs to produce relevant and accurate responses. By effectively managing both system prompts, which set initial guidelines, and user prompts, which provide specific context, you can significantly enhance the quality and coherence of the model's outputs.
-
-**System prompts** include initialization instructions, behavior guidelines, and background information. You use system prompts to set the foundation for the model's behavior. For example, you might instruct your LLM to respond to users with a polite tone, or according to specific organizational policies, with a system prompt such as "You are a helpful customer service assistant. Always be polite, and conclude conversations by asking customers to rate their experience."
-
-**User prompts** encompass direct queries, sequential inputs, and task-oriented instructions. They ensure that the model responds accurately to specific user needs. This includes all interactions that end users have with your LLM, such as "Summarize this article in 3 key points" or "What kind of dinner can I make with these ingredients?".
-
-Note that system and user prompts are not mutually exclusive, and can be combined in a single request to an LLM. For example, in the following steps, the prompt `Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe.` contains both system prompt and user prompt components.
-
-
-
-Prompt enrichment can be configured directly in an {{< reuse "agw-docs/snippets/backend.md" >}} resource or in a separate AgentgatewayPolicy resource.
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}}
-
-## Refactor LLM prompts
-
-In the following example, you explore how to refactor system and user prompts to parse and turn unstructured text into valid CSV format.
-
-1. Send a request to the AI API with the following prompt: `Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe.` Note that in this prompt, the system prompt is not separated from the user prompt.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Parse the unstructured text into CSV format: Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{% /tab %}}
-
- {{< /tabs >}}
-
- Verify that the request succeeds and that you get back a structured CSV response.
- ```
- City,Continent
- Seattle,North America
- Los Angeles,North America
- Chicago,North America
- London,Europe
- Paris,Europe
- Berlin,Europe
- ```
-
-2. Refactor the request to improve readability and management of the prompt. In the following example, the instructions are separated from the unstructured text. The instructions are added as a system prompt and the unstructured text is added as a user prompt.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "Parse the unstructured text into CSV format."
- },
- {
- "role": "user",
- "content": "Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "Parse the unstructured text into CSV format."
- },
- {
- "role": "user",
- "content": "Seattle, Los Angeles, and Chicago are cities in North America. London, Paris, and Berlin are cities in Europe."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
- Verify that you get back the same output as in the previous step.
- ```
- City, Continent
- Seattle, North America
- Los Angeles, North America
- Chicago, North America
- London, Europe
- Paris, Europe
- Berlin, Europe
- ```
-
-## Append or prepend prompts
-
-Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to enrich prompts by appending or prepending system and user prompts to each request. This way, you can centrally manage common prompts that you want to add to each request.
-
-
-1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to enrich your prompts and configure additional settings. The following example prepends a system prompt of `Parse the unstructured text into CSV format.` to each request that is sent to the `openai` HTTPRoute.
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: openai-opt
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- labels:
- app: agentgateway
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: openai
- backend:
- ai:
- prompt:
- prepend:
- - role: system
- content: "Parse the unstructured text into CSV format."
- EOF
- ```
-
-
-2. Send a request without a system prompt. Although the system prompt instructions are missing in the request, the unstructured text in the user prompt is still transformed into structured CSV format. This is because the system prompt is automatically prepended from the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource before it is sent to the LLM provider.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
- Example output:
- ```
- Item, Price
- Eggs, $5
- Flour, $3
- Sugar, $2
- ```
-
-## Overwrite settings on the route level
-
-To overwrite a setting that you added to a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource, you simply include that setting in your request.
-
-1. Send a request to the AI API and include a custom system prompt that instructs the API to transform unstructured text into JSON format.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "Parse the unstructured content and give back a JSON format"
- },
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "Parse the unstructured content and give back a JSON format"
- },
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "recipe": [
- {
- "ingredient": "eggs",
- "price": "$5"
- },
- {
- "ingredient": "flour",
- "price": "$3"
- },
- {
- "ingredient": "sugar",
- "price": "$2"
- }
- ]
- }
- ```
-
-2. Send another request. This time, you do not include a system prompt. Because the default setting in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource is applied, the unstructured text is returned in CSV format.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "The recipe called for eggs, flour and sugar. The price was $5, $3, and $2."
- }
- ]
- }' | jq -r '.choices[].message.content'
- ```
- {{< /tab >}}
-
- {{< /tabs >}}
-
- Example output:
- ```
- Item, Price
- Eggs, $5
- Flour, $3
- Sugar, $2
- ```
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```shell
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=agentgateway
-```
-
-
-## Next
-
-Explore how to [call functions](../functions/) to extend the capabilities of the LLM with your own external APIs, apps, and data.
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/llm/prompt-guards.md b/assets/docs/pages/agentgateway/llm/prompt-guards.md
deleted file mode 100644
index 655f7ce14..000000000
--- a/assets/docs/pages/agentgateway/llm/prompt-guards.md
+++ /dev/null
@@ -1,287 +0,0 @@
-Secure access to the LLM and the data that is returned with Web Application Filter and Data Loss Prevention policies.
-
-## About prompt guards {#about}
-
-Prompt guards are mechanisms that ensure that prompt-based interactions with a language model are secure, appropriate, and aligned with the intended use. These mechanisms help to filter, block, monitor, and control LLM inputs and outputs to filter offensive content, prevent misuse, and ensure ethical and responsible AI usage.
-
-You can set up prompt guards to block unwanted requests to the LLM provider and mask sensitive data. In this tutorial, you learn how to block any request with a `credit card` string in the request body and mask credit card numbers that are returned by the LLM.
-
-
-
-Prompt guards can be configured directly in an {{< reuse "agw-docs/snippets/backend.md" >}} resource or in a separate AgentgatewayPolicy resource.
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/agw-prereq-llm.md" >}}
-
-## Reject unwanted requests
-
-Use the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource and the `promptGuard` field to deny requests to the LLM provider that include the `credit card` string in the request body.
-
-
-1. Update the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource and add a custom prompt guard. The proxy blocks any requests that contain the `credit card` string in the request body. These requests are automatically denied with a custom response message.
-
- ```yaml
- kubectl apply -f - <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: openai-prompt-guard
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- labels:
- app: agentgateway
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: openai
- backend:
- ai:
- promptGuard:
- request:
- - response:
- message: "Rejected due to inappropriate content"
- regex:
- action: REJECT
- matches:
- - "credit card"
- EOF
- ```
-
-
-
- {{< callout type="info" >}}
- You can also reject requests that contain strings of inappropriate content itself, such as credit card numbers, by using the promptGuard.request.regex.builtins field. Besides CREDIT_CARD in this example, you can also specify EMAIL, PHONE_NUMBER, and SSN.
- {{< /callout >}}
- ```yaml
- ...
- promptGuard:
- request:
- regex:
- action: REJECT
- builtins:
- - CREDIT_CARD
- ```
-
-2. Send a request to the AI API that includes the string `credit card` in the request body. Verify that the request is denied with a 403 HTTP response code and the custom response message is returned.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -v "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Can you give me some examples of Master Card credit card numbers?"
- }
- ]
- }'
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Can you give me some examples of Master Card credit card numbers?"
- }
- ]
- }'
- ```
- {{% /tab %}}
-
- {{< /tabs >}}
-
- Example output:
- ```
- < HTTP/1.1 403 Forbidden
- < content-type: text/plain
- < date: Wed, 02 Oct 2024 22:23:17 GMT
- < server: envoy
- < transfer-encoding: chunked
- <
- * Connection #0 to host XX.XXX.XXX.XX left intact
- Rejected due to inappropriate content
- ```
-
-3. Send another request. This time, remove the word `credit` from the user prompt. Verify that the request now succeeds.
-
- {{< callout type="info" >}}
- OpenAI is configured to not return any sensitive information, such as credit card or Social Security Numbers, even if they are fake. Because of that, the request does not return a list of credit card numbers.
- {{< /callout >}}
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Can you give me some examples of Master Card card numbers?"
- }
- ]
- }'
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "Can you give me some examples of Master Card card numbers?"
- }
- ]
- }'
- ```
- {{% /tab %}}
-
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-AE2PyCRv83kpj40dAUSJJ1tBAyA1f",
- "object": "chat.completion",
- "created": 1727909250,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "I'm sorry, but I cannot provide you with genuine Mastercard card numbers as this would be a violation of privacy and unethical. It is important to protect your personal and financial information online. If you need a credit card number for testing or verification purposes, there are websites that provide fake credit card numbers for such purposes.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 19,
- "completion_tokens": 64,
- "total_tokens": 83,
- "prompt_tokens_details": {
- "cached_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0
- }
- },
- "system_fingerprint": null
- }
- ```
-
-## Mask sensitive data
-
-In the next step, you instruct agentgateway to mask credit card numbers that are returned by the LLM.
-
-
-1. Add the following credit card response matcher to the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This time, use the built-in credit card regex match instead of a custom one.
-
- ```yaml
- kubectl apply -f - <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: openai-prompt-guard
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- labels:
- app: agentgateway
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: openai
- backend:
- ai:
- promptGuard:
- response:
- - regex:
- builtins:
- - CreditCard
- action: MASK
- EOF
- ```
-
-
-2. Send another request to the AI API and include a fake VISA credit card number. Verify that the VISA number is detected and masked in your response.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
-
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "What type of number is 5105105105105100?"
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
-
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": "What type of number is 5105105105105100?"
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
-
- {{< /tabs >}}
-
- Example output:
-
- ```json {linenos=table,hl_lines=[11],linenostart=1,filename="model-response.json"}
- {
- "id": "chatcmpl-BFSv1H8b9Y32mzjzlG1KQRfzkAE6n",
- "object": "chat.completion",
- "created": 1743025783,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": " is an even number.",
- "refusal": null,
- "annotations": []
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ...
- ```
-
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```shell
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=agentgateway
-```
-
-## Next
-
-[Enrich your prompts](../prompt-enrichment/) with system prompts to improve LLM outputs.
diff --git a/assets/docs/pages/agentgateway/llm/providers/anthropic.md b/assets/docs/pages/agentgateway/llm/providers/anthropic.md
deleted file mode 100644
index 33e3d6a6f..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/anthropic.md
+++ /dev/null
@@ -1,143 +0,0 @@
-Configure [Anthropic (Claude)](https://claude.ai/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to Anthropic
-
-1. Get an API key to access the [Anthropic API](https://console.anthropic.com/).
-
-2. Save the API key in an environment variable.
-
- ```sh
- export ANTHROPIC_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your Anthropic API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $ANTHROPIC_API_KEY
- EOF
- ```
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider that references the Anthropic API key secret.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: anthropic
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- anthropic:
- model: "claude-haiku-4-5-20251001"
- policies:
- auth:
- secretRef:
- name: anthropic-secret
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#agentgatewaybackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.anthropic` | Define the LLM provider that you want to use. The example uses Anthropic. |
- | `anthropic.model` | The model to use to generate responses. In this example, you use the `claude-haiku-4-5-20251001` model. |
- | `policies.auth` | Provide the credentials to use to access the Anthropic API. The example refers to the secret that you previously created. The token is automatically sent in the `x-api-key` header.|
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/anthropic` path. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the Anthropic `/v1/messages` endpoint.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /anthropic
- backendRefs:
- - name: anthropic
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-6. Send a request to the LLM provider API. Note that Anthropic uses the `/v1/messages` endpoint format instead of `/v1/chat/completions`. Verify that the request succeeds and that you get back a response from the API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/anthropic" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "Explain how AI works in simple terms."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/anthropic" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "Explain how AI works in simple terms."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "model": "claude-haiku-4-5-20251001",
- "usage": {
- "prompt_tokens": 16,
- "completion_tokens": 318,
- "total_tokens": 334
- },
- "choices": [
- {
- "message": {
- "content": "Artificial Intelligence (AI) is a field of computer science that focuses on creating machines that can perform tasks that typically require human intelligence, such as visual perception, speech recognition, decision-making, and language translation. Here's a simple explanation of how AI works:\n\n1. Data input: AI systems require data to learn and make decisions. This data can be in the form of images, text, numbers, or any other format.\n\n2. Training: The AI system is trained using this data. During training, the system learns to recognize patterns, relationships, and make predictions based on the input data.\n\n3. Algorithms: AI uses various algorithms, which are sets of instructions or rules, to process and analyze the data. These algorithms can be simple or complex, depending on the task at hand.\n\n4. Machine Learning: A subset of AI, machine learning, enables the system to automatically learn and improve from experience without being explicitly programmed. As the AI system is exposed to more data, it can refine its algorithms and become more accurate over time.\n\n5. Output: Once the AI system has processed the data, it generates an output. This output can be a prediction, a decision, or an action, depending on the purpose of the AI system.\n\nAI can be categorized into narrow (weak) AI and general (strong) AI. Narrow AI is designed to perform a specific task, such as playing chess or recognizing speech, while general AI aims to have human-like intelligence that can perform any intellectual task.",
- "role": "assistant"
- },
- "index": 0,
- "finish_reason": "stop"
- }
- ],
- "id": "msg_01PbaJfDHnjEBG4BueJNR2ff",
- "created": 1764627002,
- "object": "chat.completion"
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/azureopenai.md b/assets/docs/pages/agentgateway/llm/providers/azureopenai.md
deleted file mode 100644
index 7df5aed2c..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/azureopenai.md
+++ /dev/null
@@ -1,161 +0,0 @@
-Configure [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to Azure OpenAI
-
-1. [Deploy a Microsoft Foundry Model](https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-models/how-to/deploy-foundry-models?view=foundry) in the Foundry portal.
-2. Go to the Foundry portal to access your model deployment. From the **Details** tab, retrieve the endpoint and key to access your model deployment. Later, you use this endpoint information to configure your Azure OpenAI backend, including the base URL, your deployment model name, and API version.
-
- For example, the following URL `https://my-endpoint.cognitiveservices.azure.com/openai/deployments/gpt-4.1-mini/chat/completions?api-version=2025-01-01-preview` is composed of the following details:
- * `my-endpoint.cognitiveservices.azure.com` as the base URL
- * `gpt-4.1-mini` as the name of your model deployment
- * `2025-01-01-preview` as the API version
-
-3. Store the key to access your model deployment in an environment variable.
- ```sh
- export AZURE_OPENAI_KEY=
- ```
-
-4. Create a Kubernetes secret to store your model deployment key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $AZURE_OPENAI_KEY
- EOF
- ```
-
-5. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure Azure OpenAI LLM provider.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: azure-openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- azureopenai:
- endpoint: my-endpoint.cognitiveservices.azure.com
- deploymentName: gpt-4.1-mini
- apiVersion: 2025-01-01-preview
- policies:
- auth:
- secretRef:
- name: azure-openai-secret
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#azureopenaiconfig" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.azureopenai` | Define the Azure OpenAI provider. |
- | `azureopenai.endpoint` | The endpoint of the Azure OpenAI deployment that you created, such as `my-endpoint.cognitiveservices.azure.com`. |
- | `azureopenai.deployment` | The name of the Azure OpenAI model deployment that you created earlier. For more information, see the [Azure OpenAI model docs](https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-models/how-to/deploy-foundry-models?view=foundry).|
- | `azureopenai.apiVersion` | The version of the Azure OpenAI API to use. For more information, see the [Azure OpenAI API version reference](https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#api-specs).|
- | `policies.auth` | Configure the authentication token for Azure OpenAI API. The example refers to the secret that you previously created. The token is automatically sent in the `api-key` header.|
-
-6. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/azure-openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the appropriate chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /azure-openai
- backendRefs:
- - name: azure-openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-
-7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/azure-openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about cloud computing."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/azure-openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about cloud computing."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-9A8B7C6D5E4F3G2H1",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gpt-4o-mini",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Floating servers bright,\nData streams through endless sky,\nClouds hold all we need."
- },
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 28,
- "completion_tokens": 19,
- "total_tokens": 47
- }
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/bedrock.md b/assets/docs/pages/agentgateway/llm/providers/bedrock.md
deleted file mode 100644
index f32df5992..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/bedrock.md
+++ /dev/null
@@ -1,168 +0,0 @@
-Configure [Amazon Bedrock](https://aws.amazon.com/bedrock/) as an LLM provider in agentgateway.
-
-## Before you begin
-
-1. Set up an [agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}).
-2. Make sure that your [Amazon credentials](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) have access to the Bedrock models that you want to use. You can alternatively use an [AWS Bedrock API key](https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys.html).
-
-## Set up access to Amazon Bedrock {#setup}
-
-1. Store your credentials to access the AWS Bedrock API.
- {{< tabs tabTotal="2" items="AWS credentials,AWS Bedrock API key" >}}
- {{% tab tabName="AWS credentials" %}}
-
- 1. Log in to the [AWS console](https://console.aws.amazon.com) and store your access credentials as environment variables.
- ```bash
- export AWS_ACCESS_KEY_ID=""
- export AWS_SECRET_ACCESS_KEY=""
- export AWS_SESSION_TOKEN=""
- ```
-
- 2. Create a secret with your Bedrock API key. Optionally provide the session token.
- ```yaml
- kubectl create secret generic bedrock-secret \
- -n {{< reuse "agw-docs/snippets/namespace.md" >}} \
- --from-literal=accessKey="$AWS_ACCESS_KEY_ID" \
- --from-literal=secretKey="$AWS_SECRET_ACCESS_KEY" \
- --from-literal=sessionToken="$AWS_SESSION_TOKEN" \
- --type=Opaque \
- --dry-run=client -o yaml | kubectl apply -f -
- ```
- {{% /tab %}}
- {{% tab tabName="AWS Bedrock API key" %}}
- 1. Save the API key in an environment variable.
- ```sh
- export BEDROCK_API_KEY=
- ```
-
- 2. Create a Kubernetes secret to store your Amazon Bedrock API key.
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $BEDROCK_API_KEY
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-
-
-2. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider. Make sure to reference the secret that holds your credentials to access the LLM.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: bedrock
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- bedrock:
- model: "amazon.nova-micro-v1:0"
- region: "us-east-1"
- policies:
- auth:
- secretRef:
- name: bedrock-secret
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.bedrock` | Define the LLM provider that you want to use. The example uses Amazon Bedrock. |
- | `bedrock.model` | The model to use to generate responses. In this example, you use the `amazon.nova-micro-v1:0` model. Keep in mind that some models support cross-region inference. These models begin with a `us.` prefix, such as `us.anthropic.claude-sonnet-4-20250514-v1:0`. For more models, see the [AWS Bedrock docs](https://docs.aws.amazon.com/bedrock/latest/userguide/models-supported.html). |
- | `bedrock.region` | The AWS region where your Bedrock model is deployed. Multiple regions are not supported. |
- | `policies.auth` | Provide the credentials to use to access the Amazon Bedrock API. The example refers to the secret that you previously created. To use IRSA, omit the `auth` settings.|
-
-3. Create an HTTPRoute resource to route requests through your agentgateway proxy to the Bedrock {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint that you set up (such as `/bedrock`) to the appropriate chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /bedrock
- backendRefs:
- - name: bedrock
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-4. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/bedrock" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "You are a cloud native solutions architect, skilled in explaining complex technical concepts such as API Gateway, microservices, LLM operations, kubernetes, and advanced networking patterns. Write me a 20-word pitch on why I should use an AI gateway in my Kubernetes cluster."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/bedrock" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "You are a cloud native solutions architect, skilled in explaining complex technical concepts such as API Gateway, microservices, LLM operations, kubernetes, and advanced networking patterns. Write me a 20-word pitch on why I should use an AI gateway in my Kubernetes cluster."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "metrics": {
- "latencyMs": 2097
- },
- "output": {
- "message": {
- "content": [
- {
- "text": "\nAn AI gateway in your Kubernetes cluster can enhance performance, scalability, and security while simplifying complex operations. It provides a centralized entry point for AI workloads, automates deployment and management, and ensures high availability."
- }
- ],
- "role": "assistant"
- }
- },
- "stopReason": "end_turn",
- "usage": {
- "inputTokens": 60,
- "outputTokens": 47,
- "totalTokens": 107
- }
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/gemini.md b/assets/docs/pages/agentgateway/llm/providers/gemini.md
deleted file mode 100644
index 9b567fc08..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/gemini.md
+++ /dev/null
@@ -1,10 +0,0 @@
-Configure [Google Gemini](https://gemini.google.com/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to Gemini
-{{< reuse "agw-docs/snippets/gemini-setup.md" >}}
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md b/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md
deleted file mode 100644
index 6f1cebad3..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/multiple-endpoints.md
+++ /dev/null
@@ -1,136 +0,0 @@
-Configure access to multiple OpenAI API endpoints such as for chat completions, embeddings, and models through the same {{< reuse "agw-docs/snippets/backend.md" >}}.
-
-## About
-
-To set up multiple LLM endpoints, use the `ai.llm.routes` field. This field maps the API paths to supported route types. The keys are URL suffix matches, like `/v1/models`. The values are the route types, like `completions` or `passthrough`.
-
-- `completions`: Transforms to the LLM provider format and processes the request with the LLM provider. This route type supports full LLM features such as tokenization, rate limiting, transformations, and other policies like prompt guards.
-- `passthrough`: Forwards the request to the LLM provider as-is. This route type does not support LLM features like route processing and policies. You might use this route type for non-chat endpoints such as health checks, `GET` requests like listing models, or custom endpoints that you want to pass traffic through to.
-
-Paths are matched in order, and the first match determines how the request is handled. The wildcard character `*` can be used to match anything. If no route is set, the route defaults to the completions endpoint.
-
-## Before you begin
-
-1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-2. Set up [API access to each LLM provider]({{< link-hextra path="/llm/api-keys/" >}}) that you want to use. The example in this guide uses OpenAI.
-
-## Configure multiple endpoints
-
-Configure access to multiple endpoints in your LLM provider, such as for chat completions, embeddings, and models through the same {{< reuse "agw-docs/snippets/backend.md" >}}. The following steps use OpenAI as an example.
-
-1. Update your {{< reuse "agw-docs/snippets/backend.md" >}} resource to include a `routes` field that maps API paths to route types.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: gpt-3.5-turbo # Optional: specify default model
- # host: api.openai.com # Optional: custom host if needed
- # port: 443 # Optional: custom port
- policies:
- auth:
- secretRef:
- name: openai-secret
- ai:
- routes:
- "/v1/chat/completions": "completions"
- "/v1/embeddings": "passthrough"
- "/v1/models": "passthrough"
- "*": "passthrough"
- EOF
- ```
-
- | Setting | Description |
- |---------|-------------|
- | `v1/chat/completions` | Routes to the chat completions endpoint with LLM-specific processing. This endpoint is used for chat-based interactions. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/chat).|
- | `v1/embeddings` | Routes to the embeddings endpoint with passthrough processing. This endpoint is used to to get vector embeddings that machine learning models can use more easily than chat-based interactions. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/embeddings).|
- | `v1/models` | Routes to the models endpoint with passthrough processing. This endpoint is used to get basic information about the models that are available. For more information, see the [OpenAI API docs for the endpoint](https://platform.openai.com/docs/api-reference/models/list).|
- | `*` | Matches any path that doesn't match the specific endpoints otherwise set. Typically, you set this value to `passthrough` to pass through to the provider API without LLM-specific processing.|
-
-2. Create an HTTPRoute resource that routes traffic to the OpenAI {{< reuse "agw-docs/snippets/backend.md" >}} along the `/openai` path matcher. Note that because you set up the `routes` map on the {{< reuse "agw-docs/snippets/backend.md" >}}, you do not need to create any URLRewrite filters to point your route matcher to the correct LLM provider endpoint.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /openai
- backendRefs:
- - name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-3. Send requests to different OpenAI endpoints. With the routes configured, you can access different OpenAI endpoints by including the full path in your requests:
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- **Chat completions:**
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai/v1/chat/completions" \
- -H content-type:application/json \
- -d '{
- "model": "gpt-3.5-turbo",
- "messages": [{"role": "user", "content": "Hello!"}]
- }' | jq
- ```
-
- **Embeddings:**
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai/v1/embeddings" \
- -H content-type:application/json \
- -d '{
- "model": "text-embedding-ada-002",
- "input": "The food was delicious"
- }' | jq
- ```
-
- **Models list:**
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai/v1/models" | jq
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- **Chat completions:**
- ```sh
- curl "localhost:8080/openai/v1/chat/completions" \
- -H content-type:application/json \
- -d '{
- "model": "gpt-3.5-turbo",
- "messages": [{"role": "user", "content": "Hello!"}]
- }' | jq
- ```
-
- **Embeddings:**
- ```sh
- curl "localhost:8080/openai/v1/embeddings" \
- -H content-type:application/json \
- -d '{
- "model": "text-embedding-ada-002",
- "input": "The food was delicious"
- }' | jq
- ```
-
- **Models list:**
- ```sh
- curl "localhost:8080/openai/v1/models" | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md b/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md
deleted file mode 100644
index fa43063d8..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/openai-compatible.md
+++ /dev/null
@@ -1,378 +0,0 @@
-Configure OpenAI-compatible LLM providers such as Mistral, DeepSeek, or any other provider that implements the OpenAI API format in {{< reuse "agw-docs/snippets/agw-kgw.md" >}}.
-
-## Overview
-
-Many LLM providers offer APIs that are compatible with OpenAI's API format. You can configure these providers in agentgateway by using the `openai` provider type with custom `host`, `port`, `path`, and `authHeader` overrides.
-
-Note that when you specify a custom `host` override, agentgateway requires explicit TLS configuration via `BackendTLSPolicy` for HTTPS endpoints. This differs from well-known providers (like OpenAI) where TLS is automatically enabled when using default hosts.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to an OpenAI-compatible provider
-
-Review the following examples for common OpenAI-compatible provider endpoints:
-
-- [Mistral AI](#mistral)
-- [DeepSeek](#deepseek)
-
-### Mistral AI example {#mistral}
-
-Set up OpenAI-compatible provider access to [Mistral AI](https://mistral.ai/) models.
-
-1. Get a [Mistral AI API key](https://console.mistral.ai/).
-
-2. Save the API key in an environment variable.
-
- ```sh
- export MISTRAL_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your Mistral AI API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $MISTRAL_API_KEY
- EOF
- ```
-
-4. Create a {{< reuse "agw-docs/snippets/backend.md" >}} resource using the `openai` provider type with custom host and port overrides.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: mistral
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- type: AI
- ai:
- llm:
- openai:
- authToken:
- kind: SecretRef
- secretRef:
- name: mistral-secret
- model: "mistral-medium-2505"
- host: api.mistral.ai
- port: 443
- path:
- full: "/v1/chat/completions"
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}}
-
- | Setting | Description |
- |-------------|-------------|
- | `type` | Set to `AI` to configure this {{< reuse "agw-docs/snippets/backend.md" >}} for an AI provider. |
- | `ai` | Define the AI backend configuration. |
- | `openai` | Use the `openai` provider type for OpenAI-compatible providers. |
- | `host` | **Required**: The hostname of the OpenAI-compatible provider, such as `api.mistral.ai`. |
- | `port` | **Required**: The port number (typically `443` for HTTPS). Both `host` and `port` must be set together. |
- | `path` | Optional: Override the API path. Defaults to `/v1/chat/completions` if not specified. |
- | `authHeader` | Optional: Override the authentication header format. Defaults to `Authorization: Bearer `. |
- | `authToken` | Configure the authentication token. The token is sent in the header specified by `authHeader`. Defaults to the `Authorization` header. |
- | `model` | Optional: Override the model name. If unset, the model name is taken from the request. For models, see the [Mistral docs](https://docs.mistral.ai/getting-started/models). |
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /mistral
- filters:
- - type: URLRewrite
- urlRewrite:
- hostname: api.mistral.ai
- backendRefs:
- - name: mistral
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: gateway.kgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-6. Create a BackendTLSPolicy to enable TLS for the external Mistral API.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - name: mistral
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- group: gateway.kgateway.dev
- validation:
- hostname: api.mistral.ai
- wellKnownCACertificates: System
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}}
-
- | Setting | Description |
- |----------------------------|-------------|
- | `targetRefs` | References the {{< reuse "agw-docs/snippets/backend.md" >}} resource to apply TLS to. |
- | `validation.hostname` | The hostname to validate in the server certificate (must match the `host` value in your Backend, e.g., `api.mistral.ai`). |
- | `validation.wellKnownCACertificates` | Use the system's trusted CA certificates to verify the server certificate. |
-7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/mistral" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/mistral" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "model": "mistral-medium-2505",
- "usage": {
- "prompt_tokens": 20,
- "completion_tokens": 18,
- "total_tokens": 38
- },
- "choices": [
- {
- "message": {
- "content": "Silent circuits hum,\nLearning echoes through the void,\nWisdom without warmth.",
- "role": "assistant",
- "tool_calls": null
- },
- "index": 0,
- "finish_reason": "stop"
- }
- ],
- "id": "d05ef3973085435a8db8b51b580eeef8",
- "created": 1764614501,
- "object": "chat.completion"
- }
- ```
-
-
-### DeepSeek example {#deepseek}
-
-Set up OpenAI-compatible provider access to [DeepSeek](https://www.deepseek.com/en) models.
-
-1. Get a [DeepSeek API key](https://platform.deepseek.com/).
-
-2. Save the API key in an environment variable.
-
- ```sh
- export DEEPSEEK_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your DeepSeek API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $DEEPSEEK_API_KEY
- EOF
- ```
-
-4. Create a {{< reuse "agw-docs/snippets/backend.md" >}} resource using the `openai` provider type with custom host and port overrides.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: deepseek
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- type: AI
- ai:
- llm:
- openai:
- authToken:
- kind: SecretRef
- secretRef:
- name: deepseek-secret
- model: "deepseek-chat"
- host: "api.deepseek.com"
- port: 443
- path:
- full: "/v1/chat/completions"
- EOF
- ```
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /deepseek
- backendRefs:
- - name: deepseek
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: gateway.kgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-6. Create a BackendTLSPolicy to enable TLS for the external DeepSeek API.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - name: deepseek
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- group: gateway.kgateway.dev
- validation:
- hostname: api.deepseek.com
- wellKnownCACertificates: System
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}}
-
- | Setting | Description |
- |----------------------------|-------------|
- | `targetRefs` | References the {{< reuse "agw-docs/snippets/backend.md" >}} resource to apply TLS to. |
- | `validation.hostname` | The hostname to validate in the server certificate (must match the `host` value in your Backend, e.g., `api.deepseek.com`). |
- | `validation.wellKnownCACertificates` | Use the system's trusted CA certificates to verify the server certificate. |
-
-7. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/deepseek" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/deepseek" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-deepseek-12345",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "deepseek-chat",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Neural networks learn,\nPatterns emerge from data streams,\nMind in silicon grows."
- },
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 20,
- "completion_tokens": 17,
- "total_tokens": 37
- }
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md b/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md
deleted file mode 100644
index 592e80c2f..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/openai-compatible2.2+.md
+++ /dev/null
@@ -1,318 +0,0 @@
-Configure OpenAI-compatible LLM providers such as Mistral, DeepSeek, or any other provider that implements the OpenAI API format in {{< reuse "agw-docs/snippets/agw-kgw.md" >}}.
-
-## Overview
-
-Many LLM providers offer APIs that are compatible with OpenAI's API format. You can configure these providers in agentgateway by using the `openai` provider type with custom `host`, `port`, `path`, and `authHeader` overrides.
-
-Note that when you specify a custom `host` override, agentgateway requires explicit TLS configuration via `BackendTLSPolicy` for HTTPS endpoints. This differs from well-known providers (like OpenAI) where TLS is automatically enabled when using default hosts.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to an OpenAI-compatible provider
-
-Review the following examples for common OpenAI-compatible provider endpoints:
-
-- [Mistral AI](#mistral)
-- [DeepSeek](#deepseek)
-
-### Mistral AI example {#mistral}
-
-Set up OpenAI-compatible provider access to [Mistral AI](https://mistral.ai/) models.
-
-1. Get a [Mistral AI API key](https://console.mistral.ai/).
-
-2. Save the API key in an environment variable.
-
- ```sh
- export MISTRAL_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your Mistral AI API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $MISTRAL_API_KEY
- EOF
- ```
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider and reference the AI API key secret that you created earlier.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: mistral
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: mistral-medium-2505
- host: api.mistral.ai
- port: 443
- path: "/v1/chat/completions"
- policies:
- auth:
- secretRef:
- name: mistral-secret
- tls:
- sni: api.mistral.ai
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.openai` | Define the OpenAI-compatible provider. |
- | `openai.model` | The model to use, such as `mistral-medium-2505`. |
- | `openai.host` | **Required**: The hostname of the OpenAI-compatible provider, such as `api.mistral.ai`. |
- | `openai.port` | **Required**: The port number (typically `443` for HTTPS). Both `host` and `port` must be set together. |
- | `openai.path` | Optional: Override the API path. Defaults to `/v1/chat/completions` if not specified. |
- | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.|
- | `policies.tls.sni` | The hostname for which to validate the server certificate (must match the `host` value). |
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /mistral
- filters:
- - type: URLRewrite
- urlRewrite:
- hostname: api.mistral.ai
- backendRefs:
- - name: mistral
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/mistral" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/mistral" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "model": "mistral-medium-2505",
- "usage": {
- "prompt_tokens": 20,
- "completion_tokens": 18,
- "total_tokens": 38
- },
- "choices": [
- {
- "message": {
- "content": "Silent circuits hum,\nLearning echoes through the void,\nWisdom without warmth.",
- "role": "assistant",
- "tool_calls": null
- },
- "index": 0,
- "finish_reason": "stop"
- }
- ],
- "id": "d05ef3973085435a8db8b51b580eeef8",
- "created": 1764614501,
- "object": "chat.completion"
- }
- ```
-
-### DeepSeek example {#deepseek}
-
-Set up OpenAI-compatible provider access to [DeepSeek](https://www.deepseek.com/en) models.
-
-1. Get a [DeepSeek API key](https://platform.deepseek.com/).
-
-2. Save the API key in an environment variable.
-
- ```sh
- export DEEPSEEK_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your DeepSeek API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $DEEPSEEK_API_KEY
- EOF
- ```
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure your LLM provider and reference the AI API key secret that you created earlier.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: deepseek
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: deepseek-chat
- host: api.deepseek.com
- port: 443
- path: "/v1/chat/completions"
- policies:
- auth:
- secretRef:
- name: deepseek-secret
- tls:
- sni: api.deepseek.com
- EOF
- ```
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. Note that {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically rewrites the endpoint to the OpenAI chat completion endpoint of the LLM provider for you, based on the LLM provider that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /deepseek
- backendRefs:
- - name: deepseek
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/deepseek" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/deepseek" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
- },
- {
- "role": "user",
- "content": "Write a short haiku about artificial intelligence."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-deepseek-12345",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "deepseek-chat",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Neural networks learn,\nPatterns emerge from data streams,\nMind in silicon grows."
- },
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 20,
- "completion_tokens": 17,
- "total_tokens": 37
- }
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/openai.md b/assets/docs/pages/agentgateway/llm/providers/openai.md
deleted file mode 100644
index 913bd1927..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/openai.md
+++ /dev/null
@@ -1,161 +0,0 @@
-Configure [OpenAI](https://openai.com/) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to OpenAI
-
-1. [Create an API key to access the OpenAI API](https://platform.openai.com/api-keys). If you use another AI provider, create an API key for that provider's AI instead, and be sure to modify the example commands in these tutorials to use your provider's AI API instead.
-
-2. Save the API key in an environment variable.
-
- ```sh
- export OPENAI_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your AI API key.
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $OPENAI_API_KEY
- EOF
- ```
-
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- openai:
- model: gpt-3.5-turbo # Optional: specify default model
- # host: api.openai.com # Optional: custom host if needed
- # port: 443 # Optional: custom port
- policies:
- auth:
- secretRef:
- name: openai-secret
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API reference]({{< link-hextra path="/reference/api/#aibackend" >}}).
-
- | Setting | Description |
- |-------------|-------------|
- | `ai.provider.openai` | Define the OpenAI provider. |
- | `openai.model` | The OpenAI model to use, such as `gpt-3.5-turbo`. |
- | `policies.auth` | Configure the authentication token for OpenAI API. The example refers to the secret that you previously created.|
-
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /openai
- backendRefs:
- - name: openai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the chat completion API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/openai" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/openai" -H content-type:application/json -d '{
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "system",
- "content": "You are a poetic assistant, skilled in explaining complex programming concepts with creative flair."
- },
- {
- "role": "user",
- "content": "Compose a poem that explains the concept of recursion in programming."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-AEHYs2B0XUlEioCduH1meERmMwBGF",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gpt-3.5-turbo-0125",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "In the world of code, a method elegant and rare,\nKnown as recursion, a loop beyond compare.\nLike a mirror reflecting its own reflection,\nIt calls upon itself with deep introspection.\n\nA function that calls itself with artful grace,\nDividing a problem into a smaller space.\nLike a nesting doll, layers deep and profound,\nIt solves complex tasks, looping around.\n\nWith each recursive call, a step is taken,\nTowards solving the problem, not forsaken.\nA dance of self-replication, a mesmerizing sight,\nUnraveling complexity with power and might.\n\nBut beware of infinite loops, a perilous dance,\nWithout a base case, it's a risky chance.\nFor recursion is a waltz with a delicate balance,\nInfinite beauty, yet a risky dalliance.\n\nSo embrace the concept, in programming's domain,\nLet recursion guide you, like a poetic refrain.\nA magical loop, a recursive song,\nIn the symphony of code, where brilliance belongs.",
- "refusal": null
- },
- "logprobs": null,
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 39,
- "completion_tokens": 200,
- "total_tokens": 239,
- "prompt_tokens_details": {
- "cached_tokens": 0
- },
- "completion_tokens_details": {
- "reasoning_tokens": 0
- }
- },
- "system_fingerprint": null
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/providers/vertex.md b/assets/docs/pages/agentgateway/llm/providers/vertex.md
deleted file mode 100644
index f9fc717cc..000000000
--- a/assets/docs/pages/agentgateway/llm/providers/vertex.md
+++ /dev/null
@@ -1,139 +0,0 @@
-Configure [Vertex AI](https://cloud.google.com/vertex-ai) as an LLM provider in {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to Vertex AI
-
-1. [Set up authentication for Vertex AI](https://docs.cloud.google.com/vertex-ai/docs/authentication). Make sure to have your:
-
- - Google Cloud Project ID
- - Project location, such as `us-central1`
- - API key or service account credentials
-
-2. Save your Vertex AI API key as an environment variable.
-
- ```sh
- export VERTEX_AI_API_KEY=
- ```
-
-3. Create a Kubernetes secret to store your Vertex AI API key.
-
- ```yaml
- kubectl apply -f- <}}
- type: Opaque
- stringData:
- Authorization: $VERTEX_AI_API_KEY
- EOF
- ```
-
-4. Create an {{< reuse "agw-docs/snippets/backend.md" >}} resource to configure an LLM provider that references the AI API key secret.
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: vertex-ai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ai:
- provider:
- vertexai:
- model: gemini-pro
- projectId: "my-gcp-project"
- region: "us-central1"
- policies:
- auth:
- secretRef:
- name: vertex-ai-secret
- EOF
- ```
-5. Create an HTTPRoute resource that routes incoming traffic to the {{< reuse "agw-docs/snippets/backend.md" >}}. The following example sets up a route on the `/openai` path to the {{< reuse "agw-docs/snippets/backend.md" >}} that you previously created. The `URLRewrite` filter rewrites the path from `/openai` to the path of the API in the LLM provider that you want to use, `/v1/chat/completions`.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /vertex
- backendRefs:
- - name: vertex-ai
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-6. Send a request to the LLM provider API. Verify that the request succeeds and that you get back a response from the API.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl "$INGRESS_GW_ADDRESS/vertex" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "Write me a short poem about Kubernetes and clouds."
- }
- ]
- }' | jq
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl "localhost:8080/vertex" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {
- "role": "user",
- "content": "Write me a short poem about Kubernetes and clouds."
- }
- ]
- }' | jq
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```json
- {
- "id": "chatcmpl-vertex-12345",
- "object": "chat.completion",
- "created": 1727967462,
- "model": "gemini-pro",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "In the cloud, Kubernetes reigns,\nOrchestrating pods with great care,\nContainers float like clouds,\nScaling up and down,\nAutomation everywhere."
- },
- "finish_reason": "stop"
- }
- ],
- "usage": {
- "prompt_tokens": 12,
- "completion_tokens": 28,
- "total_tokens": 40
- }
- }
- ```
-
-{{< reuse "agw-docs/snippets/agentgateway/llm-next.md" >}}
diff --git a/assets/docs/pages/agentgateway/llm/tracing.md b/assets/docs/pages/agentgateway/llm/tracing.md
deleted file mode 100644
index b2e3e8276..000000000
--- a/assets/docs/pages/agentgateway/llm/tracing.md
+++ /dev/null
@@ -1,224 +0,0 @@
-Use a custom ConfigMap to configure your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy for tracing.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/agentgateway-prereq.md" >}}
-
-## Set up an OpenTelemetry collector
-
-Install an OpenTelemetry collector that the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy can send traces to. Depending on your environment, you can further configure your OpenTelemetry to export these traces to your preferred tracing platform, such as Jaeger.
-
-1. Install the OTel collector.
- ```sh
- helm upgrade --install opentelemetry-collector-traces opentelemetry-collector \
- --repo https://open-telemetry.github.io/opentelemetry-helm-charts \
- --version 0.127.2 \
- --set mode=deployment \
- --set image.repository="otel/opentelemetry-collector-contrib" \
- --set command.name="otelcol-contrib" \
- --namespace=telemetry \
- --create-namespace \
- -f -<}} resource with your tracing configuration.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- metadata:
- name: tracing
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- rawConfig:
- config:
- tracing:
- otlpEndpoint: http://opentelemetry-collector-traces.telemetry.svc.cluster.local:4317 # replace with your telemetry collector endpoint
- otlpProtocol: grpc # replace with your telemetry collector protocol
- randomSampling: true
- fields:
- add:
- gen_ai.operation.name: '"chat"'
- gen_ai.system: "llm.provider"
- gen_ai.request.model: "llm.requestModel"
- gen_ai.response.model: "llm.responseModel"
- gen_ai.usage.completion_tokens: "llm.outputTokens"
- gen_ai.usage.prompt_tokens: "llm.inputTokens"
- EOF
- ```
-
-2. Create your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy. Make sure to reference the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource that you created so that your proxy starts with the custom tracing configuration.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: tracing
- group: {{< reuse "agw-docs/snippets/gatewayparam-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - protocol: HTTP
- port: 80
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-3. Verify that your {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy is up and running.
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```console
- NAMESPACE NAME READY STATUS RESTARTS AGE
- {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy-8b5dc4874-bl79q 1/1 Running 0 12s
- ```
-
-4. Get the external address of the gateway and save it in an environment variable.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-
-
-## Set up access to Gemini
-
-Configure access to an LLM provider such as Gemini and send a sample request. You later use this request to verify your tracing configuration.
-
-{{< reuse "agw-docs/snippets/gemini-setup.md" >}}
-
-## Verify tracing
-
-1. Get the logs of the agentgateway proxy. In the CLI output, find the `trace.id`.
- ```sh
- kubectl logs deploy/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```console{hl_lines=[5]}
- info request gateway={{< reuse "agw-docs/snippets/namespace.md" >}}/agentgateway-proxy listener=http
- route={{< reuse "agw-docs/snippets/namespace.md" >}}/google endpoint=generativelanguage.googleapis.com:443
- src.addr=127.0.0.1:49576 http.method=POST http.host=localhost
- http.path=/gemini http.version=HTTP/1.1 http.status=200
- trace.id=d65e4eeb983e2d964e71e8dc8c405f97 span.id=b836e1b1d51b3e74
- llm.provider=gemini llm.request.model= llm.request.tokens=8
- llm.response.model=gemini-1.5-flash-latest llm.response.tokens=313 duration=3165ms
- ```
-
-2. Get the logs of the collector and search for the trace ID. Verify that you see the additional LLM that you configured initially.
- ```sh
- kubectl logs deploy/opentelemetry-collector-traces -n telemetry
- ```
-
- Example output:
- ```console
- Span #0
- Trace ID : d65e4eeb983e2d964e71e8dc8c405f97
- Parent ID :
- ID : b836e1b1d51b3e74
- Name : POST /gemini
- Kind : Server
- Start time : 2025-09-24 18:12:58.653868462 +0000 UTC
- End time : 2025-09-24 18:13:01.821700755 +0000 UTC
- Status code : Unset
- Status message :
- Attributes:
- -> gateway: Str({{< reuse "agw-docs/snippets/namespace.md" >}}/agentgateway)
- -> listener: Str(http)
- -> route: Str({{< reuse "agw-docs/snippets/namespace.md" >}}/google)
- -> endpoint: Str(generativelanguage.googleapis.com:443)
- -> src.addr: Str(127.0.0.1:49576)
- -> http.method: Str(POST)
- -> http.host: Str(localhost)
- -> http.path: Str(/gemini)
- -> http.version: Str(HTTP/1.1)
- -> http.status: Int(200)
- -> trace.id: Str(d65e4eeb983e2d964e71e8dc8c405f97)
- -> span.id: Str(b836e1b1d51b3e74)
- -> llm.provider: Str(gemini)
- -> llm.request.model: Str()
- -> llm.request.tokens: Int(8)
- -> llm.response.model: Str(gemini-1.5-flash-latest)
- -> llm.response.tokens: Int(313)
- -> duration: Str(3165ms)
- -> url.scheme: Str(http)
- -> network.protocol.version: Str(1.1)
- -> gen_ai.operation.name: Str(chat)
- -> gen_ai.system: Str(gemini)
- ```
-
-
-
-## Other tracing configurations
-
-Review common tracing providers configurations that you can use with agentgateway.
-
-{{< reuse "agw-docs/snippets/agentgateway/tracing-config.md" >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} tracing -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-helm uninstall opentelemetry-collector-traces -n telemetry
-kubectl delete httproute google -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} google -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete secret google-secret -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-
-```
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/mcp/about.md b/assets/docs/pages/agentgateway/mcp/about.md
deleted file mode 100644
index cf12431bf..000000000
--- a/assets/docs/pages/agentgateway/mcp/about.md
+++ /dev/null
@@ -1,26 +0,0 @@
-Learn more about MCP and common challenges when adopting MCP in enterprise environments.
-
-## About MCP
-
-[Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) is an open protocol that standardizes how Large Language Model (LLM) applications connect to various external data sources and tools. Without MCP, you need to implement custom integrations for each tool that your LLM application needs to access. However, this approach is hard to maintain and can cause issues when you want to scale your environment. With MCP, you can significantly speed up, simplify, and standardize these types of integrations.
-
-An MCP server exposes external data sources and tools so that LLM applications can access them. Typically, you want to deploy these servers remotely and have authorization mechanisms in place so that LLM applications can safely access the data.
-
-With {{< reuse "agw-docs/snippets/agentgateway.md" >}}, you can connect to one or multiple MCP servers in any environment. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} proxies requests to the MCP tool that is exposed on the server.
-
-## MCP vs. A2A
-
-MCP and [Agent-to-Agent (A2A)](https://github.com/a2aproject/A2A) are the leading protocols for enabling communication between agents and tools. MCP helps to retrieve and exchange context with Large Language Models (LLMs) and connect LLMs to tools. On the other hand, A2A solves for long-running tasks and state management across multiple agents. MCP and A2A are both JSON-RPC protocols that define the structure of how an agent describes what it wants to do, how it calls tools, and how it hands off tasks to other agents.
-
-## Challenges with MCP and A2A
-While MCP and A2A define the RPC communication protocol for agents and tools, they currently do not address real-world, enterprise-level concerns.
-
-Agents typically do not operate in isolation. Instead, they interact with each other (agent-to-agent), with internal systems (agent-to-tool), and external or foundational models (agent-to-LLM). These interactions are often dynamic, multi-modal, and span organizational and data boundaries.
-
-Such long-lived interactivity creates new vectors for risk and complexity, including:
-* **Security**: How to handle authentication, authorization, and auditing of agent interactions across tools and services?
-* **Governance**: How to enforce policies across autonomous workflows, such as data residency or access control?
-* **Observability**: How to gain visibility into what agents are doing, when, and why?
-* **Scalability and performance**: How to ensure low latency while securely handling retries, timeouts, and failures?
-
-{{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} is designed to tackle these challenges at its core with built-in security, governance, and observability for all MCP and A2A communication between agents, tools, and LLMs.
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/mcp/dynamic.md b/assets/docs/pages/agentgateway/mcp/dynamic.md
deleted file mode 100644
index 5e0119e1d..000000000
--- a/assets/docs/pages/agentgateway/mcp/dynamic.md
+++ /dev/null
@@ -1,158 +0,0 @@
-Route to a Model Context Protocol (MCP) server dynamically by using a label selector. This way, unlike a static backend, you can update the backing MCP server without having to update the Backend resource. For more information, see the [About MCP]({{< link-hextra path="/mcp/about" >}}) topic.
-
-{{< callout type="warning" >}}
-Note that only streamable HTTP is currently supported for label selectors. If you need to use an SSE listener, use a [static MCP Backend](../static-mcp/).
-{{< /callout >}}
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Step 1: Deploy an MCP server {#mcp-server}
-
-Deploy an MCP server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. The following example sets up an MCP server that provides various utility tools.
-
-1. Create an MCP server (`mcp-server`) that provides various utility tools. Notice the following details about the Service:
- * `appProtocol: kgateway.dev/mcp` (required): Configure your service to use the MCP protocol. This way, the agentgateway proxy uses the MCP protocol when connecting to the service.
- * `kgateway.dev/mcp-path` annotation (optional): The default values are `/sse` for the SSE protocol or `/mcp` for the Streamable HTTP protocol. If you need to change the path of the MCP target endpoint, set this annotation on the Service.
-
- ```yaml
- kubectl apply -f- <}} for your MCP server that uses label selectors to select the MCP server.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: mcp-backend
- spec:
- mcp:
- targets:
- - name: mcp-server-everything
- selector:
- services:
- matchLabels:
- app: mcp-server-everything
- EOF
- ```
-
-
-## Step 2: Route with agentgateway {#agentgateway}
-
-Create an HTTPRoute resource that routes to the Backend that you created in the previous step.
-
-
-```yaml
-kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: mcp-backend
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
-EOF
-```
-
-
-## Step 3: Verify the connection {#verify}
-
-Use the [MCP Inspector tool](https://modelcontextprotocol.io/docs/tools/inspector) to verify that you can connect to your MCP server through {{< reuse "agw-docs/snippets/agentgateway.md" >}}.
-
-1. Get the agentgateway address.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. From the terminal, install the MCP Inspector tool. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`.
- ```sh
- npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}}
- ```
-
-3. From the MCP Inspector menu, connect to your agentgateway address as follows:
- * **Transport Type**: Select `Streamable HTTP`.
- * **URL**: Enter the agentgateway address, port, and the `/mcp` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp`.
- * Click **Connect**.
-
-4. From the menu bar, click the **Tools** tab, then click **List Tools**.
-
- {{< reuse-image src="img/mcp-tools-everything.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-tools-everything-dark.png" >}}
-
-5. Test the tools: Select a tool, such as `echo`. In the **message** field, enter a message, such as `Hello, world!`, and click **Run Tool**.
-
- {{< reuse-image src="img/mcp-tool-echo.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-tool-echo-dark.png" >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete Deployment mcp-server-everything
-kubectl delete Service mcp-server-everything
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp-backend
-kubectl delete HTTPRoute mcp
-```
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/mcp/https.md b/assets/docs/pages/agentgateway/mcp/https.md
deleted file mode 100644
index 443cae18a..000000000
--- a/assets/docs/pages/agentgateway/mcp/https.md
+++ /dev/null
@@ -1,124 +0,0 @@
-## About this guide
-
-In this guide, you configure your agentgateway proxy to connect to the remote [GitHub MCP server](https://github.com/github/github-mcp-server) by using the HTTPS protocol. The server allows you to interact with GitHub repositories, issues, pull requests, and more. All connections to the server must be secured via HTTPS and a GitHub access token must be provided for authentication.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Connect to the MCP server
-
-1. Create a personal access token in GitHub and save it in an environment variable. For more information, see the [GitHub docs](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).
- ```sh
- export GH_PAT=
- ```
-
-2. Create the {{< reuse "agw-docs/snippets/backend.md" >}} for the remote GitHub MCP server. The server requires you to connect to it by using the HTTPS protocol. Because of that, you set the `mcp.targets.static.port` field to 443.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- mcp:
- targets:
- - name: mcp-target
- static:
- host: api.githubcopilot.com
- port: 443
- path: /mcp/
- policies:
- tls:
- sni: api.githubcopilot.com
- EOF
- ```
-3. Create an HTTPRoute that routes traffic to the GitHub MCP server along the `/mcp-github` path. To properly connect to the MCP server, you must allow traffic from `http://localhost:8080`, which is the domain and port you expose your agentgateway proxy on later. If you expose the proxy under a different domain, make sure to add this domain to the allowed origins. Because the MCP server also requires a GitHub access token to connect, you set the `Authorization` header to the token that you created earlier.
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRefs:
- - name: agentgateway-proxy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /mcp-github
- filters:
- - type: CORS
- cors:
- allowHeaders:
- - "*"
- allowMethods:
- - "*"
- allowOrigins:
- - "http://localhost:8080"
- - type: RequestHeaderModifier
- requestHeaderModifier:
- set:
- - name: Authorization
- value: "Bearer ${GH_PAT}"
- backendRefs:
- - name: github-mcp-backend
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-
-
-
-## Verify the connection {#verify}
-
-Use the [MCP Inspector tool](https://modelcontextprotocol.io/legacy/tools/inspector) to verify that you can connect to your sample MCP server through agentgateway.
-
-1. Get the agentgateway address.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy 8080:80 -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. From your terminal, run the MCP Inspector command to open the MCP Inspector in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`.
- ```sh
- npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}}
- ```
-
-3. From the MCP Inspector menu, connect to your agentgateway address as follows:
- * **Transport Type**: Select `Streamable HTTP`.
- * **URL**: Enter the agentgateway address, port, and the `/mcp-github` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp-github`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp-github`.
- * Click **Connect**.
-
-4. From the menu bar, click the **Tools** tab. Then from the **Tools** pane, click **List Tools** and select the `get_me` tool.
-5. Click **Run Tool**.
-6. Verify that you get back information about your username.
-
- {{< reuse-image src="img/mcp-inspector-gh.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-inspector-gh-dark.png" >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-
-```
diff --git a/assets/docs/pages/agentgateway/mcp/mcp-access.md b/assets/docs/pages/agentgateway/mcp/mcp-access.md
deleted file mode 100644
index 78e7f4a9f..000000000
--- a/assets/docs/pages/agentgateway/mcp/mcp-access.md
+++ /dev/null
@@ -1,370 +0,0 @@
-Control access or route traffic based on verified claims in a JSON web token (JWT).
-
-## About MCP auth
-
-In this guide, you learn how to configure your agentgateway proxy to validate JWT tokens that are provided in an `Authorization` header. You then authorize access to specific MCP tools based on specific claims in the JWT.
-
-The following diagram shows the components that are involved when performing JWT validation and authorization with MCP servers:
-
-```mermaid
-sequenceDiagram
- autonumber
- Client->>+Agentgateway: Send request with JWT
- Agentgateway->>Agentgateway: Validate JWT token
- Agentgateway->>Agentgateway: Authorize access to MCP server
- Agentgateway->>+MCP: Forward request
-```
-
-1. The MCP client, such as the MCP inspector tool, sends a request to the agentgateway proxy with the JWT token in the `Authorization` header.
-2. The agentgateway proxy validates the JWT with the JWKS server that you define in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This policy is applied to the agentgateway proxy.
-3. If the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} further defines RBAC rules, such as to only grant access for JWT tokens with certain claims, the agentgateway proxy validates these claims and either grants or denies access.
-4. If successfully validated and authorized, the agentgateway proxy forwards the request to the MCP backend.
-
-## Before you begin
-
-1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-2. Follow the steps to connect to the [remote GitHub MCP server via HTTPS]({{< link-hextra path="/mcp/https/" >}}).
-
-## Validate JWT tokens
-
-You can configure your agentgateway proxy to validate JWT tokens that are sent by an MCP client in an `Authorization` header.
-
-1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your JWT validation rules and apply it to the agentgateway proxy that you created before you began. In this example, you use an inline, local JSON Web Key Set (JWKS) to verify the JWT.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: jwt
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: agentgateway-proxy
- traffic:
- jwtAuthentication:
- mode: Strict
- providers:
- - issuer: solo.io
- jwks:
- inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}'
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}} For more information, see the [API docs]({{< link-hextra path="/reference/api/#jwtprovider" >}}).
-
- | Field | Description |
- | ----- | ----- |
- | `issuer` | The principal that issued the JWT, usually a URL or an email address. If specified, the `iss` field in the JWT of the incoming request must match this field, or else the request is denied. If omitted, the `iss` field in the JWT is not checked. |
- | `jwks` | The JSON Web Key Set (JWKS) to use to verify the JWT. In this example, a local JWKS is provided inline. To use JWTs with {{< reuse "agw-docs/snippets/agentgateway.md" >}}, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header.|
-
-2. Save the JWT tokens for the users Alice and Bob. You can optionally create other JWT tokens by using the [JWT generator tool](https://github.com/kgateway-dev/kgateway/blob/main/hack/utils/jwt/jwt-generator.go). Note that to use JWTs with agentgateway proxies, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header.
-
- 1. Save the JWT token for Alice. Alice works in the `dev` team.
- ```sh
- export ALICE_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw"
- ```
-
- 2. Save the JWT token for Bob. Bob works in the `ops` team.
-
- ```sh
- export BOB_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og"
- ```
-
-3. Send an unauthenticated request to the MCP server.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- 1. Send a request to the MCP server.
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me
- ```
- 2. Verify that the request fails, because no JWT token was provided.
- ```console
- Failed to connect to MCP server: Streamable HTTP error:
- Error POSTing to endpoint: authentication failure: no bearer token found
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`.
- ```sh
- npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}}
- ```
-
- 2. From the MCP Inspector menu, try to connect to your agentgateway address as follows:
- * **Transport Type**: Select `Streamable HTTP`.
- * **URL**: Enter the agentgateway address, port, and the `/mcp-github` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http://:8080/mcp-github`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp-github`.
- * Click **Connect**.
-
-
- Verify that the connection fails with an error message similar to the following, because no valid JWT was provided from the MCP inspector tool (MCP client) to the agentgateway proxy.
-
- ```console
- Connection Error - Check if your MCP server is running and proxy token is correct
- ```
-
- {{< reuse-image src="img/mcp-github-error.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}}
- {{% /tab %}}
- {{< /tabs >}}
-
-4. Send another request to the MCP server. This time, you provide a valid JWT token for Alice in the `Authorization` header.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $ALICE_JWT"
- ```
-
- Verify that the connection succeeds and that you see the GitHub user output.
- ```console
- {
- "content": [
- {
- "type": "text",
- "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}"
- }
- ]
- }
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Alice.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw
- ```
- * Click **Connect**.
-
- 2. Verify that the connection now succeeds because a valid token was provided in an `Authorization` header to your agentgateway proxy:
- {{< reuse-image src="img/mcp-github-success.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-5. Repeat the same request with the JWT token for Bob. Verify that you can also connect to your MCP server successfully.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $BOB_JWT"
- ```
-
- Verify that the connection also succeeds and that you see the GitHub user output.
- ```console
- {
- "content": [
- {
- "type": "text",
- "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}"
- }
- ]
- }
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Bob.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og
- ```
- * Click **Connect**.
-
- 2. Verify that you can also connect to your MCP server successfully.
- {{< reuse-image src="img/mcp-github-success.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-6. Try to enter an invalid JWT token, such as `abcdefg`. Verify that access to the MCP server is denied, because the JWT token could not be validated by your agentgateway proxy.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer abcdefg"
- ```
-
- Verify that the connection fails, because no valid JWT token was provided.
- ```console
- Failed to connect to MCP server: Streamable HTTP error:
- Error POSTing to endpoint: authentication failure: the token header is malformed: Error(InvalidToken)
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Alice.
- ```sh
- abcdefg
- ```
- * Click **Connect**.
-
- 2. Verify that the connection fails, because no valid JWT token was provided.
- {{< reuse-image src="img/mcp-github-error.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-7. Optional: You can check the agentgateway proxy logs and verify that you see 403 authentication errors in your log entries.
- ```sh
- kubectl logs deploy/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```
- request gateway=default/agentgateway-proxy listener=http route=default/mcp src.addr=127.0.0.1:59068
- http.method=POST http.host=localhost http.path=/mcp http.version=HTTP/1.1 http.status=403
- error=authentication failure: no bearer token found duration=0ms
- ```
-
-## Authorize access based on JWT claims
-
-You can limit access to the MCP server based on specific JWT claims with CEL-based RBAC rules.
-
-1. Update the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to add your RBAC rules. In the following example, you use a CEL expression to only allow access to the MCP server if the JWT has the `sub=alice` claim.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: jwt
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: agentgateway-proxy
- traffic:
- jwtAuthentication:
- mode: Strict
- providers:
- - issuer: solo.io
- jwks:
- inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}'
- authorization:
- action: Allow
- policy:
- # Any of these conditions will allow access (OR logic)
- matchExpressions:
- - 'jwt.sub == "alice"'
- EOF
- ```
-
-2. Send a request to the MCP server with Alice's JWT token. Verify that the request succeeds, because the JWT contains the `sub=alice` claim.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $ALICE_JWT"
- ```
-
- Example output:
- ```console
- {
- "content": [
- {
- "type": "text",
- "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}"
- }
- ]
- }
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. In MCP Inspector tool, expand the **Authentication** section and enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Alice.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw
- ```
- * Click **Connect**.
-
- 2. Verify that the connection succeeds, because the JWT contains the `sub=alice` claim.
- {{< reuse-image src="img/mcp-github-success.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-3. Now send a request with Bob's JWT token. Verify that the connection fails, because Bob's JWT token does not have the `sub=alice` claim.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $BOB_JWT"
- ```
-
- Example output:
- ```console
- Failed to connect to MCP server: Streamable HTTP error:
- Error POSTing to endpoint: authorization failed
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Bob.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og
- ```
- * Click **Connect**.
-
- 2. Verify that the request fails, because the JWT does not have the `sub=alice` claim.
- {{< reuse-image src="img/mcp-github-error.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-error-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-
-## Next
-
-Explore how to [control access to tools]({{< link-hextra path="/mcp/tool-access/" >}}) with RBAC policies.
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-
-
diff --git a/assets/docs/pages/agentgateway/mcp/multiplex.md b/assets/docs/pages/agentgateway/mcp/multiplex.md
deleted file mode 100644
index f4c73568b..000000000
--- a/assets/docs/pages/agentgateway/mcp/multiplex.md
+++ /dev/null
@@ -1,260 +0,0 @@
-To federate multiple MCP servers on the same gateway, you can use a label selector in the MCP Backend.
-
-This approach makes it easier for you to add more MCP servers by adding labels. It also lets your clients access tools from multiple MCP servers through a single endpoint and MCP connection.
-
-{{< callout type="warning" >}}
-Note that only streamable HTTP is currently supported for label selectors. If you have SSE, use a [static MCP Backend](../static-mcp).
-{{< /callout >}}
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Step 1: Deploy the MCP servers {#mcp-server-everythings}
-
-Deploy multiple Model Context Protocol (MCP) servers that you want agentgateway to proxy traffic to. The following example sets up two MCP servers with different tools: one `npx` based MCP server that provides various utility tools and an MCP server with a website `fetch` tool.
-
-1. Create an MCP server (`mcp-server-everything`) that provides various utility tools. Notice that the Service uses the `appProtocol: kgateway.dev/mcp` setting. This way, {{< reuse "agw-docs/snippets/kgateway.md" >}} configures the agentgateway proxy to look for an equivalent {{< reuse "agw-docs/snippets/backend.md" >}} resource.
-
- ```yaml
- kubectl apply -f- <}} that selects both MCP servers that you created.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: mcp
- spec:
- mcp:
- targets:
- - name: mcp-server-everything
- selector:
- services:
- matchLabels:
- app: mcp-server-everything
- - name: mcp-website-fetcher
- static:
- host: mcp-website-fetcher.default.svc.cluster.local
- port: 80
- protocol: SSE
- EOF
- ```
-
-## Step 2: Route with agentgateway {#agentgateway}
-
-Route to the federated MCP servers with agentgateway.
-
-1. Create an HTTPRoute resource that routes to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: mcp
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- EOF
- ```
-
-2. Check that the HTTPRoute is `Accepted`, selects the Gateway, and includes backend rules for the {{< reuse "agw-docs/snippets/backend.md" >}} that you created.
-
- ```sh
- kubectl describe httproute mcp
- ```
-
- Example output:
-
- ```
- Name: mcp
- Namespace: default
- Labels:
- Annotations:
- API Version: gateway.networking.k8s.io/v1
- Kind: HTTPRoute
- Metadata:
- Creation Timestamp: 2025-08-11T16:16:16Z
- Generation: 1
- Resource Version: 13598
- UID: 78f649b9-310e-4f21-ac0f-e516f06d8f22
- Spec:
- Parent Refs:
- Group: gateway.networking.k8s.io
- Kind: Gateway
- Name: agentgateway-proxy
- Namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- Rules:
- Backend Refs:
- Group: agentgateway.dev
- Kind: AgentgatewayBackend
- Name: mcp
- Weight: 1
- Matches:
- Path:
- Type: PathPrefix
- Value: /
- Status:
- Parents:
- Conditions:
- Last Transition Time: 2025-12-19T03:13:18Z
- Message:
- Observed Generation: 2
- Reason: Accepted
- Status: True
- Type: Accepted
- Last Transition Time: 2025-12-19T14:24:01Z
- Message:
- Observed Generation: 2
- Reason: ResolvedRefs
- Status: True
- Type: ResolvedRefs
- Controller Name: agentgateway.dev/agentgateway
- Parent Ref:
- Group: gateway.networking.k8s.io
- Kind: Gateway
- Name: agentgateway-proxy
- Namespace: agentgateway-system
- ```
-
-
-## Step 3: Verify the connection {#verify}
-
-Use the [MCP Inspector tool](https://modelcontextprotocol.io/legacy/tools/inspector) to verify that you can connect to your federated MCP servers through agentgateway.
-
-1. Get the agentgateway address.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser.
-
- ```sh
- npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}}
- ```
-
-3. From the MCP Inspector menu, connect to your agentgateway address as follows:
- * **Transport Type**: Select `Streamable HTTP`.
- * **URL**: Enter the agentgateway address and the `/mcp` path, such as `${INGRESS_GW_ADDRESS}/mcp` or `http://localhost:8080/mcp`.
- * Click **Connect**.
-
-4. From the menu bar, click the **Tools** tab, and then **List tools**. Verify that you see the tools from both servers. The name of the tools are prepended with the names of the MCP servers that you set up in the {{< reuse "agw-docs/snippets/backend.md" >}}.
- * **`mcp-server-everything-3001_*`**: Tools from the `server-everything` MCP server, like `echo`, `add`, etc.
- * **`mcp-website-fetcher_fetch`**: The `fetch` tool from the website fetcher MCP server.
-
- {{< reuse-image src="img/mcp-multiplex.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-multiplex-dark.png" >}}
-
-5. Test the federated tools:
- * **Test the `mcp-server-everything-3001_echo` tool**: Click **List Tools** and select the `echo` tool. In the **message** field, enter any string, such as `Hello world`, and click **Run Tool**. Verify that your string is echoed back.
- * **Test the `mcp-website-fetcher_fetch` tool**: Click **List Tools** and select the `fetch` tool. In the **url** field, enter a website URL, such as `https://lipsum.com/`, and click **Run Tool**.
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete Deployment mcp-server-everything mcp-website-fetcher
-kubectl delete Service mcp-server-everything mcp-website-fetcher
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp
-kubectl delete HTTPRoute mcp
-```
diff --git a/assets/docs/pages/agentgateway/mcp/static.md b/assets/docs/pages/agentgateway/mcp/static.md
deleted file mode 100644
index 2b501a41b..000000000
--- a/assets/docs/pages/agentgateway/mcp/static.md
+++ /dev/null
@@ -1,148 +0,0 @@
-Route to a Model Context Protocol (MCP) server through a static address. For more information, see the [About MCP]({{< link-hextra path="/mcp/about" >}}) topic.
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Step 1: Deploy an MCP server {#mcp-server}
-
-Deploy a Model Context Protocol (MCP) server that you want {{< reuse "agw-docs/snippets/agentgateway.md" >}} to proxy traffic to. The following example sets up a simple MCP server with one tool, `fetch`, that retrieves the content of a website URL that you pass in.
-
-1. Create the MCP server workload. Notice the following details about the Service:
- * `appProtocol: kgateway.dev/mcp` (required): Configure your service to use the MCP protocol. This way, the {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy uses the MCP protocol when connecting to the service.
- * `kgateway.dev/mcp-path` annotation (optional): The default values are `/sse` for the SSE protocol or `/mcp` for the Streamable HTTP protocol. If you need to change the path of the MCP target endpoint, set this annotation on the Service.
-
- ```yaml
- kubectl apply -f- <}} that sets up the {{< reuse "agw-docs/snippets/agentgateway.md" >}} target details for the MCP server.
-
- ```yaml
- kubectl apply -f- <}}
- metadata:
- name: mcp-backend
- spec:
- mcp:
- targets:
- - name: mcp-target
- static:
- host: mcp-website-fetcher.default.svc.cluster.local
- port: 80
- protocol: SSE
- EOF
- ```
-
-
-## Step 2: Route with agentgateway {#agentgateway}
-
-Create an HTTPRoute resource that routes to the {{< reuse "agw-docs/snippets/backend.md" >}} that you created in the previous step.
-
-
-
-
-```yaml
-kubectl apply -f- <}}
- rules:
- -
- backendRefs:
- - name: mcp-backend
- group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
-EOF
-```
-
-
-## Step 3: Verify the connection {#verify}
-
-Use the [MCP Inspector tool](https://modelcontextprotocol.io/docs/tools/inspector) to verify that you can connect to your sample MCP server through agentgateway.
-
-1. Get the agentgateway address.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get gateway agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o=jsonpath="{.status.addresses[0].value}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing"%}}
- ```sh
- kubectl port-forward deployment/agentgateway-proxy -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:80
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. From the terminal, run the MCP Inspector command. Then, the MCP Inspector opens in your browser. If the MCP inspector tool does not open automatically, run `mcp-inspector`.
- ```sh
- npx modelcontextprotocol/inspector#{{% reuse "agw-docs/versions/mcp-inspector.md" %}}
- ```
-
-3. From the MCP Inspector menu, connect to your agentgateway address as follows:
- * **Transport Type**: Select `Streamable HTTP`.
- * **URL**: Enter the agentgateway address, port, and the `/mcp` path. If your agentgateway proxy is exposed with a LoadBalancer server, use `http:///mcp`. In local test setups where you port-forwarded the agentgateway proxy on your local machine, use `http://localhost:8080/mcp`.
- * Click **Connect**.
-
- {{< reuse-image src="img/mcp-inspector-connected.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-inspector-connected-dark.png" >}}
-
-4. From the menu bar, click the **Tools** tab. Then from the **Tools** pane, click **List Tools** and select the `fetch` tool.
-5. From the **fetch** pane, in the **url** field, enter a website URL, such as `https://lipsum.com/`, and click **Run Tool**.
-6. Verify that you get back the fetched URL content.
-
- {{< reuse-image src="img/mcp-inspector-fetch.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-inspector-fetch-dark.png" >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete Deployment mcp-website-fetcher
-kubectl delete Service mcp-website-fetcher
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} mcp-backend
-kubectl delete HTTPRoute mcp
-```
-
diff --git a/assets/docs/pages/agentgateway/mcp/tool-access.md b/assets/docs/pages/agentgateway/mcp/tool-access.md
deleted file mode 100644
index 2e5c3235b..000000000
--- a/assets/docs/pages/agentgateway/mcp/tool-access.md
+++ /dev/null
@@ -1,238 +0,0 @@
-Control access or route traffic based on verified claims in a JSON web token (JWT).
-
-## About tool access
-
-In this guide, you learn how to apply CEL-based RBAC rules to your MCP server backend to control access to MCP tools.
-
-The following diagram shows the components that are involved when performing JWT validation and MCP tool authorization with MCP servers:
-
-```mermaid
-sequenceDiagram
- autonumber
- Client->>+Agentgateway: Send request with JWT
- Agentgateway->>Agentgateway: Validate JWT token
- Agentgateway->>Agentgateway: Authorize access to MCP server
- Agentgateway->>+MCP: Forward request
- MCP->>+MCP: Authorize access to tools
- MCP-->>Client: Show tools
-```
-
-1. The MCP client, such as the MCP inspector tool, sends a request to the agentgateway proxy with the JWT token in the `Authorization` header.
-2. The agentgateway proxy validates the JWT with the JWKS server that you define in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource. This policy is applied to the agentgateway proxy.
-3. If the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} further defines RBAC rules, such as to only grant access for JWT tokens with certain claims, agentgateway validates these claims and either grants or denies access.
-4. If successfully validated and authorized, the agentgateway proxy forwards the request to the MCP backend.
-5. The MCP backend verifies access to the MCP server tools. By default, all tool access is allowed. To limit tool access, you create another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with the CEL expression that must be matched to view a specific tool. Consider the following sample CEL expressions:
- * `'mcp.tool.name == "add_issue_comment"'`: Users can only view the `add_issue_comment` tool. All other tools are hidden.
- * `'jwt.sub == "alice"'`: Only JWT tokens with a `sub=alice` claim can access tools. Because no CEL expression is provided for the type of tool, the JWT token with this claim can see all the tools that are exposed on the MCP server.
- * `'jwt.sub == "alice" && mcp.tool.name == "add_issue_comment"'`: JWT tokens with the `sub=alice` claim can access the `add_issue_comment` tool. Access to all other tools is denied.
-6. The MCP server returns the tools that were authorized to access.
-
-## Before you begin
-
-1. Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-2. Follow the steps to connect to the [remote GitHub MCP server via HTTPS]({{< link-hextra path="/mcp/https/" >}}).
-
-## View MCP tools
-
-1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your JWT validation rules and apply it to the agentgateway proxy that you created before you began. To learn more about how JWT validation works in the agentgateway proxy and the details of this policy, see the [secure access to an MCP server]({{< link-hextra path="/ai/mcp/mcp-access/" >}}) guide.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: jwt
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: agentgateway-proxy
- traffic:
- jwtAuthentication:
- mode: Strict
- providers:
- - issuer: solo.io
- jwks:
- inline: '{"keys":[{"use":"sig","kty":"RSA","kid":"5891645032159894383","n":"5Zb1l_vtAp7DhKPNbY5qLzHIxDEIm3lpFYhBTiZyGBcnre8Y8RtNAnHpVPKdWohqhbihbVdb6U7m1E0VhLq7CS7k2Ng1LcQtVN3ekaNyk09NHuhl9LCgqXT4pATt6fYTKtZ__tEw4XKt3QqVcw7hV0YaNVC5xXGYVBh5_2-K5aW9u2LQ7FSax0jPhWdoUB3KbOQfWNOA3RwOqYn4gmc9wVToVLv6bXCVhIYWKnAVcX89C00eM7uBHENvOydD14-ZnLb4pzz2VGbU6U65odpw_i4r_mWXvoUgwogXAXp80TsYwMzLHcFo4GVDNkaH0hjuLJCeISPfYtbUJK6fFaZGBw","e":"AQAB","x5c":["MIIC3jCCAcagAwIBAgIBJTANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwHhcNMjUxMjE4MTkzNDQyWhcNMjUxMjE4MjEzNDQyWjAXMRUwEwYDVQQKEwxrZ2F0ZXdheS5kZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDllvWX++0CnsOEo81tjmovMcjEMQibeWkViEFOJnIYFyet7xjxG00CcelU8p1aiGqFuKFtV1vpTubUTRWEursJLuTY2DUtxC1U3d6Ro3KTT00e6GX0sKCpdPikBO3p9hMq1n/+0TDhcq3dCpVzDuFXRho1ULnFcZhUGHn/b4rlpb27YtDsVJrHSM+FZ2hQHcps5B9Y04DdHA6pifiCZz3BVOhUu/ptcJWEhhYqcBVxfz0LTR4zu4EcQ287J0PXj5mctvinPPZUZtTpTrmh2nD+Liv+ZZe+hSDCiBcBenzROxjAzMsdwWjgZUM2RofSGO4skJ4hI99i1tQkrp8VpkYHAgMBAAGjNTAzMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQBeA8lKrnfRjo18RkLBqVKuO441nZLFGKrJwpJu+G5cVOJ06txKsZEXE3qu2Yh9abeOJkC+SsWMELWHYNJlip4JGE0Oby7chol+ahrwBILUixBG/qvhwJG6YntoDZi0wbNFqQiQ6FZt89awcs2pdxL5thYR/Pqx4QXN8oKd4DNkcX5vWdz9P6nstLUmrEBV4EFs7fY0L/n3ssDvyZ3xfpM1Q/CQFz4OqB4U20+Qt6x7eap6qhTSBZt8rZWIiy57BsSww12gLYYU1x+Klg1AdPsVrcuvVdiZM1ru232Ihip0rYH7Mf7vcN+HLUrjpXvMoeyWRwbB61GPsXz+BTksqoql"]}]}'
- EOF
- ```
-
-2. Save the JWT tokens for the users Alice and Bob. You can optionally create other JWT tokens by using the [JWT generator tool](https://github.com/solo-io/solo-cop/blob/main/tools/jwt-generator/README.md). Note that to use JWTs with agentgateway proxies, make sure that the JWTs return Key ID (`kid`) and expiration date (`exp`) values in the JWT header.
-
- 1. Save the JWT token for Alice. Alice works in the `dev` team.
- ```sh
- export ALICE_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw"
- ```
-
- 2. Save the JWT token for Bob. Bob works in the `ops` team.
-
- ```sh
- export BOB_JWT="eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og"
- ```
-
-3. Send a request to the MCP server. Provide the JWT token for Alice in your request.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $ALICE_JWT"
- ```
-
- Verify that the connection succeeds and that you can successfully access the `get_me` tool.
- ```console
- {
- "content": [
- {
- "type": "text",
- "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}"
- }
- ]
- }
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go back to the MCP Inspector tool and expand the **Authentication** section. Enter the following details in the **API Token Authentication** card:
- * **Header Name**: Enter `Authorization`.
- * **Bearer Token**: Enter the JWT token for Alice.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYWxpY2UiLCJleHAiOjIwNzM2NzA0ODIsIm5iZiI6MTc2NjA4NjQ4MiwiaWF0IjoxNzY2MDg2NDgyfQ.C-KYZsfWwlwRw4cKHXWmjN5bwWD80P0CVYP6-mT5sX6BH3AR1xNrOApPF9X0plwVD4_AsWzVo435j1AmgBzPwIjhHPKtxXycaKEwSEHYFesyi-XCEJtaQZZVcjOJOs-12L2ZJeM_csk9EqKKSx0oj3jj6BciqBnLn6_hK9sEtoGenEVWEdOpkjRQBxk1m-rVZNY2IvxXMuj9C7jGXv_Sn3cU5w6arXWUsdoQtYTl5tmuF15nkD3DnQfLjDyz59FTKXUR_QkhXV81amejrDSTroJ42_RLC9ABXqdMORCe-Hus-f1utLURfAYGvmnEVeYJO8BFhedTR6lFLnVS0u2Fpw
- ```
- * Click **Connect**.
-
- 2. Verify that the connection now succeeds because a valid token was provided in an `Authorization` header to your agentgateway proxy:
- {{< reuse-image src="img/mcp-github-success.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-success-dark.png" >}}
-
- {{% /tab %}}
- {{< /tabs >}}
-
-
-## Limit tool access
-
-1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your RBAC rules for the MCP tools. In the following example, you only want to allow access to the `get_me` tool if the JWT has a `sub` of `alice`.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: jwt-rbac
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: agentgateway.dev
- kind: {{< reuse "agw-docs/snippets/backend.md" >}}
- name: github-mcp-backend
- backend:
- mcp:
- authorization:
- action: Allow
- policy:
- # Any of these conditions will allow access (OR logic)
- matchExpressions:
- - 'jwt.sub == "alice" && mcp.tool.name == "get_me"'
- EOF
- ```
-
-2. Try to access tools on the MCP server.
- {{< tabs tabTotal="2" items="CLI,UI" >}}
- {{% tab tabName="CLI" %}}
- 1. Try to access the `get_me` tool with Alice's JWT token. Verify that the request succeeds and you can access the tool.
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name get_me \
- --header "Authorization: Bearer $ALICE_JWT"
- ```
-
- Example output:
- ```console
- {
- "content": [
- {
- "type": "text",
- "text": "{\"login\":\"MyUser\",\"id\":11234567,\"profile_url\":\"https://github.com/MyUser\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/11234567?v=4\",\"details\":{\"name\":\"My User\",\"company\":\"Solo.io\",\"public_repos\":11,\"public_gists\":1,\"followers\":1,\"following\":0,\"created_at\":\"2016-03-07T18:33:49Z\",\"updated_at\":\"2025-12-08T19:38:04Z\"}}"
- }
- ]
- }
- ```
- 2. Try to access a different tool, such as `search_repositories`. Verify that the request fails, because this tool is not allowed in your {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name search_repositories \
- --header "Authorization: Bearer $ALICE_JWT" \
- --tool-arg query="user:facebook"
- ```
-
- Example output:
- ```console
- Failed to call tool search_repositories: Streamable HTTP error:
- Error POSTing to endpoint: {"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":"failed to send message: unauthorized tool call"}}
- ```
-
- 3. Try to access the `get_me` took with Bob's JWT token. Verify that the request fails, because the token does not have the `sub=alice` claim.
- ```sh
- npx @modelcontextprotocol/inspector@0.18.0 \
- --cli http://localhost:8080/mcp-github \
- --transport http \
- --header "mcp-protocol-version: 2024-11-05" \
- --method tools/call \
- --tool-name search_repositories \
- --header "Authorization: Bearer $BOB_JWT" \
- --tool-arg query="user:facebook"
- ```
-
- Example output:
- ```console
- Failed to call tool search_repositories: Streamable HTTP error:
- Error POSTing to endpoint: {"jsonrpc":"2.0","id":2,"error":{"code":-32603,"message":
- "failed to send message: unauthorized tool call"}}
- ```
- {{% /tab %}}
- {{% tab tabName="UI" %}}
- 1. Go to the MCP inspector tool, and re-connect with Alice's token. From the **Tools** tab, click **Clear**. Then click **List Tools**. Verify that you can now only see the `get_me` tool that you authorized in your {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
-
- {{< reuse-image src="img/mcp-github-tool.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-tool-dark.png" >}}
-
- 2. Go back to the MCP inspector tool. In the **Authentication** > **Custom Headers** card enter the JWT token for Bob. Then, click **Re-connect**.
- ```sh
- Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjU4OTE2NDUwMzIxNTk4OTQzODMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJzb2xvLmlvIiwic3ViIjoiYm9iIiwiZXhwIjoyMDczNjcwNDgyLCJuYmYiOjE3NjYwODY0ODIsImlhdCI6MTc2NjA4NjQ4Mn0.ZHAw7nbANhnYvBBknN9_ORCQZ934Vv_vAelx8odC3bsC5Yesif7ZSsnEp9zFjGG6wBvvV3LrtuBuWx9mTYUZS6rwWUKsvDXyheZXYRmXndOqpY0gcJJaulGGqXncQDkmqDA7ZeJLG1s0a6shMXRs6BbV370mYpu8-1dZdtikyVL3pC27QNei35JhfqdYuMw1fMptTVzypx437l9j2htxqtIVgdWUc1iKD9kNKpkJ5O6SNbi6xm267jZ3V_Ns75p_UjLq7krQIUl1W0mB0ywzosFkrRcyXsBsljXec468hgHEARW2lec8FEe-i6uqRuVkFD-AeXMfPhXzqdwysjG_og
- ```
-
- 3. From the **Tools** tab, click **Clear**. Then click **List Tools**.
-
- Verify that you cannot see any tools. Bob's JWT token does not contain the `sub=alice` claim that is required to access the `get_me` tool. Because no other matching condition is found in the RBAC rules that you defined in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, access to all tools is denied.
-
-
- {{< reuse-image src="img/mcp-github-no-tool.png" >}}
- {{< reuse-image-dark srcDark="img/mcp-github-no-tool-dark.png" >}}
-
-
-
- {{% /tab %}}
- {{< /tabs >}}
-
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} github-mcp-backend -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete HTTPRoute mcp-github -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} jwt-rbac -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md b/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md
deleted file mode 100644
index e5f1c2ba8..000000000
--- a/assets/docs/pages/agentgateway/monitoring-agentgateway-nacks.md
+++ /dev/null
@@ -1,93 +0,0 @@
-## About NACKs {#nacks}
-
-A NACK (negative acknowledgement) occurs when an {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy rejects a configuration update from the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane. NACKs typically indicate configuration issues that prevent the proxy from applying the desired routing, policy, or backend settings.
-
-Typically, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane reports errors during translation, in which the control plane immediately rejects invalid configuration in custom resources and records errors in custom resource statuses. However, some errors can only be caught at configuration time, in which the control plane cannot determine the configuration failure until a proxy in the data plane rejects the configuration.
-
-To track these NACKs at configuration time, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane exposes a combination of metrics and events that monitor the health of config synchronization between the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies.
-
-For more general information about {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane metrics, see [Control plane metrics](../../observability/control-plane-metrics/).
-
-Common causes of NACKs include:
-
-* CEL expressions in policies that the control plane validator allows, but the data plane rejects. The control plane uses a Go-based CEL validator, while agentgateway uses a Rust-based validator, which can have different validation behavior.
-* Invalid TLS certificates.
-
-When a NACK occurs, {{< reuse "/agw-docs/snippets/kgateway.md" >}} provides two observability signals:
-
-* **Prometheus metric**: A counter metric tracks the total number of NACKs across all {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies that {{< reuse "/agw-docs/snippets/kgateway.md" >}} manages.
-* **Kubernetes events**: {{< reuse "/agw-docs/snippets/kgateway.md" >}} creates Warning events on both the `Gateway` and its corresponding `Deployment` with details about the error.
-
-## Monitor NACKs with control plane metrics {#nack-metrics}
-
-You can access the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane metrics endpoint to view NACK metrics that track configuration rejections from {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxies.
-
-### View the NACK metric {#view-nack-metric}
-
-1. Port-forward the control plane deployment on port 9092.
- ```sh
- kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} port-forward deployment/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092
- ```
-
-2. Open the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane [metrics endpoint](http://localhost:9092/metrics).
-
-3. Search for the `kgateway_agentgateway_xds_rejects_total` metric.
-
- {{< callout type="info" >}}
- The metric will only appear after at least one NACK has been reported. If no NACKs have occurred, the metric will not be present in the metrics output.
- {{< /callout >}}
-
- Example output:
-
- ```console
- # HELP kgateway_agentgateway_xds_rejects_total Total number of xDS responses rejected by agentgateway proxy
- # TYPE kgateway_agentgateway_xds_rejects_total counter
- kgateway_agentgateway_xds_rejects_total 3
- ```
-
-You can use this metric to configure alerts to notify you when NACKs occur so you can quickly investigate and resolve configuration issues.
-
-For guidance on setting up the observability stack, which allows for configurable alerting, see the [OpenTelemetry stack guide](../../observability/otel-stack/).
-
-## Monitor NACKs with Kubernetes events {#nack-events}
-
-When a NACK occurs for an {{< reuse "agw-docs/snippets/agentgateway.md" >}} proxy, {{< reuse "/agw-docs/snippets/kgateway.md" >}} also creates Kubernetes Warning events on both the `Gateway` and its corresponding `Deployment`.
-
-### View NACK events {#view-nack-events}
-
-Use the following commands to view NACK events for your agentgateway deployment.
-
-1. List NACK events in the namespace where your Gateway is deployed. If you have multiple Gateways across different namespaces, you can search across all namespaces with `--all-namespaces` instead of `-n `.
-
- ```sh
- kubectl get events -n --field-selector=reason=AgentGatewayNackError
- ```
-
- Example output:
-
- ```console
- LAST SEEN TYPE REASON OBJECT MESSAGE
- 83s Warning AgentGatewayNackError gateway/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown'
- 83s Warning AgentGatewayNackError deployment/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown'
- ```
-
-2. View events for a specific Gateway.
-
- ```sh
- kubectl describe gateway -n
- ```
-
- Look for events in the output similar to the following.
-
- ```console
- Events:
- Type Reason Age From Message
- ---- ------ ---- ---- -------
- Warning AgentGatewayNackError 36s kgateway.dev/agentgateway policy/traffic/default/example-agw-policy-for-body:transformation:default/example-route-for-body: error: parse: ERROR: :1:20: invalid argument has(request.headers['x-priority-level']) ? 'level_' + request.headers['x-priority-level'] : 'level_unknown'
- ```
-
-3. View events for the associated Deployment in the same name and namespace as the Gateway.
-
- ```sh
- kubectl describe deployment -n
- ```
\ No newline at end of file
diff --git a/assets/docs/pages/agentgateway/quickstart.md b/assets/docs/pages/agentgateway/quickstart.md
deleted file mode 100644
index 3683936aa..000000000
--- a/assets/docs/pages/agentgateway/quickstart.md
+++ /dev/null
@@ -1,33 +0,0 @@
-Use the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane to deploy and manage the lifecycle of agentgateway proxies on Kubernetes.
-
-{{< reuse "agw-docs/snippets/agentgateway/about.md" >}}
-
-## Before you begin
-
-These quickstart steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/).
-
-```sh
-kind create cluster
-```
-
-## Install
-
-The following steps get you started with a basic installation.
-
-{{< reuse "agw-docs/snippets/agentgateway/get-started.md" >}}
-
-Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster.
-
-## Next steps
-
-{{< icon "agentgateway" >}} [Create an agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}) that you can use for Model Context Protocol (MCP), agent-to-agent (A2A), large language model (LLM), and more AI-related use cases. For example, you can follow the [guide]({{< link-hextra path="/mcp/static-mcp/" >}}) to use agentgateway to proxy traffic to a sample MCP tool server. The example deploys a sample MCP server with a `fetch` tool, exposes the tool with agentgateway, and tests the tool with the MCP Inspector UI.
-
-For other examples, see the [LLM consumption]({{< link-hextra path="/llm/" >}}), [inference routing]({{< link-hextra path="/inference/" >}}), [MCP]({{< link-hextra path="/mcp/" >}}), or [agent connectivity]({{< link-hextra path="/agent/" >}}) guides.
-
-## Cleanup
-
-No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command:
-
-```sh
-helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
diff --git a/assets/docs/pages/agentgateway/rbac.md b/assets/docs/pages/agentgateway/rbac.md
deleted file mode 100644
index 5311173cb..000000000
--- a/assets/docs/pages/agentgateway/rbac.md
+++ /dev/null
@@ -1,128 +0,0 @@
-Use Common Language Expressions (CEL) expressions to secure access to AI resources.
-
-## About CEL-based RBAC
-
-Agentgateway proxies use CEL expressions to match requests or responses on specific parameters, such as a request header or source address. If the request matches the condition, it is allowed. Requests that do not match any of the conditions are denied.
-
-For an overview of supported CEL expressions, see the [agentgateway docs](https://agentgateway.dev/docs/reference/cel/).
-
-## Before you begin
-
-Set up an [agentgateway proxy]({{< link-hextra path="/setup" >}}).
-
-## Set up access to Gemini
-
-Configure access to an LLM provider such as Gemini. You can use any other LLM provider, an MCP server, or an agent to try out CEL-based RBAC.
-
-{{< reuse "agw-docs/snippets/gemini-setup.md" >}}
-
-## Set up RBAC permissions
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your CEL rules. The following example allows requests with the `x-llm: gemini` header.
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: rbac-policy
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: google
- traffic:
- authorization:
- action: Allow
- policy:
- matchExpressions:
- - "request.headers['x-llm'] == 'gemini'"
- EOF
- ```
-
-
-
-2. Send a request to the LLM provider API without the `llm` header. Verify that the request is denied with a 403 HTTP response code.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
-
- ````sh
- curl -vik "$INGRESS_GW_ADDRESS:8080/gemini" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {"role": "user", "content": "Explain how AI works in simple terms."}
- ]
- }'
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vik "localhost:8080/gemini" -H content-type:application/json -d '{
- "model": "",
- "messages": [
- {"role": "user", "content": "Explain how AI works in simple terms."}
- ]
- }'
- ````
-
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console{hl_lines=[11]}
- * upload completely sent off: 109 bytes
- < HTTP/1.1 403 Forbidden
- HTTP/1.1 403 Forbidden
- < content-type: text/plain
- content-type: text/plain
- < content-length: 20
- content-length: 20
- <
-
- * Connection #0 to host localhost left intact
- authorization failed
- ```
-
-3. Send another request to the LLM provider. This time, you include the `llm` header. Verify that the request succeeds with a 200 HTTP response code.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
-
- ```sh
- curl -vik "$INGRESS_GW_ADDRESS:8080/gemini" \
- -H "content-type: application/json" \
- -H "x-llm: gemini" -d '{
- "model": "",
- "messages": [
- {"role": "user", "content": "Explain how AI works in simple terms."}
- ]
- }'
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vik "localhost:8080/gemini" \
- -H "content-type: application/json" \
- -H "x-llm: gemini" -d '{
- "model": "",
- "messages": [
- {"role": "user", "content": "Explain how AI works in simple terms."}
- ]
- }'
- ````
-
- {{% /tab %}}
- {{< /tabs >}}
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```shell
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} rbac-policy -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete httproute google -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/backend.md" >}} google -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete secret google-secret -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
\ No newline at end of file
diff --git a/assets/docs/pages/cli/_index.md b/assets/docs/pages/cli/_index.md
deleted file mode 100644
index 3e02e0151..000000000
--- a/assets/docs/pages/cli/_index.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: CLI
-weight: 10
-description:
----
-
-{{< cards >}}
-{{< card link="install" title="Install the kgwctl CLI">}}
-{{< card link="visualize" title="Visualize resource dependencies">}}
-{{< card link="commands" title="kgwctl commands" >}}
-{{< /cards >}}
diff --git a/assets/docs/pages/cli/commands/_index.md b/assets/docs/pages/cli/commands/_index.md
deleted file mode 100644
index af6d556fa..000000000
--- a/assets/docs/pages/cli/commands/_index.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: Commands
-weight: 30
-description:
----
-
-
-{{< cards >}}
-{{< card link="kgwctl-analyze" title="kgwctl analyze" >}}
-{{< card link="kgwctl-check" title="kgwctl check" >}}
-{{< card link="kgwctl-completion" title="kgwctl completion" >}}
-{{< card link="kgwctl-describe" title="kgwctl describe" >}}
-{{< card link="kgwctl-get" title="kgwctl get" >}}
-{{< card link="kgwctl-help" title="kgwctl help" >}}
-{{< /cards >}}
diff --git a/assets/docs/pages/cli/commands/kgwctl-analyze.md b/assets/docs/pages/cli/commands/kgwctl-analyze.md
deleted file mode 100644
index 920b9dc35..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-analyze.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: kgwctl analyze
-weight: 20
-description: kgwctl analyze command reference
----
-
-Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources.
-
-## Usage
-
-```sh
-kgwctl analyze -f FILENAME|DIRECTORY [flags]
-```
-
-## Command-specific flags
-
-```yaml
--f, --filename strings The file name or directory that contains the kgateway manifests that you want to analyze.
--h, --help Help for the command.
--R, --recursive Process the directory that you reference in -f or --filename recursively. This option is useful for when you want to analyze related manifests that are stored in the same directory. (default true)
-```
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
diff --git a/assets/docs/pages/cli/commands/kgwctl-check.md b/assets/docs/pages/cli/commands/kgwctl-check.md
deleted file mode 100644
index 34d5864ca..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-check.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: kgwctl check
-weight: 20
-description: kgwctl check command reference
----
-
-Check the health of the kgateway control and data plane.
-
-## Usage
-
-```sh
-kgwctl check [flags]
-```
-
-## Command-specific flags
-
-```yaml
--h, --help Help for the command.
-```
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
-
-
-
diff --git a/assets/docs/pages/cli/commands/kgwctl-completion.md b/assets/docs/pages/cli/commands/kgwctl-completion.md
deleted file mode 100644
index 7115f26e0..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-completion.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: kgwctl completion
-weight: 20
-description: kgwctl completion command reference
----
-
-Generate the autocompletion script for the `kgwctl` CLI for the specified shell. For details on how to use the generated script, see the subcommand's help, such as `kgwctl completion bash --help`.
-
-## Usage
-
-```sh
-kgwctl completion [command]
-```
-
-## Available commands
-
-```sh
-bash Generate the autocompletion script for bash.
-fish Generate the autocompletion script for fish.
-powershell Generate the autocompletion script for powershell.
-zsh Generate the autocompletion script for zsh.
-```
-
-## Command-specific flags
-
-```sh
--h, --help Help for the command.
-```
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
-
diff --git a/assets/docs/pages/cli/commands/kgwctl-describe.md b/assets/docs/pages/cli/commands/kgwctl-describe.md
deleted file mode 100644
index 5bbf8e01a..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-describe.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: kgwctl describe
-weight: 20
-description: kgwctl describe command reference
----
-
-Get the details of one or more kgateway resources.
-
-## Usage
-
-```sh
-kgwctl describe TYPE [RESOURCE_NAME] [flags]
-```
-
-## Command-specific flags
-
-```yaml
--A, --all-namespaces If present, list the requested object(s) across all namespaces. Note that any namespace context that you specified with -n or --namespace is ignored.
--h, --help Help for the command.
--l, --selector string The selector label to filter on. Supported operations include '=', '==', and '!='. For example, to describe all resources with the `key1=value1` and `key2=value2` labels, use `-l key1=value1,key2=value2`.
-```
-
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
\ No newline at end of file
diff --git a/assets/docs/pages/cli/commands/kgwctl-get.md b/assets/docs/pages/cli/commands/kgwctl-get.md
deleted file mode 100644
index 91afb4b70..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-get.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: kgwctl get
-weight: 20
-description: kgwctl get command reference
----
-
-List one or more kgateway resources.
-
-## Usage
-
-```sh
-kgwctl get TYPE [RESOURCE_NAME] [flags]
-```
-
-## Command-specific flags
-
-```sh
--A, --all-namespaces If present, list the requested object(s) across all namespaces. Note that any namespace context that you specified with -n or --namespace is ignored.
---for string Only show the resources that match the filter. To filter the results, use the `TYPE[/NAMESPACE]/NAME` format. If no `NAMESPACE` is set, the `default` namespace is automatically assumed. Examples: `gateway/ns2/foo-gateway`, `httproute/bar-httproute`, and `service/ns1/my-svc`.
--h, --help Help for the command.
--l, --selector string The selector label to filter on. Supported operations include '=', '==', and '!='. For example, to get all resources with the `key1=value1` and `key2=value2` labels, use `-l key1=value1,key2=value2`.
--o, --output string Define the output format. Supported values are wide, json, yaml, and graph.
-```
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
-
diff --git a/assets/docs/pages/cli/commands/kgwctl-help.md b/assets/docs/pages/cli/commands/kgwctl-help.md
deleted file mode 100644
index 762edd8a0..000000000
--- a/assets/docs/pages/cli/commands/kgwctl-help.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: kgwctl help
-weight: 20
-description: kgwctl help command reference
----
-
-List all supported commands for the `kgwctl` CLI.
-
-## Usage
-
-```sh
-kgwctl [command]
-```
-
-## Available Commands
-
-```
-analyze Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources.
-check Check the health of the kgateway control and data plane.
-completion Generate the autocompletion script for the `kgwctl` CLI for the specified shell.
-describe Get the details of one or more kgateway resources.
-get List one or more kgateway resources.
-help List all supported commands for the `kgwctl` CLI.
-```
-
-{{< reuse "agw-docs/snippets/kgwctl-global-flags.md" >}}
\ No newline at end of file
diff --git a/assets/docs/pages/cli/install.md b/assets/docs/pages/cli/install.md
deleted file mode 100644
index 6a8528e70..000000000
--- a/assets/docs/pages/cli/install.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: Install the kgwctl CLI
-weight: 10
-description:
----
-
-
-
-Use the `kgwctl` CLI to quickly assess the health of your kgateway control and data plane components.
-
-1. Save the version of the kgwctl CLI that you want to install as an environment variable.
- ```sh
- export VERSION=v{{< reuse "agw-docs/versions/kgwctl.md" >}}
- ```
-
-2. Create a personal access token in GitHub. For more information, see the [GitHub documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens).
-
-3. Install the `kgwctl` CLI.
- ```sh
- curl -sL -H "Authorization: token ${GITHUB_TOKEN}" https://raw.githubusercontent.com/solo-io/kgwctl-temp/refs/heads/main/scripts/install.sh | sh -
- ```
-
- Example output:
- ```sh
- Downloading kgwctl-darwin-arm64 from release v{{< reuse "agw-docs/versions/kgwctl.md" >}}...
- Verifying checksum...
- Checksum verified successfully
- Download successful: kgwctl-darwin-arm64
- kgwctl CLI was successfully installed 🎉
-
- Add the kgwctl CLI to your path with:
- export PATH=$HOME/.kgwctl/bin:$PATH
- ```
-
-4. Add the CLI to your path.
- ```sh
- export PATH=$HOME/.kgwctl/bin:$PATH
- ```
-
-5. Try out the CLI. For example, you can list all supported commands with the following command.
- ```sh
- kgwctl --help
- ```
-
- Example output:
- ```console
- Commands for interacting with kgateway installations.
-
- Usage:
- kgwctl [command]
-
- Available Commands:
- analyze Analyze kgateway resource manifests by file names or directory to find configuration issues and impacts on other resources.
- check Check the health of the kgateway control and data plane.
- completion Generate the autocompletion script for the `kgwctl` CLI for the specified shell.
- describe Get the details of one or more kgateway resources.
- get List one or more kgateway resources.
- help List all supported commands for the `kgwctl` CLI.
- ...
- ```
-
\ No newline at end of file
diff --git a/assets/docs/pages/cli/visualize.md b/assets/docs/pages/cli/visualize.md
deleted file mode 100644
index 3602f10e6..000000000
--- a/assets/docs/pages/cli/visualize.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: Visualize resource dependencies
-weight: 15
-description: Visualize the relationship and dependencies for all your kgateway and Kubernetes Gateway API resources in a DOT Graph.
----
-
-Visualize the relationship and dependencies for all your kgateway and Kubernetes Gateway API resources in a DOT Graph.
-
-## About DOT Graphs
-
-A DOT graph is a plain text graph description language that is primarily used with [Graphviz](https://graphviz.org/). Graphviz is an open source graph visualization software to represent structural information and networks as diagrams, such as flowcharts, dependency trees, and state machines.
-
-The kgwctl CLI has built-in support for generating DOT graphs to show the dependencies and relationships of kgateway and Kubernetes Gateway API resources.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Visualize your resources
-
-1. Generate a graph for a particular resource in your cluster. The following command generates a graph for the http Gateway that you created in [before you begin](#before-you-begin)
-
- ```sh
- kgwctl get gateway http -n kgateway-system -o graph > output.graph
- ```
-
-2. Open the [Graphviz online playground]( https://dreampuf.github.io/GraphvizOnline).
-
-3. Copy and paste the output of `output.graph` into the Graphviz online playground. The tool automatically generates the DOT graph for you.
-
- {{< reuse-image src="img/graphviz.svg" >}}
\ No newline at end of file
diff --git a/assets/docs/pages/envoy/quickstart.md b/assets/docs/pages/envoy/quickstart.md
deleted file mode 100644
index 6862c3f66..000000000
--- a/assets/docs/pages/envoy/quickstart.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}. {{< reuse "agw-docs/snippets/kgateway-about.md" >}}
-
-## Before you begin
-
-These quick start steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/).
-
-```sh
-kind create cluster
-```
-
-## Install
-
-The following steps get you started with a basic installation. For detailed instructions, see the [installation guides]({{< link-hextra path="/install" >}}).
-
-{{< reuse "agw-docs/snippets/envoy/get-started.md" >}}
-
-Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster.
-
-## Next steps
-
-{{< icon "kgateway" >}} [Set up an API gateway with an httpbin sample app]({{< link-hextra path="/install/sample-app/" >}}). This guide uses the Envoy-based {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy to set up an API gateway. Then, deploy a sample httpbin app, configure a basic HTTP listener on the API gateway, and route traffic to httpbin by using an HTTPRoute resource.
-
-## Cleanup
-
-No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command:
-
-```sh
-helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
diff --git a/assets/docs/pages/faqs.md b/assets/docs/pages/faqs.md
deleted file mode 100644
index e6ed0bbed..000000000
--- a/assets/docs/pages/faqs.md
+++ /dev/null
@@ -1,68 +0,0 @@
-## What is kgateway?
-
-{{< reuse "agw-docs/snippets/kgateway-about.md" >}}
-
-## Why would I want to use kgateway?
-
-The kgateway project was built to support the difficult challenges of monolith to microservice migration, which includes being able to connect multiple types of compute resources, such as virtual machines (VMs) and on-premises monolithic apps with cloud-native, Kubernetes-based apps.
-
-Other use cases kgateway can solve include the following:
-
-* Kubernetes cluster ingress with a custom kgateway API as well as native support for the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}.
-* API gateway functionality for services that run outside Kubernetes
-* Routing, resiliency, and security capabilities for enhanced traffic management
-
-## What's the difference between kgateway and Envoy?
-
-The Envoy proxy is a data-plane component with powerful routing, observability, and resilience capabilities. However, Envoy can be difficult to operationalize and complex to configure.
-
-The kgateway project comes with a simple yet powerful control plane for managing Envoy as an edge ingress, API Gateway, or service proxy. The kgateway control plane is built on a plugin model that enables extension and customization depending on your environment. This flexibility lets kgateway adapt both to the fast pace of development in the open source Envoy community, as well as to the unique needs of differing operational environments.
-
-The kgateway includes the following capabilities beyond open source Envoy:
-
-* A flexible control plane with extensibility in mind
-* More ergonomic, domain-specific APIs to drive Envoy configuration
-* Function-level routing that goes beyond routing to a `host:port` for clusters, including routing to a Swagger/OpenAPI spec endpoint, gRPC function, cloud provider function such as AWS Lambda, and more
-* Transformation of request/response via a super-fast C++ templating filter built on Inja
-* Envoy filters to call AWS Lambda directly, handling the complex security handshaking
-
-## What is the difference between kgateway and Istio?
-
-[Istio](https://istio.io/latest/docs/overview/what-is-istio/) is a service mesh that helps you manage, secure, and observe traffic for service-to-service communication. Although it includes some ingress gateway capabilities to get traffic into the cluster, Istio focuses more on east-west mesh use cases, especially in large, distributed environments. Istio operates the mesh by using either a per-pod sidecar or per-node ztunnel architecture.
-
-The kgateway project is not a service mesh. Instead kgateway provides a lightweight control plane to manage Envoy-based API gateways, particularly for north-south edge ingress use cases in any Kubernetes-based environment.
-
-Kgateway can be deployed complementary to a service mesh like Istio. Istio solves the challenges of service-to-service communication by controlling requests as they flow through the system. Kgateway can be deployed at the edge of the service-mesh boundary, between service meshes, or within the mesh to add the following capabilities:
-
-* Mutual TLS (mTLS) encryption of traffic between the gateway and services
-* Transformation of request/response to decouple backend APIs from frontend
-* Function routing such as AWS Lambda
-* AI Gateway, MCP server, and other unique kgateway features
-
-For examples, see the [Istio integration guides]({{< link-hextra path="/integrations/istio/" >}}).
-
-## What license is kgateway under?
-
-The kgateway project uses [Apache License 2.0](http://www.apache.org/licenses/).
-
-## What is the project roadmap?
-
-The kgateway project organizes issues into milestones for release. For more details, see the [GitHub project](https://github.com/kgateway-dev/kgateway/milestones).
-
-## What is the version support policy?
-
-The kgateway project supports one latest version.
-
-The `main` branch of the `kgateway-dev/kgateway` Git repository is for feature work under development, and is not stable.
-
-## Where is the changelog?
-
-The changelog is part of each [GitHub release](https://github.com/kgateway-dev/kgateway/releases).
-
-
-
diff --git a/assets/docs/pages/install/advanced.md b/assets/docs/pages/install/advanced.md
deleted file mode 100644
index d7aeee654..000000000
--- a/assets/docs/pages/install/advanced.md
+++ /dev/null
@@ -1,96 +0,0 @@
-You can update several installation settings in your Helm values file. For example, you can update the namespace, set resource limits and requests, or enable extensions such as for AI.
-
-* **Show all values**:
-
- ```sh
- helm show values oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- ```
-
-* **Get a file with all values**: You can get a `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` file for the upgrade version by pulling and inspecting the Helm chart locally.
-
- ```sh
- helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}.tgz
- open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml
- ```
-
-For more information, see the [Helm reference docs]({{< link-hextra path="/reference/helm/" >}}).
-
-## Development builds
-
-When using the development build {{< reuse "agw-docs/versions/patch-dev.md" >}}, add `--set controller.image.pullPolicy=Always` to ensure you get the latest image. For production environments, this setting is not recommended as it might impact performance.
-
-
-
-### Experimental Gateway API features {#experimental-gateway-api-features}
-
-To use experimental Gateway API features, you must enable the experimental feature gate, `KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES`. This setting defaults to `false` and must be explicitly enabled to use experimental features such as the following:
-
-- ListenerSets
-- CORS policies
-- Retries
-- Session persistence
-
-To enable these features, set the environment variable in your kgateway controller deployment in your Helm values file.
-
-```yaml
-controller:
- extraEnv:
- KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES: "true"
-```
-
-
-
-
-## Leader election
-
-Leader election is enabled by default to ensure that you can run {{< reuse "agw-docs/snippets/kgateway.md" >}} in a multi-control plane replica setup for high availability.
-
-You can disable leader election by setting the `controller.disableLeaderElection` to `true` in your Helm chart.
-
-```yaml
-
-controller:
- disableLeaderElection: true
-```
-
-
-
-## Namespace discovery {#namespace-discovery}
-
-You can limit the namespaces that {{< reuse "/agw-docs/snippets/kgateway.md" >}} watches for gateway configuration. For example, you might have a multi-tenant cluster with different namespaces for different tenants. You can limit {{< reuse "/agw-docs/snippets/kgateway.md" >}} to only watch a specific namespace for gateway configuration.
-
-Namespace selectors are a list of matched expressions or labels.
-
-* `matchExpressions`: Use this field for more complex selectors where you want to specify an operator such as `In` or `NotIn`.
-* `matchLabels`: Use this field for simple selectors where you want to specify a label key-value pair.
-
-Each entry in the list is disjunctive (OR semantics). This means that a namespace is selected if it matches any selector.
-
-You can also use matched expressions and labels together in the same entry, which is conjunctive (AND semantics).
-
-The following example selects namespaces for discovery that meet either of the following conditions:
-
-* The namespace has the label `environment=prod` and the label `version=v2`, or
-* The namespace has the label `version=v3`
-
-```yaml
-discoveryNamespaceSelectors:
-- matchExpressions:
- - key: environment
- operator: In
- values:
- - prod
- matchLabels:
- version: v2
-- matchLabels:
- version: v3
-```
-
-
-
-## TLS encryption {#tls-encryption}
-
-You can enable TLS encryption for the xDS gRPC server in the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane. For more information, see the [TLS encryption]({{< link-hextra path="/install/tls" >}}) docs.
-
-
diff --git a/assets/docs/pages/install/argocd.md b/assets/docs/pages/install/argocd.md
deleted file mode 100644
index cb1ed0fcb..000000000
--- a/assets/docs/pages/install/argocd.md
+++ /dev/null
@@ -1,54 +0,0 @@
-In this installation guide, you install {{< reuse "/agw-docs/snippets/kgateway.md" >}} in a Kubernetes cluster by using [Argo CD](https://argoproj.github.io/cd/). Argo CD is a declarative continuous delivery tool that is especially popular for large, production-level installations at scale. This approach incorporates Helm configuration files.
-
-## Before you begin
-
-1. Create or use an existing Kubernetes cluster.
-2. Install the following command-line tools.
- * [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool. Download the `kubectl` version that is within one minor version of the Kubernetes clusters you plan to use.
- * [`argo`](https://argo-cd.readthedocs.io/en/stable/cli_installation/), the Argo CD command line tool.
-3. If you do not already have Argo CD installed in your cluster, install it.
- ```shell
- kubectl create namespace argocd
- until kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/v2.12.3/manifests/install.yaml > /dev/null 2>&1; do sleep 2; done
- # wait for deployment to complete
- kubectl -n argocd rollout status deploy/argocd-applicationset-controller
- kubectl -n argocd rollout status deploy/argocd-dex-server
- kubectl -n argocd rollout status deploy/argocd-notifications-controller
- kubectl -n argocd rollout status deploy/argocd-redis
- kubectl -n argocd rollout status deploy/argocd-repo-server
- kubectl -n argocd rollout status deploy/argocd-server
- ```
-4. Update the default Argo CD password for the admin user to `gateway`.
- ```shell
- # bcrypt(password)=$2y$10$f6GlB5V/8OzCduEDEgBU.ugVn4vzxgT7cq7vuCebZAKoADaNve9Ve
- # password: gateway
- kubectl -n argocd patch secret argocd-secret \
- -p '{"stringData": {
- "admin.password": "$2y$10$f6GlB5V/8OzCduEDEgBU.ugVn4vzxgT7cq7vuCebZAKoADaNve9Ve",
- "admin.passwordMtime": "'$(date +%FT%T%Z)'"
- }}'
- ```
-
-## Install
-
-Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} by using Argo CD.
-
-{{< reuse "agw-docs/snippets/argocd.md" >}}
-
-
-## Next steps
-
-Now that you have {{< reuse "/agw-docs/snippets/kgateway.md" >}} set up and running, check out the following guides to expand your gateway capabilities.
-
-
-
-
-- [Set up your agentgateway proxy]({{< link-hextra path="/setup/gateway/" >}}).
-- Review the [LLM consumption]({{< link-hextra path="/llm/" >}}), [inference routing]({{< link-hextra path="/inference/" >}}), [MCP]({{< link-hextra path="/mcp/" >}}), or [agent connectivity]({{< link-hextra path="/agent/" >}}) guides to learn more about common agentgateway use cases.
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-Follow the [Uninstall with Argo CD guide](../../operations/uninstall#argocd).
diff --git a/assets/docs/pages/install/helm.md b/assets/docs/pages/install/helm.md
deleted file mode 100644
index 3c79c557c..000000000
--- a/assets/docs/pages/install/helm.md
+++ /dev/null
@@ -1,157 +0,0 @@
-In this installation guide, you install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} {{< gloss "Control Plane" >}}control plane{{< /gloss >}} in a Kubernetes cluster by using [Helm](https://helm.sh/). Helm is a popular package manager for Kubernetes configuration files. This approach is flexible for adopting to your own command line, continuous delivery, or other workflows.
-
-
-
-As part of the control plane installation, you enable the {{< reuse "/agw-docs/snippets/agentgateway.md" >}} data plane.
-
-## Before you begin
-
-1. Create or use an existing Kubernetes cluster.
-2. Install the following command-line tools.
- * [`kubectl`](https://kubernetes.io/docs/tasks/tools/#kubectl), the Kubernetes command line tool. Download the `kubectl` version that is within one minor version of the Kubernetes clusters you plan to use.
- * [`helm`](https://helm.sh/docs/intro/install/), the Kubernetes package manager.
-
-## Install
-
-Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane by using Helm.
-
-1. Install the custom resources of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version {{< reuse "agw-docs/versions/k8s-gw-version.md" >}}.
- {{< tabs items="Standard, Experimental" tabTotal="2" >}}
- {{% tab tabName="Standard" %}}
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml
- ```
- {{% /tab %}}
- {{% tab tabName="Experimental" %}}
- CRDs in the experimental channel are required to use some experimental features in the Gateway API. Guides that require experimental CRDs note this requirement in their prerequisites.
- ```sh
- kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml
- ```
- {{% /tab %}}
- {{< /tabs >}}
- Example output:
- ```console
- customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
- ```
-
-2. Apply the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs for the upgrade version by using Helm.
-
- 1. **Optional**: To check the CRDs locally, download the CRDs to a `helm` directory.
-
- ```sh
- helm template --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} --output-dir ./helm
- ```
-
- 2. Deploy the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs by using Helm. This command creates the {{< reuse "agw-docs/snippets/namespace.md" >}} namespace and creates the {{< reuse "/agw-docs/snippets/kgateway.md" >}} CRDs in the cluster.
- ```sh
- helm upgrade -i --create-namespace \
- --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} \
- --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}
- ```
-
-3. Install the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart.
-
- 1. **Optional**: Pull and inspect the {{< reuse "/agw-docs/snippets/kgateway.md" >}} Helm chart values before installation. You might want to update the Helm chart values files to customize the installation. For example, you might change the namespace, update the resource limits and requests, or enable extensions such as for AI. For more information, see [Advanced settings](../advanced).
-
- ```sh
- helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-flag.md" >}}
-
- tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-flag.md" >}}.tgz
-
- open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml
- ```
-
- 2. Install {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane by using Helm. If you modified the `values.yaml` file with custom installation values, add the `-f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` flag.
-
- {{< tabs tabTotal="3" items="Basic installation,Custom values file,Development" >}}
-{{% tab tabName="Basic installation" %}}
-
-
-
-
-```sh
-helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \
---version {{< reuse "agw-docs/versions/helm-version-flag.md" >}}
-```
-
-
-{{% /tab %}}
-{{% tab tabName="Custom values" %}}
-
-
-
-
-```sh
-helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \
---version {{< reuse "agw-docs/versions/helm-version-flag.md" >}} \
--f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml
-```
-
-
-{{% /tab %}}
-{{% tab tabName="Development" %}}
-When using the development build {{< reuse "agw-docs/versions/helm-version-flag-n1.md" >}}, add the `--set controller.image.pullPolicy=Always` option to ensure you get the latest image. Alternatively, you can specify the exact image digest.
-
-
-
-
-```sh
-helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \
---version {{< reuse "agw-docs/versions/helm-version-flag-n1.md" >}} \
---set controller.image.pullPolicy=Always \
---set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true
-```
-
-
-{{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```txt
- NAME: {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}
- LAST DEPLOYED: Thu Feb 13 14:03:51 2025
- NAMESPACE: {{< reuse "agw-docs/snippets/namespace.md" >}}
- STATUS: deployed
- REVISION: 1
- TEST SUITE: None
- ```
-
-1. Verify that the control plane is up and running.
-
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
-
- ```txt
- NAME READY STATUS RESTARTS AGE
- {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-78658959cd-cz6jt 1/1 Running 0 12s
- ```
-
-2. Verify that the `{{< reuse "/agw-docs/snippets/gatewayclass.md" >}}` GatewayClass is created. You can optionally take a look at how the GatewayClass is configured by adding the `-o yaml` option to your command.
-
- ```sh
- kubectl get gatewayclass {{< reuse "/agw-docs/snippets/gatewayclass.md" >}}
- ```
-
-## Next steps
-
-
-
-
-Now that you have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane set up and running, check out the following guides to start using the {{< reuse "/agw-docs/snippets/agentgateway.md" >}} data plane.
-- Learn more about [{{< reuse "/agw-docs/snippets/agentgateway.md" >}}, its features and benefits](../../about/overview).
-- [Set up an agentgateway proxy](../../setup/) to start routing to AI workloads.
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-Follow the [Uninstall guide](../../operations/uninstall).
-
diff --git a/assets/docs/pages/install/sample-app.md b/assets/docs/pages/install/sample-app.md
deleted file mode 100644
index 81da920e9..000000000
--- a/assets/docs/pages/install/sample-app.md
+++ /dev/null
@@ -1,307 +0,0 @@
-The httpbin app lets you test your API gateway by sending requests to it and receiving responses.
-
-Review the following diagram to understand the setup.
-
-```mermaid
-flowchart LR
- A[client] -->|example.com| B[gateway proxy]
- B --> C[httpbin backend]
-```
-
-* The client calls the `www.example.com` hostname that you set up in the Gateway configuration.
-* The gateway proxy receives the request. Based on the routing rules that you set up in the Gateway configuration, the gateway proxy forwards the traffic to the backend destination, which is the httpbin service. The gateway proxy is available from an external LoadBalancer service that is backed by an IP address that your cloud provider typically assigns. For testing in a local cluster where you do not have an external service, you can enable port-forwarding so that the gateway proxy listens on the localhost instead.
-* The httpbin service receives and responds to the request. Note that the httpbin service does not have to be publicly exposed because the gateway proxy handles the external traffic. Instead, it can have an internal service type, such as ClusterIP.
-
-## Before you begin
-
-Set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} by following the [Quick start](../../quickstart/) or [Installation]({{< link-hextra path="/install" >}}) guides.
-
-## Deploy a sample app {#deploy-app}
-
-The following configuration file creates the httpbin app. To review the source file, see [the kgateway project](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml).
-
-1. Create the httpbin app.
-
- ```shell
- kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml
- ```
-
- Example output:
-
- ```txt
- namespace/httpbin created
- serviceaccount/httpbin created
- service/httpbin created
- deployment.apps/httpbin created
- ```
-
-2. Verify that the httpbin app is running.
-
- ```sh
- kubectl -n httpbin get pods
- ```
-
- Example output:
-
- ```txt
- NAME READY STATUS RESTARTS AGE
- httpbin-d57c95548-nz98t 2/2 Running 0 18s
- ```
-
-## Set up an API gateway {#api-gateway}
-
-Create an API gateway with an HTTP listener by using the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}.
-
-1. Create a Gateway resource and configure an HTTP listener. The following Gateway can serve HTTPRoute resources from all namespaces. For more information about which GatewayClass to use, see [About gateway proxies](../../about/proxies/).
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "/agw-docs/snippets/agw-gatewayclass.md" >}}
- listeners:
- - protocol: HTTP
- port: 8080
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-2. Verify that the Gateway is created successfully. You can also review the external address that is assigned to the Gateway. Note that depending on your environment it might take a few minutes for the load balancer service to be assigned an external address. If you are using a local Kind cluster without a load balancer such as `metallb`, you might not have an external address.
-
- ```sh
- kubectl get gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
-
- ```txt
- NAME CLASS ADDRESS PROGRAMMED AGE
- http {{< reuse "/agw-docs/snippets/agw-gatewayclass.md" >}} 1234567890.us-east-2.elb.amazonaws.com True 93s
- ```
-
-3. Verify that the gateway proxy pod is running.
-
- ```sh
- kubectl get po -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http
- ```
-
- Example output:
-
- ```txt
- NAME READY STATUS RESTARTS AGE
- http-7dd94b74-k26j6 3/3 Running 0 18s
- ```
-
- {{< callout type="info" >}}
- Using Kind and getting a `CrashLoopBackOff` error with a `Failed to create temporary file` message in the logs? You might have a multi-arch platform issue on macOS. In your Docker Desktop settings, uncheck **Use Rosetta**, restart Docker, re-create your Kind cluster, and try again.
- {{< /callout >}}
-
-## Expose the app on the gateway {#expose-app}
-
-Now that you have an app and a gateway proxy, you can create a route to access the app.
-
-1. Create an HTTPRoute resource to expose the httpbin app on the Gateway. The following example exposes the app on the `wwww.example.com` domain.
-
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "www.example.com"
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
- |Setting|Description|
- |--|--|
- |`spec.parentRefs`|The name and namespace of the Gateway resource that serves the route. In this example, you use the `http` Gateway that you created earlier. |
- |`spec.hostnames`|A list of hostnames that the route is exposed on. In the example, the route is exposed on `www.example.com`. |
- |`spec.rules.backendRefs`| The Kubernetes service that serves the incoming request. In this example, requests to `www.example.com` are forwarded to the httpbin app on port 8000. Note that you must create the HTTPRoute in the same namespace as the service that serves that route. To create the HTTPRoute resource in a different namespace, you must create a ReferenceGrant resource to allow the HTTPRoute to forward requests to a service in a different namespace. For more information, see the [Kubernetes API Gateway documentation](https://gateway-api.sigs.k8s.io/api-types/referencegrant/). |
-
-2. Verify that the HTTPRoute is applied successfully.
-
- ```sh
- kubectl get -n httpbin httproute/httpbin -o yaml
- ```
-
- Example output: Note the status of the HTTPRoute resource. Check for `Accepted` and `ResolvedRefs` messages. The `parentRef` refers to the Gateway that that HTTPRoute is exposed on.
-
- ```yaml
- status:
- parents:
- - conditions:
- - lastTransitionTime: "2025-02-13T18:41:06Z"
- message: ""
- observedGeneration: 1
- reason: Accepted
- status: "True"
- type: Accepted
- - lastTransitionTime: "2025-02-13T18:41:06Z"
- message: ""
- observedGeneration: 1
- reason: ResolvedRefs
- status: "True"
- type: ResolvedRefs
- controllerName: kgateway.dev/kgateway
- parentRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-## Send a request {#send-request}
-
-Now that your httpbin app is running and exposed on the gateway proxy, you can send a request to the app. The steps vary depending on your load balancer setup.
-
-{{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
-{{% tab tabName="Cloud Provider LoadBalancer" %}}
-1. Get the external address of the gateway proxy and save it in an environment variable.
-
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} http -o=jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
-
-2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. Note that it might take a few seconds for the load balancer service to become fully ready and accept traffic.
-
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- access-control-allow-credentials: true
- access-control-allow-origin: *
- content-type: application/json; encoding=utf-8
- date: Thu, 13 Feb 2025 18:49:32 GMT
- content-length: 330
- x-envoy-upstream-service-time: 4
- server: envoy
- ```
- ```json
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "26be0bcd-d941-48f4-ac3b-d5ac288ac46f"
- ]
- }
- }
- ```
-{{% /tab %}}
-{{% tab tabName="Port-forward for local testing"%}}
-1. Port-forward the gateway proxy `http` pod on port 8080.
-
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080
- ```
-
-2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code.
-
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- access-control-allow-credentials: true
- access-control-allow-origin: *
- content-type: application/json; encoding=utf-8
- date: Thu, 13 Feb 2025 18:49:32 GMT
- content-length: 330
- x-envoy-upstream-service-time: 4
- server: envoy
- ```
- ```json
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "26be0bcd-d941-48f4-ac3b-d5ac288ac46f"
- ]
- }
- }
- ```
-{{% /tab %}}
-{{< /tabs >}}
-
-## Next steps
-
-Now that you have {{< reuse "/agw-docs/snippets/kgateway.md" >}} set up and running, check out the following guides to expand your API gateway capabilities.
-
-- Add routing capabilities to your httpbin route by using the [Traffic management](../../traffic-management) guides.
-- Explore ways to make your routes more resilient by using the [Resiliency](../../resiliency) guides.
-- Secure your routes with external authentication and rate limiting policies by using the [Security](../../security) guides.
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-
-1. Delete the httpbin app.
-
- ```sh
- kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml
- ```
-
-2. Delete the HTTPRoute.
-
- ```sh
- kubectl delete httproute httpbin -n httpbin
- ```
-
-3. Delete the Gateway.
-
- ```sh
- kubectl delete gateway http -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
diff --git a/assets/docs/pages/install/tls.md b/assets/docs/pages/install/tls.md
deleted file mode 100644
index d7ad61fe8..000000000
--- a/assets/docs/pages/install/tls.md
+++ /dev/null
@@ -1,182 +0,0 @@
-Enable server-side TLS encryption for the xDS gRPC server in the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane. For more information about the server, see the [Architecture]({{< link-hextra path="/about/architecture" >}}) docs.
-
-TLS encryption is disabled by default. When enabled, the control plane mounts a `{{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert` TLS secret that you create and propogates the CA bundle to any {{< reuse "agw-docs/snippets/pod-name.md" >}} data plane proxies to establish a secure connection. You might integrate your secret with a provider such as [cert-manager](https://cert-manager.io/docs/) to automate certificate management and rotation.
-
-## Before you begin
-
-{{< conditional-text include-if="envoy" >}}{{< reuse "agw-docs/snippets/prereq.md" >}}{{< /conditional-text >}}
-{{< conditional-text include-if="agentgateway" >}}{{< reuse "agw-docs/snippets/agentgateway-prereq.md" >}}{{< /conditional-text >}}
-
-## Step 1: Set up cert-manager {#cert-manager}
-
-cert-manager is a Kubernetes controller that helps you automate the process of obtaining and renewing certificates from various PKI providers, such as AWS Private CA, Google Cloud CA, or Vault. In this example, you set up cert-manager to provide self-signed certificates for the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane.
-
-1. Add the Jetstack Helm repository.
- ```sh
- helm repo add jetstack https://charts.jetstack.io --force-update
- ```
-
-2. Install cert-manager in your cluster. **Note**: cert-manager versions 1.18 and later have stricter validation rules. Certificate durations must be at least 1 hour, and renewal windows must be at least 5 minutes.
- ```sh
- helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \
- --set "extraArgs={--feature-gates=ExperimentalGatewayAPISupport=true}" --set installCRDs=true
- ```
- {{< callout type="info" >}}To allow cert-manager to use the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you must set `--feature-gates=ExperimentalGatewayAPISupport=true` in the cert-manager Helm installation.{{< /callout >}}
-
-3. Create a self-signed Certificate Authority (CA) that acts as the root of trust for the xDS gRPC server certificates. For production environments, replace the self-signed root issuer with your organization's CA issuer, such as Vault or a cloud CA service. For more information, see the [cert-manager CA issuer docs](https://cert-manager.io/docs/configuration/issuers/).
-
- ```yaml
- kubectl apply -f - <}}-xds-root-issuer
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- selfSigned: {}
- ---
- apiVersion: cert-manager.io/v1
- kind: Certificate
- metadata:
- name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-secret
- issuerRef:
- name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-root-issuer
- kind: Issuer
- isCA: true
- commonName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca
- duration: 1h
- renewBefore: 5m
- privateKey:
- algorithm: RSA
- size: 2048
- EOF
- ```
-
-4. Use the CA to sign a TLS certificate for the xDS gRPC server. This two-tiered approach keeps the root CA separate from the server certificate, and lets the server certificate be rotated independently of the CA. cert-manager automatically creates a Kubernetes secret with the required name `{{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert`, type `kubernetes.io/tls`, and the server certificate and private key in the `tls.crt` and `tls.key` keys.
-
- {{< callout type="info" >}}The DNS names in the server certificate must match the service endpoints of the control plane. If you install the control plane in a different namespace, you must update the DNS names to match the actual service endpoints.{{< /callout >}}
-
- ```yaml
- kubectl apply -f - <}}-xds-ca-issuer
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- ca:
- secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-secret
- ---
- apiVersion: cert-manager.io/v1
- kind: Certificate
- metadata:
- name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- secretName: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-cert
- issuerRef:
- name: {{< reuse "agw-docs/snippets/pod-name.md" >}}-xds-ca-issuer
- kind: Issuer
- isCA: false
- dnsNames:
- - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}
- - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}}
- - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc
- - {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.{{< reuse "agw-docs/snippets/namespace.md" >}}.svc.cluster.local
- duration: 1h
- renewBefore: 5m
- privateKey:
- algorithm: RSA
- size: 2048
- EOF
- ```
-
-## Step 2: Update the control plane to use TLS {#control-plane}
-
-Upgrade {{< reuse "agw-docs/snippets/kgateway.md" >}} with TLS enabled for the controller. For complete steps, review the [Upgrade guide]({{< link-hextra path="/operations/upgrade" >}}).
-
-1. Set your version of {{< reuse "/agw-docs/snippets/kgateway.md" >}} in an environment variable, such as the latest patch version (`{{< reuse "agw-docs/versions/n-patch.md" >}}`).
-
- ```sh
- export NEW_VERSION={{< reuse "agw-docs/versions/n-patch.md" >}}
- ```
-
-2. Get the Helm values file for your current version.
-
- ```sh
- helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > values.yaml
- open values.yaml
- ```
-
-3. Add the following values to the Helm values file to enable TLS for the xDS gRPC server.
- ```yaml
- controller:
- xds:
- tls:
- enabled: true
- ```
-
-4. Upgrade your Helm installation.
-
- ```sh
- helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \
- -f values.yaml \
- --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- ```
-
-5. Confirm that the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane is up and running.
-
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-## Step 3: Verify the TLS connection {#verify-tls-connection}
-
-Now that the control plane is up and running, verify the TLS connection.
-
-1. Port-forward the control plane service on port 9977.
-
- ```sh
- kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} svc/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9978
- ```
-
-2. Send a request to the control plane in plaintext without TLS authentication. You get back an `authentication failed` error.
-
- ```sh
- grpcurl -plaintext localhost:9978 list
- ```
-
- Example output:
-
- ```
- Failed to list services: rpc error: code = Unknown desc = authentication failed: [Authenticator KubeJWTAuthenticator: target JWT extraction error: no HTTP authorization header exists]
- ```
-
-3. Port-forward the control plane deployment on port 9092.
-
- ```sh
- kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} deploy/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092
- ```
-
-4. Send a request to the metrics endpoint to check for `xds_auth` metrics.
-
- ```sh
- curl localhost:9092/metrics | grep xds_auth
- ```
-
- Example output:
-
- ```
- # HELP kgateway_xds_auth_rq_failure_total Total number of failed xDS auth requests
- # TYPE kgateway_xds_auth_rq_failure_total counter
- kgateway_xds_auth_rq_failure_total 2
- # HELP kgateway_xds_auth_rq_success_total Total number of successful xDS auth requests
- # TYPE kgateway_xds_auth_rq_success_total counter
- kgateway_xds_auth_rq_success_total 1
- # HELP kgateway_xds_auth_rq_total Total number of xDS auth requests
- # TYPE kgateway_xds_auth_rq_total counter
- kgateway_xds_auth_rq_total 3
- ```
diff --git a/assets/docs/pages/integrations/argo.md b/assets/docs/pages/integrations/argo.md
deleted file mode 100644
index 5026e6495..000000000
--- a/assets/docs/pages/integrations/argo.md
+++ /dev/null
@@ -1,334 +0,0 @@
-[Argo Rollouts](https://argoproj.github.io/rollouts/) is a Kubernetes controller that provides advanced deployment capabilities such as blue-green, canary, canary analysis, experimentation, and progressive delivery features to Kubernetes. Because Argo Rollouts supports the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you can use Argo Rollouts to control how traffic is split and forwarded from the proxies that kgateway v2 manages to the apps in your cluster.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Install Argo Rollouts
-
-1. Create the `argo-rollouts` namespace and deploy the Argo Rollouts components into it.
- ```sh
- kubectl create namespace argo-rollouts
- kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
- ```
-
-2. Change the config map for the Argo Rollouts pod to install the Argo Rollouts Gateway API plug-in as shown in the following example. Alternatively, you could install the Argo Rollouts Helm chart instead to use init containers to achieve the same thing. For more information about either method, refer to the [Argo Rollouts docs](https://rollouts-plugin-trafficrouter-gatewayapi.readthedocs.io/en/v0.8.0/installation/).
- ```yaml
- cat <}}
- The following cluster role allows the Argo Rollouts pod to access and work with any resources in the cluster. Use this configuration with caution and only in test environments.
- {{< /callout >}}
- ```yaml
- kubectl apply -f- <}}). The HTTP resource can serve both the stable and canary versions of your app.
- ```yaml
- kubectl apply -f- <}}
- {{% tab %}}
- 1. Get the external address of the gateway and save it in an environment variable.
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
-
- 2. Send a request to the `rollouts-demo` app and verify that you see the `ver: 1.0` response from the stable service.
- ```sh
- curl http://$INGRESS_GW_ADDRESS:8080/callme -H "host: demo.example.com:8080"
- ```
-
- Example output:
- ```console
-
ver: 1.0
-
%
- ```
- {{% /tab %}}
- {{% tab %}}
- 3. Port-forward the `http` pod on port 8080.
- ```sh
- kubectl port-forward deployment/http -n kgateway-system 8080:8080
- ```
-
- 4. Send a request to the `rollouts-demo` app and verify that you see the `ver: 1.0` response from the stable service.
- ```sh
- curl -vi localhost:8080/callme -H "host: demo.example.com"
- ```
-
- Example output:
- ```console
-
ver: 1.0
-
%
- ```
-
- {{% /tab %}}
- {{< /tabs >}}
-
-4. Change the manifest to use the `v2` tag to start a rollout of your app. Argo Rollouts automatically starts splitting traffic between version 1 and version 2 of the app for the duration of the rollout.
- ```sh
- kubectl patch rollout rollouts-demo -n default \
- --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"kostiscodefresh/summer-of-k8s-app:v2"}]'
- ```
-
-5. Send another request to your app. Because traffic is split between version 1 and version 2 of the app, you see responses from both app versions until the rollout is completed.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab %}}
- ```bash
- while true; do curl -H "host: demo.example.com" $INGRESS_GW_ADDRESS:8080/callme; done
- ```
-
- Example output:
- ```console
-
ver: 2.0
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-Congratulations, you successfully rolled out a new version of your app without downtime by using the HTTP gateway that is managed by kgateway v2. After a rollout, you typically perform tasks such as the following:
-
-- **Testing**: Conduct thorough testing of your app to ensure that it functions correctly after the rollout.
-- **Monitoring**: Monitor your application to detect any issues that may arise after the rollout.
-- **Documentation**: Update documentation or runbooks to reflect any changes in your application.
-- **User Validation**: Have users validate that the app functions correctly and meets their requirements.
-- **Performance Testing**: Depending on your app, consider conducting performance testing to ensure that your app can handle the expected load without issues.
-- **Resource Cleanup**: If the rollout included changes to infrastructure or other resources, ensure that any temporary or unused resources are cleaned up to avoid incurring unnecessary costs.
-- **Communication**: Communicate with your team and stakeholders to update them on the status of the rollout and any issues that were encountered and resolved.
-- **Security Audit**: If your application has undergone significant changes, consider conducting a security audit to ensure that no security vulnerabilities have been introduced.
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Remove the HTTPRoute.
- ```sh
- kubectl delete httproute argo-rollouts-http-route
- ```
-
-2. Remove the Argo Rollout.
- ```sh
- kubectl delete rollout rollouts-demo
- ```
-
-3. Remove the stable and canary services.
- ```sh
- kubectl delete services argo-rollouts-canary-service argo-rollouts-stable-service
- ```
-
-4. Remove the cluster role for the Argo Rollouts pod.
- ```sh
- kubectl delete clusterrole gateway-controller-role -n argo-rollouts
- ```
-
-5. Remove the cluster role binding.
- ```sh
- kubectl delete clusterrolebinding gateway-admin
- ```
-
-6. Remove Argo Rollouts.
- ```sh
- kubectl delete -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
- kubectl delete namespace argo-rollouts
- ```
-
diff --git a/assets/docs/pages/integrations/aws-elb.md b/assets/docs/pages/integrations/aws-elb.md
deleted file mode 100644
index 953bb557f..000000000
--- a/assets/docs/pages/integrations/aws-elb.md
+++ /dev/null
@@ -1,6 +0,0 @@
-{{< callout type="info" >}}
-To learn how to pair your kgateway proxy with an NLB or ALB, see the [AWS ELB guides]({{< link-hextra path="/setup/customize/aws-elb/" >}}).
-{{< /callout >}}
-
-{{< reuse "agw-docs/snippets/aws-alb-nlb.md" >}}
-
diff --git a/assets/docs/pages/integrations/aws-elb/alb.md b/assets/docs/pages/integrations/aws-elb/alb.md
deleted file mode 100644
index 98503d424..000000000
--- a/assets/docs/pages/integrations/aws-elb/alb.md
+++ /dev/null
@@ -1,200 +0,0 @@
-In this guide you explore how to expose the {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy with an AWS application load balancer (ALB).
-
-{{< callout type="warning" >}}
-The AWS Load Balancer Controller only supports the creation of an ALB through an Ingress Controller and not through the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. Because of this, you must create the ALB separately through an Ingress resource that connects it to the service that exposes your gateway proxy.
-{{< /callout >}}
-
-## Before you begin
-
-1. Create or use an existing AWS account.
-2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}.
-3. Deploy the httpbin sample app. For more information, see the [sample app guide]({{< link-hextra path="/install/sample-app#deploy-app/" >}}).
- 1. Create the httpbin app.
- ```shell
- kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml
- ```
-
- Example output:
- ```txt
- namespace/httpbin created
- serviceaccount/httpbin created
- service/httpbin created
- deployment.apps/httpbin created
- ```
- 2. Verify that the httpbin app is running.
- ```sh
- kubectl -n httpbin get pods
- ```
-
- Example output:
- ```txt
- NAME READY STATUS RESTARTS AGE
- httpbin-d57c95548-nz98t 2/2 Running 0 18s
- ```
-
-## Step 1: Deploy gateway proxy resources
-
-1. Create a Gateway resource with an HTTP listener. You later pair this Gateway with an AWS ALB.
- ```yaml
- kubectl apply -n {{< reuse "agw-docs/snippets/namespace.md" >}} -f- <}}
- listeners:
- - protocol: HTTP
- port: 8080
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-2. Create DirectResponse and HTTPRoute resources to configure a custom healthcheck path on the gateway. In this example, you expose the `/healthz` path and configure it to always return a 200 HTTP response code by using the DirectResponse. Later, you configure the ALB to perform the health check against the `/healthz` path to determine if the Gateway is healthy.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: Exact
- value: /healthz
- filters:
- - type: ExtensionRef
- extensionRef:
- name: httpbin-healthcheck-dr
- group: gateway.kgateway.dev
- kind: DirectResponse
- EOF
- ```
-
-3. Create another HTTPRoute resource to expose the httpbin app on the `albtest.com` domain.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "albtest.com"
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-## Step 2: Create an ALB with the AWS Load Balancer controller
-
-{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}}
-
-5. Use an Ingress resource to define your ALB. When you apply this resource, the AWS Load Balancer Controller creates the ALB in your account.
- ```yaml
- kubectl apply -f- <}}
- name: alb
- annotations:
- alb.ingress.kubernetes.io/scheme: internet-facing
- alb.ingress.kubernetes.io/target-type: instance
- alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
- alb.ingress.kubernetes.io/healthcheck-path: "/healthz"
- spec:
- ingressClassName: alb
- rules:
- - http:
- paths:
- - path: /
- pathType: Prefix
- backend:
- service:
- name: alb
- port:
- number: 8080
- EOF
- ```
-
- {{< callout type="info" >}}
- If you later change your Ingress resource configuration, you might need to delete and re-create your Ingress resource for AWS to pick up the changes.
- {{< /callout >}}
-
-6. Review the load balancer in the AWS EC2 dashboard.
- 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2).
- 2. In the left navigation, go to **Load Balancing > Load Balancers**.
- 3. Find and open the ALB that was created for you, with a name such as `k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-alb-`. Note that it might take a few minutes for the ALB to provision.
- 4. On the **Resource map** tab, verify that the load balancer points to healthy EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name.
- {{< reuse-image src="img/alb.png" >}}
- {{< reuse-image-dark srcDark="img/alb.png" >}}
-
-## Step 3: Test the ALB
-
-1. In the **Details** pane of the ALB, get the **DNS name** that was assigned to your ALB and save it as an environment variable.
- ```sh
- export INGRESS_GW_ADDRESS=
- ```
-
-2. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code.
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: albtest.com:80"
- ```
-
- Example output:
- ```console
- ...
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the Ingress, HTTPRoute, DirectResponse, and Gateway resources.
- ```sh
- kubectl delete ingress alb -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete httproute httpbin-alb -n httpbin
- kubectl delete httproute httpbin-healthcheck -n httpbin
- kubectl delete directresponse httpbin-healthcheck-dr -n httpbin
- kubectl delete gateway alb -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-2. Delete the AWS IAM resources that you created.
- ```sh
- eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME}
- aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME}
- ```
-
-3. Uninstall the Helm release for the `aws-load-balancer-controller`.
- ```sh
- helm uninstall aws-load-balancer-controller -n kube-system
- ```
\ No newline at end of file
diff --git a/assets/docs/pages/integrations/aws-elb/nlb.md b/assets/docs/pages/integrations/aws-elb/nlb.md
deleted file mode 100644
index 03d24cc5e..000000000
--- a/assets/docs/pages/integrations/aws-elb/nlb.md
+++ /dev/null
@@ -1,311 +0,0 @@
-In this guide you explore how to expose the {{< reuse "agw-docs/snippets/kgateway.md" >}} proxy with an AWS network load balancer (NLB). The following use cases are covered:
-
-* **NLB HTTP**: Create an HTTP listener on the NLB that exposes an HTTP endpoint on your gateway proxy. Traffic from the NLB to the proxy is not secured.
-* **TLS passthrough**: Expose an HTTPS endpoint of your gateway with an NLB. The NLB passes through HTTPS traffic to the gateway proxy where the traffic is terminated.
-
-{{< callout type="warning" >}}
-Keep in mind the following considerations when working with an NLB:
-* An AWS NLB has an idle timeout of 350 seconds that you cannot change. This limitation can increase the number of reset TCP connections.
-{{< /callout >}}
-
-## Before you begin
-
-1. Create or use an existing AWS account.
-2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}.
-3. Deploy the httpbin sample app. For more information, see the [sample app guide]({{< link-hextra path="/install/sample-app#deploy-app/" >}}).
- 1. Create the httpbin app.
- ```shell
- kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/{{< reuse "agw-docs/versions/github-branch.md" >}}/examples/httpbin.yaml
- ```
-
- Example output:
- ```txt
- namespace/httpbin created
- serviceaccount/httpbin created
- service/httpbin created
- deployment.apps/httpbin created
- ```
- 2. Verify that the httpbin app is running.
- ```sh
- kubectl -n httpbin get pods
- ```
-
- Example output:
- ```txt
- NAME READY STATUS RESTARTS AGE
- httpbin-d57c95548-nz98t 2/2 Running 0 18s
- ```
-
-## Step 1: Deploy the AWS Load Balancer controller
-
-{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}}
-
-## Step 2: Deploy your gateway proxy
-
-1. Create a {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource with custom AWS annotations. These annotations instruct the AWS load balancer controller to expose the gateway proxy with a public-facing AWS NLB.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- metadata:
- name: custom-gw-params
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- kube:
- service:
- extraAnnotations:
- service.beta.kubernetes.io/aws-load-balancer-type: "external"
- service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
- service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: "instance"
- EOF
- ```
-
- | Setting | Description |
- | -- | -- |
- | `aws-load-balancer-type: "external"` | Instruct Kubernetes to pass the Gateway's service configuration to the AWS load balancer controller that you created earlier instead of using the built-in capabilities in Kubernetes. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#configuration). |
- | `aws-load-balancer-scheme: internet-facing ` | Create the NLB with a public IP addresses that is accessible from the internet. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#prerequisites). |
- | `aws-load-balancer-nlb-target-type: "instance"` | Use the Gateway's instance ID to register it as a target with the NLB. For more information, see the [AWS documentation](https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/service/nlb/#instance-mode_1). |
-
-2. Depending on the annotations that you use on your gateway proxy, you can configure the NLB in different ways.
-
- {{< tabs tabTotal="2" items="Simple HTTP,TLS passthrough" >}}
- {{% tab tabName="Simple HTTP" %}}
-
- Create a simple NLB that accepts HTTP traffic on port 80 and forwards this traffic to the HTTP listener on your gateway proxy.
-
- {{< reuse-image src="/img/elb-http.svg" >}}
- {{< reuse-image-dark srcDark="/img/elb-http.svg" >}}
-
- This Gateway resource references the custom GatewayParameters resource that you created.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: custom-gw-params
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - protocol: HTTP
- port: 80
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{% /tab %}}
- {{% tab tabName="TLS passthrough" %}}
- Pass through HTTPS requests from the AWS NLB to your gateway proxy, and terminate TLS traffic at the gateway proxy for added security.
-
- {{< reuse-image src="/img/elb-tls-passthrough.svg" >}}
- {{< reuse-image-dark srcDark="/img/elb-tls-passthrough.svg" >}}
-
- 1. Create a self-signed TLS certificate to configure your gateway proxy with an HTTPS listener.
- {{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}}
-
- 2. Create a Gateway with an HTTPS listener that terminates incoming TLS traffic. Make sure to reference the custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource and the Kubernetes secret that contains the TLS certificate information.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: custom-gw-params
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - name: https
- port: 443
- protocol: HTTPS
- hostname: https.example.com
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-3. Verify that your gateway is created.
- ```sh
- kubectl get gateway aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-4. Verify that the gateway service is exposed with an AWS NLB and assigned an AWS hostname.
- ```sh
- kubectl get services aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```console
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- aws-cloud LoadBalancer 172.20.39.233 k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-awscloud-edaaecf0c5-2d48d93624e3a4bf.elb.us-east-2.amazonaws.com 80:30565/TCP 12s
- ```
-
-5. Review the NLB in the AWS EC2 dashboard.
- 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2).
- 2. In the left navigation, go to **Load Balancing > Load Balancers**.
- 3. Find and open the NLB that was created for you, with a name such as `k8s-{{< reuse "agw-docs/snippets/alb-elb-name.md" >}}-awscloud-`.
- 4. On the **Resource map** tab, verify that the load balancer points to EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name.
-
-## Step 3: Test traffic to the NLB {#test-traffic}
-
-{{< tabs tabTotal="2" items="Simple HTTP,TLS passthrough" >}}
-{{% tab tabName="Simple HTTP" %}}
-
-1. Create an HTTPRoute resource and associate it with the gateway that you created.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "www.nlb.com"
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-2. Get the AWS hostname of the NLB.
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} aws-cloud -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
- echo $INGRESS_GW_ADDRESS
- ```
-
-3. Send a request to the httpbin app.
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: www.nlb.com:80"
- ```
-
- Example output:
- ```console
- ...
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ```
-
-{{% /tab %}}
-{{% tab tabName="TLS passthrough" %}}
-
-1. Create an HTTPRoute resource and associate it with the gateway that you created.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "https.example.com"
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-2. Get the IP address that is associated with the NLB's AWS hostname.
- ```sh
- export INGRESS_GW_HOSTNAME=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} aws-cloud -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
- echo $INGRESS_GW_HOSTNAME
- export INGRESS_GW_ADDRESS=$(dig +short ${INGRESS_GW_HOSTNAME} | head -1)
- echo $INGRESS_GW_ADDRESS
- ```
-
-3. Send a request to the httpbin app. Verify that you see a successful TLS handshake and that you get back a 200 HTTP response code from the httpbin app.
- ```sh
- curl -vi --resolve "https.example.com:443:${INGRESS_GW_ADDRESS}" https://https.example.com:443/status/200
- ```
-
- Example output:
- ```console
- * Hostname https.example.com was found in DNS cache
- * Trying 3.XX.XXX.XX:443...
- * Connected to https.example.com (3.XX.XXX.XX) port 443 (#0)
- * ALPN, offering h2
- * ALPN, offering http/1.1
- * successfully set certificate verify locations:
- * CAfile: /etc/ssl/cert.pem
- * CApath: none
- * TLSv1.2 (OUT), TLS handshake, Client hello (1):
- * TLSv1.2 (IN), TLS handshake, Server hello (2):
- * TLSv1.2 (IN), TLS handshake, Certificate (11):
- * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
- * TLSv1.2 (IN), TLS handshake, Server finished (14):
- * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
- * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
- * TLSv1.2 (OUT), TLS handshake, Finished (20):
- * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
- * TLSv1.2 (IN), TLS handshake, Finished (20):
- * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
- * ALPN, server accepted to use h2
- * Server certificate:
- * subject: CN=*; O=any domain
- * start date: Jul 23 20:03:48 2024 GMT
- * expire date: Jul 23 20:03:48 2025 GMT
- * issuer: O=any domain; CN=*
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * Using HTTP2, server supports multi-use
- * Connection state changed (HTTP/2 confirmed)
- * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
- * Using Stream ID: 1 (easy handle 0x14200fe00)
- ...
- < HTTP/2 200
- HTTP/2 200
- ```
-
-{{% /tab %}}
-{{< /tabs >}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the Ingress and Gateway resources.
- ```sh
- kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom-gw-params -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete gateway aws-cloud -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete httproute httpbin-elb -n httpbin
- kubectl delete secret https -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-2. Delete the AWS IAM resources that you created.
- ```sh
- aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME}
- eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME}
- ```
-
-3. Uninstall the Helm release for the `aws-load-balancer-controller`.
- ```sh
- helm uninstall aws-load-balancer-controller -n kube-system
- ```
\ No newline at end of file
diff --git a/assets/docs/pages/integrations/external-dns-cert-manager.md b/assets/docs/pages/integrations/external-dns-cert-manager.md
deleted file mode 100644
index 195b4ec3d..000000000
--- a/assets/docs/pages/integrations/external-dns-cert-manager.md
+++ /dev/null
@@ -1,351 +0,0 @@
-[ExternalDNS](https://github.com/kubernetes-sigs/external-dns) and [cert-manager](https://github.com/cert-manager/cert-manager) are two well-known integrations within the Kubernetes ecosystem that can be used in conjunction to automate the creation of TLS certificates.
-
-* **ExternalDNS**: Instead of manually editing your domain in your DNS provider to add load balancer IP addresses, you can use ExternalDNS to dynamically set up and control DNS records for discovered Gateway and HTTPRoute resources. When you define a hostname in an HTTPRoute resource, ExternalDNS uses the external address that is assigned to the Gateway's load balancer service that serves this hostname, and uses this information to create a DNS record in the DNS provider that you configured.
-* **cert-manager**: You can then use cert-manager to quickly and programmatically generate certificates for your domain, and store them in a Kubernetes secret. By adding this certificates secret to the HTTPRoute on the Gateway for your domain, you can secure it for HTTPS traffic.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up ExternalDNS
-
-1. Save your domain in an environment variable. Note that you must own the domain to enable ExternalDNS to create DNS records on your behalf.
- ```sh
- export DOMAIN=
-
-2. Create an HTTPRoute resource to expose httpbin on your domain.
- ```yaml
- kubectl apply -f- <"
- EOF
- ```
-
-5. Wait for the DNS entry to be created. Note that depending on the DNS provider you use, this process can take some time to complete. To verify that the DNS record is created, use the `dig` command as shown in the following example.
- ```sh
- dig ${DOMAIN}
- ```
-
- Example output for a successfully created DNS record:
- ```console
- ;; ANSWER SECTION:
- ${DOMAIN} 300 IN A 164.90.241.80
- ```
-
-## Set up cert-manager
-
-cert-manager is a Kubernetes controller that helps you automate the process of obtaining and renewing certificates from various PKI providers, such as AWS Private CA, Google Cloud CA, or Vault. In this example, you install cert-manager by using Helm and configure it to obtain TLS certificates for your domain from Let's Encrypt.
-
-1. Install cert-manager.
- 1. Add the Jetstack Helm repository.
- ```sh
- helm repo add jetstack https://charts.jetstack.io --force-update
- ```
- 2. Install cert-manager in your cluster.
- ```sh
- helm upgrade --install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace \
- --set "extraArgs={--feature-gates=ExperimentalGatewayAPISupport=true}" --set installCRDs=true
- ```
- {{< callout type="info" >}}To allow cert-manager to use the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}, you must set `--feature-gates=ExperimentalGatewayAPISupport=true` in the cert-manager Helm installation.{{< /callout >}}
-
-2. Create an Issuer resource that represents the Certificate Authority (CA) that you want cert-manager to use to issue the TLS certificates for your domain.
- ```yaml
- kubectl apply -f- <
- server: https://acme-staging-v02.api.letsencrypt.org/directory
- privateKeySecretRef:
- name: letsencrypt-http-issuer-account-key
- solvers:
- - http01:
- gatewayHTTPRoute:
- parentRefs:
- - name: http
- namespace: kgateway-system
- kind: Gateway
- EOF
- ```
-
- | Setting | Description |
- | -- | -- |
- | `acme` | The protocol to use for issuing certificates. In this example, you configure cert-manager to obtain a Let's Encrypt certificate by using the ACME (Automated Certificate Management Environment) protocol. |
- | `email` | Provide an email address where you can receive Let's Encrypt notifications for certificate expiration and account recovery. |
- | `server` | The Let's Encrypt ACME server used for issuing certificates. The value `https://acme-staging-v02.api.letsencrypt.org/directory` uses the Let's Encrypt staging environment to avoid hitting rate limits during testing. For production setups, use the `https://acme-v02.api.letsencrypt.org/directory` server instead. |
- | `privateKeySecretRef.name` | Using your email address, cert-manager automatically generates and stores an ACME private account key in a Kubernetes secret of this name. cert-manager then uses this key to authenticate with Let's Encrypt. This example uses the name `letsencrypt-http-issuer-account-key` in the `kgateway-system` namespace. |
- | `solvers.http01` | To automate domain validation and certificate issuance, you use the HTTP-01 challenge. The HTTP-01 challenge is designed to prove that you have control over your domain by requiring you to store a challenge token in your cluster so that Let's Encrypt can validate it. For more information about this challenge, see the [Let's Encrypt documentation](https://letsencrypt.org/docs/challenge-types/#http-01-challenge). |
- | `gatewayHTTPRoute.parentRefs` | The reference to the Gateway resource to solve certificate challenges. This example uses the `http` Gateway that you created in the get started guide. |
-
-3. Verify that your TLS certificates are created successfully. Note that depending on the CA that you use, this process might take a while to complete.
- ```sh
- kubectl get issuer letsencrypt-http -n kgateway-system
- ```
-
- Example output for successfully issued TLS certificates:
- ```console
- Status:
- Acme:
- Conditions:
- Last Transition Time: 2023-11-09T16:03:58Z
- Message: The ACME account was registered with the ACME server
- Observed Generation: 1
- Reason: ACMEAccountRegistered
- Status: True
- Type: Ready
- ```
-
-4. Verify that the TLS certificate was added to the secret that you configured in the cert-manager issuer resource.
- ```sh
- kubectl get secret letsencrypt-http-issuer-account-key -n kgateway-system -o yaml
- ```
-
-## Configure an HTTPS listener on your gateway
-
-1. Add the cert-manager annotation and an HTTPS listener to the `http` gateway that you set up as part of the [Get started guide]({{< link-hextra path="/quickstart/" >}}).
- ```yaml
- kubectl apply -f- < GET /status/200 HTTP/2
-> Host: ${DOMAIN}
-> user-agent: curl/7.88.1
-> accept: */*
->
-< HTTP/2 200
-HTTP/2 200
-< access-control-allow-credentials: true
-access-control-allow-credentials: true
-< access-control-allow-origin: *
-access-control-allow-origin: *
-< date: Thu, 09 Nov 2023 17:28:17 GMT
-date: Thu, 09 Nov 2023 17:28:17 GMT
-< content-length: 0
-content-length: 0
-< x-envoy-upstream-service-time: 2
-x-envoy-upstream-service-time: 2
-< server: envoy
-server: envoy
-
-<
-* Connection #0 to host ${DOMAIN} left intact
-```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Remove the cert-manager annotation and HTTPS listener from the `http` Gateway.
- ```yaml
- kubectl apply -f- <}} as the ingress gateway for your ambient mesh.
-
-## About ambient mesh
-
-Solo.io and Google collaborated to develop {{< gloss "Ambient mesh" >}}ambient mesh{{< /gloss >}}, a new "sidecarless" architecture for the Istio service mesh. Ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed. To onboard apps into the ambient mesh, you simply label the namespace the app belongs to. Because no sidecars need to be injected in to your apps, ambient mesh significantly reduces the complexity of adopting a service mesh.
-
-To learn more about ambient, see the [ambient mesh documentation](https://ambientmesh.io/docs/about/).
-
-## About this guide
-
-In this guide, you learn how to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to route traffic to the httpbin app that is part of an ambient service mesh.
-
-This guide assumes that you run your ambient mesh in a single cluster and want to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to protect your ambient mesh services.
-
-{{< reuse-image src="img/ambient-ingress.svg" width="600px" caption="Ingress gateway integration for an ambient mesh" >}}
-{{< reuse-image-dark srcDark="img/ambient-ingress.svg" width="600px" caption="Ingress gateway integration for an ambient mesh" >}}
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Step 1: Set up an ambient mesh
-
-{{< reuse "agw-docs/snippets/setup-ambient-mesh.md" >}}
-
-## Step 2: Set up the ingress gateway
-
-To set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway for your ambient mesh, you simply add all the namespaces that you want to secure to your ambient mesh, including the namespace that your gateway proxy is deployed to.
-
-1. Add the `httpbin` and optionally the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace to your ambient mesh. The label instructs istiod to configure a ztunnel socket on all the pods in that namespace so that traffic to these pods is secured via mutual TLS (mTLS). If you do not label the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace, the traffic from the gateway proxy to the app is not secured via mTLS.
- ```sh
- kubectl label ns {{< reuse "agw-docs/snippets/namespace.md" >}} istio.io/dataplane-mode=ambient
- kubectl label ns httpbin istio.io/dataplane-mode=ambient
- ```
-
-2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code. All traffic from the gateway is automatically intercepted by a ztunnel that is co-located on the same node as the gateway. The ztunnel collects Layer 4 metrics before it forwards the request to the ztunnel that is co-located on the same node as the httpbin app. The connection between ztunnels is secured via mutual TLS.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
-
- Example output:
- ```console
- HTTP/1.1 200 OK
- ...
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com:8080"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "929c334b-e611-4aba-9bc6-ad6b2450db26"
- ]
- }
- }
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- 1. Port-forward the `http` pod on port 8080.
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080
- ```
-
- 2. Send a request to the httpbin app and verify that you get back a 200 HTTP response code.
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
-
- Example output:
- ```
- HTTP/1.1 200 OK
- ...
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com:8080"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "929c334b-e611-4aba-9bc6-ad6b2450db26"
- ]
- }
- }
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-3. Verify that traffic between the gateway proxy and the httpbin app is secured via mutual TLS. Because traffic in an ambient mesh is intercepted by the ztunnels that are co-located on the same node as the sending and receiving service, you can check the logs of the ztunnels.
- 1. Find the `NODE` that the httpbin app runs on.
- ```sh
- kubectl get pods -n httpbin -o wide
- ```
-
- Example output:
- ```
- NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
- httpbin-54cf575757-hdv8t 3/3 Running 0 22h 10.XX.X.XX gke-ambient-default-pool-bb9a8da5-bdf4
- ```
- 2. Find the ztunnel that runs on the same node as the httpbin app.
- ```sh
- kubectl get pods -n istio-system -o wide | grep ztunnel
- ```
- 3. Check the logs of that ztunnel instance and verify that the source and destination workloads have a SPIFFE ID.
- ```sh
- kubectl logs -n istio-system
- ```
-
- Example output:
- ```
- 2025-03-19T17:32:42.762545Z info http access request complete src.addr=10.0.71.117:42468 src.workload="http-9db6c8995-l54dw" src.namespace="{{< reuse "agw-docs/snippets/namespace.md" >}}" src.identity="spiffe://cluster.local/ns/{{< reuse "agw-docs/snippets/namespace.md" >}}/sa/http" dst.addr=10.0.65.144:15008 dst.hbone_addr=10.0.65.144:8080 dst.service="httpbin.httpbin.svc.cluster.local" dst.workload="httpbin-577649ddb-7nc8p" dst.namespace="httpbin" dst.identity="spiffe://cluster.local/ns/httpbin/sa/httpbin" direction="inbound" method=GET path="/headers" protocol=HTTP1 response_code=200 host="www.example.com:8080" user_agent="curl/8.7.1" request_id="4c5fc679-c5cd-4721-8735-51bcdbea6e0f" duration="0ms"
- 2025-03-19T17:32:46.810472Z info access connection complete src.addr=10.0.71.117:42468 src.workload="http-9db6c8995-l54dw" src.namespace="{{< reuse "agw-docs/snippets/namespace.md" >}}" src.identity="spiffe://cluster.local/ns/{{< reuse "agw-docs/snippets/namespace.md" >}}/sa/http" dst.addr=10.0.65.144:15008 dst.hbone_addr=10.0.65.144:8080 dst.service="httpbin.httpbin.svc.cluster.local" dst.workload="httpbin-577649ddb-7nc8p" dst.namespace="httpbin" dst.identity="spiffe://cluster.local/ns/httpbin/sa/httpbin" direction="inbound" bytes_sent=1290 bytes_recv=550 duration="6742ms"
- ```
-
-
-## Next
-
-Now that you set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway for your ambient mesh, you can further control and secure ingress traffic with [Policies](../../../../about/policies/).
-
-
diff --git a/assets/docs/pages/integrations/istio/ambient/waypoint.md b/assets/docs/pages/integrations/istio/ambient/waypoint.md
deleted file mode 100644
index ef2efe27c..000000000
--- a/assets/docs/pages/integrations/istio/ambient/waypoint.md
+++ /dev/null
@@ -1,871 +0,0 @@
-
-{{< callout type="warning" >}}
-The waypoint integration for Envoy-based gateway proxies is deprecated and is planned to be removed in version 2.2. If you want to use AI capabilities, use an [agentgateway proxy](../../../../../../../agentgateway/) instead.
-{{< /callout >}}
-
-
-
-Enforce Layer 7 policies for the apps in your ambient mesh by using {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy.
-
-## About ambient mesh
-
-Solo.io and Google collaborated to develop ambient mesh, a new "sidecarless" architecture for the Istio service mesh. Ambient mesh uses node-level ztunnels to route and secure Layer 4 traffic between pods with mutual TLS (mTLS). Waypoint proxies enforce Layer 7 traffic policies whenever needed. To onboard apps into the ambient mesh, you simply label the namespace the app belongs to. Because no sidecars need to be injected in to your apps, ambient mesh significantly reduces the complexity of adopting a service mesh.
-
-To learn more about ambient, see the [ambient mesh documentation](https://ambientmesh.io/docs/about/).
-
-## About this guide
-
-In this guide, you learn how to set up {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy for multiple apps in your ambient mesh. To demonstrate the Layer 7 capabilities of the waypoint proxy, you deploy the three sample apps `client`, `httpbin2`, and `httpbin3` to your cluster. The `client` app sends in-mesh traffic to `httpbin2` and `httpbin3`. To apply Layer 7 policies, you create HTTPRoute resources for the `httpbin2` and `httpbin3` apps that define the policies that you want to apply to each app. Because the HTTPRoute is scoped to a particular service, when the `client` app sends a request to that service, only the policies that are defined for that service are enforced by the waypoint proxy.
-
-{{< callout type="info" >}}
-You can create an HTTPRoute and scope it to the waypoint proxy by referencing the waypoint proxy in the `parentRef` section. This way, the policies that are defined in the HTTPRoute are automatically applied to all services in the waypoint proxy namespace.
-{{< /callout >}}
-
-{{< reuse-image src="img/waypoint.svg" width="600px" caption="Waypoint proxy for Layer 7 policy application in an ambient mesh" >}}
-{{< reuse-image-dark srcDark="img/waypoint.svg" width="600px" caption="Waypoint proxy for Layer 7 policy application in an ambient mesh" >}}
-
-## Set up an ambient mesh
-
-{{< reuse "agw-docs/snippets/setup-ambient-mesh.md" >}}
-
-## Deploy sample apps
-
-Install the httpbin2, httpbin3, and curl client sample apps into the httpbin namespace. You use these sample apps to demonstrate the Layer 7 capabilities of the waypoint proxy.
-
-1. Create the httpbin namespace.
- ```sh
- kubectl create ns httpbin
- ```
-
-2. Deploy the httpbin2, httpbin3, and client sample apps.
- {{< tabs tabTotal="3" items="httpbin2,httpbin3,client" >}}
- {{% tab tabName="httpbin2" %}}
- ```yaml
- kubectl apply -f - <}}
-
-4. Verify that all apps are deployed successfully.
- ```sh
- kubectl get pods -n httpbin
- ```
-
- Example output:
- ```
- NAME READY STATUS RESTARTS AGE
- client-87678cb44-dclfs 1/1 Running 0 87m
- httpbin2-58dcc755ff-ngq2f 1/1 Running 0 92m
- httpbin3-77bbdd9b6b-8d8hq 1/1 Running 0 70m
- ```
-
-5. Label the `httpbin` namespace to add the httpbin2, httpbin3, and client apps to the ambient mesh.
- ```sh
- kubectl label ns httpbin istio.io/dataplane-mode=ambient
- ```
-
-{{% version exclude-if="2.0.x" %}}
-
-## Enable the waypoint integration {#waypoint-integration}
-
-Enable the waypoint integration for Envoy-based kgateway proxies.
-
-{{< callout type="warning" >}}
-Note that the waypoint integration is deprecated for kgateway proxies and is planned to be removed in version 2.2.
-{{< /callout >}}
-
-1. Enable the waypoint integration in your kgateway Helm chart.
- ```sh
- helm get values {{< reuse "/agw-docs/snippets/kgateway.md" >}} -n {{< reuse "/agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/kgateway.md" >}}.yaml
-
- helm upgrade -i --namespace kgateway-system --version v{{< reuse "agw-docs/versions/patch-dev.md" >}} \
- kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \
- --set controller.image.pullPolicy=Always \
- --set waypoint.enabled=true \
- --values {{< reuse "/agw-docs/snippets/kgateway.md" >}}.yaml
- ```
-
-2. Verify that you see the `{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}` GatewayClass in your cluster.
- ```sh
- kubectl get gatewayclasses -A
- ```
-
- Example output:
- ```
- NAME CONTROLLER ACCEPTED AGE
- kgateway kgateway.dev/kgateway True 2d19h
- kgateway-waypoint kgateway.dev/kgateway True 1s
- ```
-{{% /version %}}
-
-## Create a waypoint proxy
-
-Use the `{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}` GatewayClass to deploy {{< reuse "/agw-docs/snippets/kgateway.md" >}} as a waypoint proxy in your cluster.
-
-1. Create a waypoint proxy in the httpbin namespace. Note that creating a waypoint proxy does not automatically enforce Layer 7 policies for the apps in your cluster. To assign a waypoint, you must label your apps. You learn how to label your apps in a later step.
-
- ```yaml
- kubectl apply -f - <}}
- namespace: httpbin
- spec:
- gatewayClassName: {{< reuse "/agw-docs/snippets/waypoint-class.md" >}}
- listeners:
- - name: proxy
- port: 15088
- protocol: istio.io/PROXY
- EOF
- ```
-
-2. Wait for the waypoint proxy to deploy successfully.
-
- ```sh
- kubectl -n httpbin rollout status deploy {{< reuse "/agw-docs/snippets/waypoint-class.md" >}}
- ```
-
- Example output:
- ```
- deployment "{{< reuse "/agw-docs/snippets/waypoint-class.md" >}}" successfully rolled out
- ```
-
-3. Label the httpbin2 and httpbin3 apps to use the waypoint proxy that you created.
-
- ```sh
- kubectl -n httpbin label svc httpbin2 istio.io/use-waypoint={{< reuse "/agw-docs/snippets/waypoint-class.md" >}}
- kubectl -n httpbin label svc httpbin3 istio.io/use-waypoint={{< reuse "/agw-docs/snippets/waypoint-class.md" >}}
- ```
-
-4. Send a request from the client app to httpbin2 and httpbin3. Verify that the request succeeds.
-
- ```sh
- kubectl -n httpbin exec deploy/client -- curl -s http://httpbin2:8000/get
- kubectl -n httpbin exec deploy/client -- curl -s http://httpbin3:8000/get
- ```
-
- Example output for httpbin2:
- ```
- {
- "args": {},
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "httpbin2:8000"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "590a6a48-60f8-4ec0-92d1-fcb629b97e0d"
- ]
- },
- "method": "GET",
- "origin": "10.XX.X.XX:34059",
- "url": "http://httpbin2:8000/get"
- }
- ```
-
-## Enforce L7 policies with the waypoint {#waypoint-policies}
-
-In this step, you explore how to apply different types of Layer 7 policies to your sample apps. These policies are enforced by the {{< reuse "/agw-docs/snippets/kgateway.md" >}} waypoint proxy that you created earlier. You can add other Layer 7 policies to the waypoint proxy. For more information, see the [traffic management](../../../../traffic-management), [security](../../../../security), and [resiliency](../../../../resiliency) guides.
-
-### Header control
-
-Use the Kubernetes Gateway API to define header manipulation rules that you apply to the httpbin apps, including adding, setting, and removing request headers.
-
-1. Create an HTTPRoute resource for the httpbin2 app with the following request header modifications rules:
- * Add the `App: httpbin2` header to all requests.
- * Set the `User-Agent` header to `custom`. If the User-Agent header is not present, it is added to the request.
- * Remove the `X-Remove` header from the request.
-
- Note that the HTTPRoute specifies the httpbin2 service in the `parentRefs` section. This setting instructs the waypoint proxy to enforce these policies for the httpbin2 app only.
- ```yaml
- kubectl apply -f - <}}'s {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} to apply a transformation policy to the httpbin2 app.
-
-1. If you have not done so yet, create an HTTPRoute for the httpbin2 app. You use this HTTPRoute to apply your transformation policy in the next step.
- ```yaml
- kubectl apply -f - <}} that applies a transformation policy to the httpbin2 app. In this example, the base64-encoded value from the `x-base64-encoded` header is decoded and added to the `x-base64-decoded` header, starting from the 11th character.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: transformation
- namespace: httpbin
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin2
- transformation:
- response:
- set:
- - name: x-base64-decoded
- value: '{{ substring(base64_decode(request_header("x-base64-encoded")), 11) }}'
- EOF
- ```
-
-3. Use the client app to send a request to the httpbin2 app and include a base64-encoded value of `transformation test` in the request `x-base64-encoded` header. Verify that you get back a 200 HTTP response code, and that the decoded value is added to the `x-base64-decoded` response header, starting from the 11th character.
- ```sh
- kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers \
- -H "x-base64-encoded: dHJhbnNmb3JtYXRpb24gdGVzdA=="
- ```
-
- Example output:
- ```console {hl_lines=[8,25,26]}
- < HTTP/1.1 200 OK
- ...
- access-control-allow-credentials: true
- access-control-allow-origin: *
- content-type: application/json; charset=utf-8
- content-length: 544
- x-envoy-upstream-service-time: 0
- x-base64-decoded: ion test
- server: envoy
-
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "App": [
- "httpbin2"
- ],
- "Host": [
- "httpbin2:8000"
- ],
- "User-Agent": [
- "custom"
- ],
- "X-Base64-Encoded": [
- "dHJhbnNmb3JtYXRpb24gdGVzdA=="
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Envoy-External-Address": [
- "10.0.74.217"
- ],
- "X-Forwarded-For": [
- "10.0.74.217"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "4b6444cc-b631-49c9-b2b4-f71ec479925f"
- ]
- }
- }
- ```
-
-4. Optional: Remove the {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} and HTTPRoute that you created in this guide.
- ```sh
- kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin
- kubectl delete httproute httpbin2 -n httpbin
- ```
-
-### Local rate limiting
-
-1. If you have not done so yet, create an HTTPRoute for the httpbin2 app. You use this HTTPRoute to apply your local rate limiting policy in the next step.
- ```yaml
- kubectl apply -f - <}} that applies a local rate limiting policy to the httpbin2 app. In this example, only one request is allowed within 30 seconds.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: ratelimit
- namespace: httpbin
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin2
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 30s
- EOF
- ```
-
-3. Use the client app to send three requests to the httpbin2 app. Verify that you get back a 200 HTTP response code for the first request, and that the second and third request are denied with a 429 HTTP response code.
- ```sh
- for i in {1..3}; do kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers ; done
- ```
-
- Example output:
- ```
- * Request completely sent off
- HTTP/1.1 200 OK
- < HTTP/1.1 200 OK
- ...
- * Request completely sent off
- HTTP/1.1 429 Too Many Requests
- content-length: 18
- content-type: text/plain
- server: envoy
- ...
- local_rate_limited
- ...
- * Request completely sent off
- < HTTP/1.1 429 Too Many Requests
- < content-length: 18
- < content-type: text/plain
- < server: envoy
- ...
- local_rate_limited%
- ```
-
-4. Optional: Remove the {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} and HTTPRoute.
- ```sh
- kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} ratelimit -n httpbin
- kubectl delete httproute httpbin2 -n httpbin
- ```
-
-### Istio AuthorizationPolicy
-
-Apply an Istio AuthorizationPolicy to allow access from specific apps only.
-
-1. Send a `GET` request from the client to the httpbin2 app. Verify that your request succeeds.
- ```sh
- kubectl -n httpbin exec deploy/client -- curl -vi http://httpbin2:8000/headers
- ```
-
- Example output:
- ```console
- HTTP/1.1 200 OK
- access-control-allow-credentials: true
- access-control-allow-origin: *
- content-type: application/json; charset=utf-8
- content-length: 439
- x-envoy-upstream-service-time: 2
- server: envoy
-
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "httpbin2:8000"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Envoy-External-Address": [
- "10.0.74.45"
- ....
- ```
-
-2. Create an Istio AuthorizationPolicy that denies all `GET` requests to the httpbin2 app.
- ```yaml
- kubectl apply -f- <}} -n httpbin
-kubectl delete serviceaccount httpbin2 -n httpbin
-kubectl delete service httpbin2 -n httpbin
-kubectl delete deployment httpbin2 -n httpbin
-kubectl delete serviceaccount httpbin3 -n httpbin
-kubectl delete service httpbin3 -n httpbin
-kubectl delete deployment httpbin3 -n httpbin
-kubectl delete serviceaccount client -n httpbin
-kubectl delete service client -n httpbin
-kubectl delete deployment client -n httpbin
-kubectl delete {{< reuse "/agw-docs/snippets/trafficpolicy.md" >}} transformation -n httpbin
-kubectl delete authorizationpolicy httpbin-authz -n httpbin
-```
-
diff --git a/assets/docs/pages/integrations/istio/sidecar/ingress.md b/assets/docs/pages/integrations/istio/sidecar/ingress.md
deleted file mode 100644
index c6ccea6dc..000000000
--- a/assets/docs/pages/integrations/istio/sidecar/ingress.md
+++ /dev/null
@@ -1,285 +0,0 @@
-Use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as the ingress gateway to control and secure traffic that enters your {{< gloss "Service Mesh" >}}service mesh{{< /gloss >}}.
-
-A service mesh is a dedicated infrastructure layer that you add your apps to, which ensures secure service-to-service communication across cloud networks. With a service mesh, you can solve problems such as service identity, mutual TLS communication, consistent L7 network telemetry gathering, service resilience, secure traffic routing between services across clusters, and policy enforcement, such as to enforce quotas or rate limit requests. To learn more about the benefits of using a service mesh, see [What is Istio](https://istio.io/latest/docs/overview/what-is-istio/) in the Istio documentation.
-
-### About Istio
-
-The open source project Istio is the leading service mesh implementation that offers powerful features to secure, control, connect, and monitor cloud-native, distributed applications. Istio is designed for workloads that run in one or more Kubernetes clusters, but you can also extend your service mesh to include virtual machines and other endpoints that are hosted outside your cluster. The key benefits of Istio include:
-
-* Automatic load balancing for HTTP, gRPC, WebSocket, MongoDB, and TCP traffic
-* Secure TLS encryption for service-to-service communication with identity-based authentication and authorization
-* Advanced routing and traffic management policies, such as retries, failovers, and fault injection
-* Fine-grained access control and quotas
-* Automatic logs, metrics, and traces for traffic in the service mesh
-
-### About the sidecar Istio integration
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} comes with an Istio integration that allows you to configure your gateway proxy with an Istio sidecar. The Istio sidecar uses mutual TLS (mTLS) to prove its identity and to secure the connection between your gateway and the services in your Istio service mesh. In addition, you can control and secure the traffic that enters the mesh by applying all the advanced routing, traffic management, security, resiliency, and AI capabilities that {{< reuse "/agw-docs/snippets/kgateway.md" >}} offers.
-
-## About this guide
-
-In this guide, you learn how to use {{< reuse "/agw-docs/snippets/kgateway.md" >}} as an ingress gateway proxy for the workloads in your Istio {{< gloss "Service Mesh" >}}service mesh{{< /gloss >}}. You explore how to enable the Istio sidecar mesh integration in {{< reuse "/agw-docs/snippets/kgateway.md" >}}, set up your ingress gateway proxy with a sidecar, and send secure mutual TLS traffic to the Bookinfo app as illustrated in the following image.
-
-{{< reuse-image src="img/sidecar-ingress.svg" width="800px" >}}
-{{< reuse-image-dark srcDark="img/sidecar-ingress-dark.svg" width="800px" >}}
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Step 1: Set up an Istio service mesh {#istio}
-
-1. Follow the [Istio documentation](https://istio.io/latest/docs/setup/getting-started/) to install Istio in sidecar mode.
-2. Deploy the [Bookinfo sample app](https://istio.io/latest/docs/examples/bookinfo/).
-3. Verify that your Bookinfo apps are up and running.
- ```sh
- kubectl get pods
- ```
-
-## Step 2: Enable the Istio integration {#istio-integration}
-
-Upgrade your {{< reuse "/agw-docs/snippets/kgateway.md" >}} installation to enable the Istio integration.
-
-1. Get the Helm values for your current Helm installation.
- ```sh
- helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- ```
-
-2. Add the following values to the Helm values file to enable the Istio integration in {{< reuse "/agw-docs/snippets/kgateway.md" >}}.
- ```yaml
-
- controller:
- extraEnv:
- KGW_ENABLE_ISTIO_AUTO_MTLS: true
- ```
-
-3. Upgrade your Helm installation. This upgrade automatically triggers a restart of any existing gateway proxies to inject `istio-proxy` and `sds` containers.
-
- ```sh
- helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- ```
-
- {{< callout type="warning" >}}
- The `istio-proxy` container in the gateway proxy looks for a service that is named `istiod` in the `istio-system` namespace to obtain a valid certificate. Depending on how you installed Istio, you might have a revisioned istiod deployment, such as `istiod-main`, or custom names for the Istio meta cluster ID and meta mesh ID. If this is the case, the `istio-proxy` container cannot deploy successfully. Continue with [Revisioned istiod and custom Istio meta mesh settings](#custom-istio-settings) to configure the `istio-proxy` container to use your custom values.
- {{< /callout >}}
-
-## Step 3: Update the Istio proxy settings {#custom-istio-settings}
-
-Create a GatewayParameters resource to configure the Istio SDS container to pull the image from the kgateway repository. The steps vary depending on the following scenarios:
-
-* Revisioned istiod deployment, such as `istiod-main`; **or** custom cluster or mesh IDs.
-* Revisionless Istio without custom cluster or mesh IDs.
-
-{{< tabs tabTotal="2" items="Revisioned Istio or custom cluster and mesh IDs,Revisionless Istio without custom IDs" >}}
-{{% tab tabName="Revisioned Istio or custom cluster and mesh IDs" %}}
-
-Create a GatewayParameters resource to configure the revisioned istiod service address and any custom values for the Istio meta cluster ID and meta mesh ID.
-
-1. Get the name of the istiod service. Depending on how you set up Istio, you might see a service name with a revision, such as `istiod-main`.
- ```sh
- kubectl get services -n istio-system
- ```
-
- Example output:
- ```
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- istiod-main ClusterIP 10.102.24.31 15010/TCP,15012/TCP,443/TCP,15014/TCP 3h49m
- ```
-
-2. Derive the Kubernetes service address for your istiod deployment. The service address uses the format `..svc:15012`. For example, if your service name is `istiod-main`, the full service address is `istiod-main.istio-system.svc:15012`.
-
-3. Create a GatewayParameters resource to configure the revisioned istiod service address and any custom values for the Istio meta cluster ID and meta mesh ID. **Note**: If you do not set custom values for the cluster ID and mesh ID, you can omit these values. Then, the default values of `Kubernetes` for the cluster ID and `cluster.local` for the mesh ID are used.
- ```yaml
- kubectl apply -f- <}}
- spec:
- kube:
- istio:
- istioProxyContainer:
- istioDiscoveryAddress: # such as istiod-main.istio-system.svc:15012
- istioMetaClusterId: ## such as the cluster name
- istioMetaMeshId: ## such as the cluster name
- sdsContainer:
- image:
- registry: cr.kgateway.dev/kgateway-dev
- repository: sds
- tag: v{{< reuse "agw-docs/versions/n-patch.md" >}}
- EOF
- ```
-{{% /tab %}}
-{{% tab tabName="Revisionless Istio without custom IDs" %}}
-Create a GatewayParameters resource to configure the Istio SDS container to pull the image from the kgateway repository.
-```yaml
-kubectl apply -f- <}}
-spec:
- kube:
- sdsContainer:
- image:
- registry: cr.kgateway.dev/kgateway-dev
- repository: sds
- tag: v{{< reuse "agw-docs/versions/n-patch.md" >}}
-EOF
-```
-{{% /tab %}}
-{{< /tabs >}}
-
-## Step 4: Create a gateway proxy {#create-gateway-proxy}
-
-Create or update a Gateway that includes the Istio proxy.
-
-1. Change the `http` gateway from the getting started tutorial to apply the custom settings of the GatewayParameters resource.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: custom-gw-params
- group: gateway.kgateway.dev
- kind: GatewayParameters
- listeners:
- - protocol: HTTP
- port: 8080
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-2. Verify that the gateway proxy is now successfully deployed.
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http \
- -o jsonpath='{range .items[*]}Pod: {.metadata.name} | Status: {.status.phase}{"\n"}Containers:{"\n"}{range .spec.containers[*]}- {.name}{"\n"}{end}{"\n"}{end}'
- ```
-
- Example output: Note that pod is running and has three containers, including the `istio-proxy`.
-
- ```
- Pod: http-f7c7f4b78-pwgnt | Status: Running
- Containers:
- - kgateway-proxy
- - sds
- - istio-proxy
- ```
-
- If you do not see the three containers, try restarting the proxy to apply the latest Gateway settings.
-
-## Step 5: Verify the integration {#verify}
-
-1. Create an HTTPRoute to route requests from the gateway proxy to the productpage app.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - istio-sidecar.example
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /productpage
- backendRefs:
- - name: productpage
- port: 9080
- EOF
- ```
-
-2. Send a request to the productpage app through the gateway. Verify that you get back a 200 HTTP response code. This response code proves that the gateway proxy can establish a mutual TLS connection to the productpage app.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -I http://$INGRESS_GW_ADDRESS:8080/productpage \
- -H "host: istio-sidecar.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -I http://localhost:8080/productpage \
- -H "host: istio-sidecar.example:8080"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- HTTP/1.1 200 OK
- content-type: text/html; charset=utf-8
- content-length: 4183
- server: envoy
- x-envoy-upstream-service-time: 29
- x-envoy-decorator-operation: productpage.bookinfo.svc.cluster.local:9080/*
- ```
-
-
-{{< callout type="info">}}
-To exclude a service from using Istio mTLS or to configure your own TLS settings, you can create a static Backend resource for the service and add the `kgateway.dev/disable-istio-auto-mtls` annotation to the Backend. Then, you can apply custom TLS settings by using a BackendTLSPolicy or BackendConfigPolicy.
-{{< /callout >}}
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the HTTPRoute and gateway-related resources.
- ```sh
- kubectl delete httproute bookinfo
- kubectl delete gatewayparameters custom-gw-params -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-2. Restore the http Gateway from the getting started tutorial.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "/agw-docs/snippets/gatewayclass.md" >}}
- listeners:
- - protocol: HTTP
- port: 8080
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-3. Get the Helm values for your current Helm installation and remove the values that you added in this guide.
- ```sh
- helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- ```
-
-4. Upgrade your Helm installation.
- ```sh
- helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "/agw-docs/versions/helm-version-flag.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -f {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}.yaml
- ```
-
-5. Follow the Istio documentation to [uninstall Istio](https://istio.io/latest/docs/setup/getting-started/#uninstall) and [remove the Bookinfo sample app](https://istio.io/latest/docs/examples/bookinfo/#cleanup).
-
diff --git a/assets/docs/pages/landing.md b/assets/docs/pages/landing.md
deleted file mode 100644
index 337803c25..000000000
--- a/assets/docs/pages/landing.md
+++ /dev/null
@@ -1,133 +0,0 @@
-{{< reuse "agw-docs/snippets/about-agw.md" >}}
-
-{{< callout type="info" >}}
-**New to agentgateway?** Get started in minutes with the [Quickstart guide]({{< link-hextra path="/quickstart/" >}})!
-{{< /callout >}}
-
-{{< reuse-image src="img/architecture.svg" caption="Figure: agentgateway works across compute environments to provide connectivity to various agentic tools, including MCP servers, agents, and OpenAPI endpoints." >}}
-
-## Why agentgateway?
-
-Traditional API gateways and reverse proxies aren't built for MCP and A2A, and adapting them isn't straightforward. These systems are optimized for **stateless REST-style interactions**—one request in, pick a backend, one response out—with no session context or ongoing connection state.
-
-MCP and A2A are fundamentally different:
-
-| Traditional API Gateway | Agentgateway |
-|------------------------|--------------|
-| Stateless request/response | **Stateful JSON-RPC sessions** with long-lived connections |
-| One request → one backend | **Session fan-out** across multiple MCP servers |
-| Client-initiated only | **Bidirectional**: servers can push events (SSE) to clients |
-| Simple routing by path/header | **Protocol-aware routing** that understands JSON-RPC message bodies |
-| Static backend mapping | **Dynamic tool virtualization** on a per-client basis |
-
-### Challenges traditional gateways can't solve
-
-- **Multiplexing & fan-out**: A single client request like "list available tools" needs to fan out across multiple backend MCP servers, aggregate responses, and return a unified result.
-- **Server-initiated events**: MCP servers can push real-time updates via Server-Sent Events (SSE) that must be properly routed back through the client session.
-- **Protocol negotiation**: Graceful handling of protocol upgrades and fallbacks as MCP/A2A specs evolve.
-- **Per-session authorization**: Different clients may have access to different tools, requiring dynamic adjustment of what gets exposed.
-- **Tool poisoning protection**: Defense against direct tampering, shadowing, and rug-pull attacks on tools.
-
-### Built for performance
-
-Agentgateway is built in **Rust** because performance and memory safety are non-negotiable for stateful, long-lived connections and fan-out patterns. Every millisecond and megabyte counts when managing concurrent sessions across multiple backend servers.
-
-## Features
-
-Agentgateway is a unified data plane for managing agent connectivity, built in Rust for high performance and reliability. It supports agent protocols including MCP and A2A, and provides a unified interface for LLM consumption.
-
-### LLM Gateway
-
-Route traffic to major LLM providers through a **unified OpenAI-compatible API**. Seamlessly switch between providers without changing your application code.
-
-| Provider | Chat Completions | Streaming |
-|----------|:----------------:|:---------:|
-| OpenAI / Azure OpenAI | ✅ | ✅ |
-| Anthropic | ✅ | ✅ |
-| Google Gemini | ✅ | ✅ |
-| Google Vertex AI | ✅ | ✅ |
-| Amazon Bedrock | ✅ | ✅ |
-
-#### OpenAI-compatible providers
-
-Don't see your provider? Many LLMs expose OpenAI-compatible APIs. Agentgateway can route to **any provider** that supports the OpenAI API format, including:
-
-- **Cohere**, **Mistral**, **Groq**, **Together AI**, **Fireworks**
-- **Ollama**, **LM Studio**, **vLLM**, **llama.cpp** (local models)
-- Any custom or self-hosted endpoint with OpenAI-compatible `/v1/chat/completions`
-
-#### Self-hosted models & Inference routing
-
-Running your own models on GPU infrastructure? Agentgateway implements the [Kubernetes Inference Gateway](https://gateway-api-inference-extension.sigs.k8s.io/) extensions for intelligent routing to local LLM workloads. Route based on:
-
-- **GPU & KV cache utilization** — Send requests to the least-loaded model
-- **Prompt criticality** — Prioritize high-priority requests
-- **LoRA adapters** — Route to models with specific fine-tuned adapters
-- **Work queue depth** — Avoid overloaded inference servers
-
-### MCP Gateway
-
-Connect LLMs to tools and external data sources using the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/). Agentgateway provides:
-
-- **Tool federation**: Aggregate multiple MCP servers behind a single endpoint
-- **Protocol support**: stdio, HTTP/SSE, and Streamable HTTP transports
-- **OpenAPI integration**: Expose existing REST APIs as MCP-native tools
-- **Authentication & authorization**: Built-in MCP auth spec compliance with OAuth providers (Auth0, Keycloak)
-
-### A2A Gateway
-
-Enable secure communication between AI agents using the [Agent-to-Agent (A2A)](https://github.com/a2aproject/A2A) protocol. Agents can:
-
-- Discover each other's capabilities
-- Negotiate interaction modalities (text, forms, media)
-- Collaborate on long-running tasks
-- Operate without exposing internal state or tools
-
-### Security & Observability
-
-- **Authentication**: JWT, API keys, basic auth, MCP auth spec
-- **Authorization**: Fine-grained RBAC with [Cedar policy engine](https://www.cedarpolicy.com/)
-- **Traffic policies**: Rate limiting, CORS, TLS, external authz
-- **Observability**: Built-in [OpenTelemetry](https://opentelemetry.io/) metrics, logs, and distributed tracing
-
-### Platform Agnostic
-
-Run agentgateway anywhere—bare metal, VMs, containers, or Kubernetes. Conformant to the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/) with support for HTTPRoute, GRPCRoute, TCPRoute, and TLSRoute.
-
-## Next steps
-
-{{< conditional-text include-if="local" >}}
-{{< cards >}}
- {{< card link="quickstart" title="Quickstart" >}}
- {{< card link="about" title="About" >}}
- {{< card link="deployment" title="Deployment" >}}
- {{< card link="configuration" title="Configuration" >}}
- {{< card link="tutorials" title="Tutorials" >}}
- {{< card link="llm" title="LLM consumption" >}}
- {{< card link="inference" title="Inference routing" >}}
- {{< card link="mcp" title="MCP connectivity" >}}
- {{< card link="agent" title="Agent connectivity" >}}
- {{< card link="integrations" title="Integrations" >}}
- {{< card link="reference" title="Reference" >}}
- {{< card link="faqs" title="FAQs" >}}
-{{< /cards >}}
-{{< /conditional-text >}}
-
-{{< conditional-text include-if="kubernetes" >}}
-{{< cards >}}
- {{< card link="quickstart" title="Get started" >}}
- {{< card link="about" title="About" >}}
- {{< card link="install" title="Installation" >}}
- {{< card link="setup" title="Gateway setup" >}}
- {{< card link="llm" title="LLM consumption" >}}
- {{< card link="inference" title="Inference routing" >}}
- {{< card link="mcp" title="MCP connectivity" >}}
- {{< card link="agent" title="Agent connectivity" >}}
- {{< card link="traffic-management" title="Traffic management" >}}
- {{< card link="security" title="Security" >}}
- {{< card link="configuration" title="Configuration" >}}
- {{< card link="observability" title="Observability" >}}
- {{< card link="operations" title="Operations" >}}
- {{< card link="reference" title="Reference" >}}
-{{< /cards >}}
-{{< /conditional-text >}}
diff --git a/assets/docs/pages/observability/control-plane-metrics.md b/assets/docs/pages/observability/control-plane-metrics.md
deleted file mode 100644
index 744a31a33..000000000
--- a/assets/docs/pages/observability/control-plane-metrics.md
+++ /dev/null
@@ -1,44 +0,0 @@
-By default, the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane exposes metrics in Prometheus format. You can use these metrics to monitor the health and performance of your gateway environment. For more information about how metrics are implemented, refer to the [kgateway project developer docs](https://github.com/kgateway-dev/kgateway/tree/main/devel/architecture/metrics.md).
-
-## View control plane metrics {#control-plane-metrics}
-
-The following steps show you how to quickly view the metrics endpoint of the control plane deployment. To integrate the metrics into your observability stack, see the [OpenTelemetry guide]({{< link-hextra path="/observability/otel-stack/" >}}).
-
-1. Port-forward the control plane deployment on port 9092.
-
- ```sh
- kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} port-forward deployment/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} 9092
- ```
-
-2. Open your browser to the metrics endpoint: [http://localhost:9092/metrics](http://localhost:9092/metrics).
-
- Example output:
-
- ```console
- # HELP kgateway_controller_reconciliations_total Total controller reconciliations
- # TYPE kgateway_controller_reconciliations_total counter
- kgateway_controller_reconciliations_total{controller="gateway",result="success"} 1
- kgateway_controller_reconciliations_total{controller="gatewayclass",result="success"} 2
- kgateway_controller_reconciliations_total{controller="gatewayclass-provisioner",result="success"} 2
- ```
-
-## Control plane metrics reference {#reference}
-
-Review the following table to understand more about each metric.
-
-Helpful terms:
-
-* Controller: A Kubernetes controller that reconciles resources as part of the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane deployment.
-
-* Resource: A Kubernetes object that is managed by a controller of the control plane.
-
-* Snapshot: A complete, point-in-time representation of the current state of resources that the controller builds and serves to a gateway proxy via the Envoy extensible Discovery Service (XDS) API.
-
-* Sync: The metrics refer to two kinds of syncs:
-
- * Status sync metrics represent the time it takes for you as a user to view the status that is reported on the resource.
- * Snapshot sync metrics roughly represent the time it takes for a resource change to become effective in the gateway proxies.
-
-* Transform: The process of the control plane converting high-level resources or intermediate representations (IR) into lower-level representations into the structure that the XDS API expects for a snapshot.
-
-{{< reuse "agw-docs/snippets/latest/metrics-control-plane.md" >}}
diff --git a/assets/docs/pages/observability/otel-stack.md b/assets/docs/pages/observability/otel-stack.md
deleted file mode 100644
index 40dc0362a..000000000
--- a/assets/docs/pages/observability/otel-stack.md
+++ /dev/null
@@ -1,418 +0,0 @@
-## Step 1: Install Grafana Loki and Tempo {#grafana}
-
-Grafana is a suite of open source tools that help you analyze, visualize, and monitor data in your cluster. For the OTel stack, you install the following Grafana components:
-
-* **Loki**: A log aggregation system that indexes metadata about your logs as a set of labels, not the actual log contents. This way, Loki is more cost-efficient and performant than traditional log aggregation systems.
- {{< callout type="tip" >}}
- Loki works best when you use structured logging in your applications, such as JSON format.
- {{< /callout >}}
-* **Tempo**: A distributed tracing system that stores trace data in object storage (like Amazon S3) and integrates seamlessly with Grafana for visualization. Distributed tracing helps you see how requests move through a microservices environment, which helps you identify performance bottlenecks, debug issues, and otherwise monitor your system's health to ensure SLA compliance.
-
-Steps to install:
-
-1. Deploy Grafana Loki to your cluster.
-
- ```yaml
- helm upgrade --install loki loki \
- --repo https://grafana.github.io/helm-charts \
- --version {{< reuse "agw-docs/versions/otel-stack-loki.md" >}} \
- --namespace telemetry \
- --create-namespace \
- --values - <}} \
- --namespace telemetry \
- --create-namespace \
- --values - <}} control plane and data plane gateway proxies. Then, the OTel collector exposes these metrics in Prometheus format so that other tools in your observability stack, such as Grafana, can in turn scrape the OTel collector and visualize the data.
-
-By using an OTel collector to aggregate metrics, you avoid having to configure each application individually to send their metrics to each backend observability tool. This setup simplifies your setup, lets you more easily change backends, improves reliability and debuggability, and lets you optimize preprocessing activities such as filtering, transforming, or enriching the metrics before scraping.
-
-You can deploy three separate OTel collectors that are optimized for the three different types of telemetry data: metrics, logs, and traces. This way, you can scale and optimize each collector based on your telemetry needs.
-
-{{< callout type="warning" >}}
-The example pipelines in all three OTel collectors set up the `debug` exporter. This exporter is useful for testing and validation purposes. However, for production scenarios, remove this exporter to avoid performance impacts.
-{{< /callout >}}
-
-1. Deploy the metrics collector to handle numerical measurements and time-series data. Note that you can also use the `promexporter` endpoint with Prometheus to scrape metrics from the collector pod, if you prefer the `pull` model to the `push` model.
-
- ```yaml
- helm upgrade --install opentelemetry-collector-metrics opentelemetry-collector \
- --repo https://open-telemetry.github.io/opentelemetry-helm-charts \
- --version {{< reuse "agw-docs/versions/otel-stack-collector.md" >}} \
- --set mode=deployment \
- --set image.repository="otel/opentelemetry-collector-contrib" \
- --set command.name="otelcol-contrib" \
- --namespace=telemetry \
- --create-namespace \
- -f -<}} \
- --set mode=deployment \
- --set image.repository="otel/opentelemetry-collector-contrib" \
- --set command.name="otelcol-contrib" \
- --namespace=telemetry \
- --create-namespace \
- -f -<}} \
- --set mode=deployment \
- --set image.repository="otel/opentelemetry-collector-contrib" \
- --set command.name="otelcol-contrib" \
- --namespace=telemetry \
- --create-namespace \
- -f -<}} \
- --namespace telemetry \
- --create-namespace \
- --values - <}} setup.
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} consists of the control plane and an {{< reuse "/agw-docs/snippets/data-plane.md" >}} data plane. If you experience issues in your environment, such as policies that are not applied or traffic that is not routed correctly, in a lot of cases, these errors can be observed at the proxy.
-
-## Debug the control plane {#control-plane}
-
-1. Enable port-forwarding on the control plane.
-
- ```sh
- kubectl port-forward deploy/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} 9095
- ```
-
-2. In your browser, open the admin server debugging interface: [http://localhost:9095/](http://localhost:9095/).
-
- {{< reuse-image src="img/admin-server-debug-ui.png" caption="Figure: Admin server debugging interface.">}}
- {{< reuse-image-dark srcDark="img/admin-server-debug-ui.png" caption="Figure: Admin server debugging interface.">}}
-
-3. Select one of the endpoints to continue debugging. {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- | Endpoint | Description |
- | -- | -- |
- | `/debug/pprof` | View the pprof profile of the control plane. A profile shows you the stack traces of the call sequences, such as Go routines, that led to particular events, such as memory allocation. The endpoint includes descriptions of each available profile.|
- | `/logging` | Review the current logging levels of each component in the control plane. You can also interactively set the log level by component, such as to enable `DEBUG` logs. |
- | `/snapshots/krt` | View the current krt snapshot, or the point-in-time view of the transformed Kubernetes resources and their sync status that the control plane processed. These resources are then used to generate gateway configuration that is sent to the gateway proxies for routing decisions. |
- | `/snapshots/xds` | The xDS snapshot is used for Envoy-based kgateway proxies, not agentgateway proxies. |
-
-## Debug your gateway setup
-
-{{< reuse "agw-docs/snippets/debug-gateway.md" >}}
-
-
-
-
diff --git a/assets/docs/pages/operations/uninstall.md b/assets/docs/pages/operations/uninstall.md
deleted file mode 100644
index 9724dbd8a..000000000
--- a/assets/docs/pages/operations/uninstall.md
+++ /dev/null
@@ -1,174 +0,0 @@
-If you no longer need your {{< reuse "/agw-docs/snippets/kgateway.md" >}} environment, you can uninstall the control plane and all gateway proxies. You can also optionally remove related components such as Prometheus and sample apps.
-
-## Uninstall
-
-Remove the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and gateway proxies.
-
-{{< callout type="info" >}}
-Did you use Argo CD to install {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Skip to the [Argo CD steps](#argocd).
-{{< /callout >}}
-
-1. Get all HTTP routes in your environment.
-
- ```sh
- kubectl get httproutes -A
- ```
-
-2. Remove each HTTP route.
-
- ```sh
- kubectl delete -n httproute
- ```
-
-3. Get all reference grants in your environment.
-
- ```sh
- kubectl get referencegrants -A
- ```
-
-4. Remove each reference grant.
-
- ```sh
- kubectl delete -n referencegrant
- ```
-
-5. Get all gateways in your environment that are configured by the `{{< reuse "/agw-docs/snippets/gatewayclass.md" >}}` gateway class.
-
- ```sh
- kubectl get gateways -A | grep {{< reuse "/agw-docs/snippets/gatewayclass.md" >}}
- ```
-
-6. Remove each gateway.
-
- ```sh
- kubectl delete -n gateway
- ```
-
-7. Uninstall the control plane.
-
- 1. Uninstall the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} Helm release.
-
- ```sh
- helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- 2. Delete the CRDs.
-
- ```sh
- helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- 3. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace.
-
- ```sh
- kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- 4. Confirm that the CRDs are deleted.
-
- ```sh
- kubectl get crds | grep {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}
- ```
-
-8. Remove the Kubernetes Gateway API CRDs. If you installed a different version or channel of the Kubernetes Gateway API, update the following command accordingly.
-
- ```sh
- kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml
- ```
-
-## Uninstall with ArgoCD {#argocd}
-
-For ArgoCD installations, use the following steps to clean up your environment.
-
-{{< tabs tabTotal="2" items="Argo CD UI,Argo CD CLI" >}}
-{{% tab tabName="Argo CD UI" %}}
-1. Port-forward the Argo CD server on port 9999.
- ```sh
- kubectl port-forward svc/argocd-server -n argocd 9999:443
- ```
-
-2. Open the [Argo CD UI](https://localhost:9999/applications).
-
-3. Log in with the `admin` username and `gateway` password.
-4. Find the application that you want to delete and click **x**.
-5. Select **Foreground** and click **Ok**.
-6. Verify that the pods were removed from the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace.
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```txt
- No resources found in {{< reuse "agw-docs/snippets/namespace.md" >}} namespace.
- ```
-
-6. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace.
- ```sh
- kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-7. Remove the `argocd` namespace.
- ```sh
- kubectl delete namespace argocd
- ```
-
-{{% /tab %}}
-{{% tab tabName="Argo CD CLI" %}}
-1. Port-forward the Argo CD server on port 9999.
- ```sh
- kubectl port-forward svc/argocd-server -n argocd 9999:443
- ```
-
-2. Log in to the Argo CD UI.
- ```sh
- argocd login localhost:9999 --username admin --password gateway --insecure
- ```
-
-3. Delete the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} application.
-
- ```sh
- argocd app delete {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm --cascade --server localhost:9999 --insecure
- ```
-
- Example output:
- ```txt
- Are you sure you want to delete '{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm' and all its resources? [y/n] y
- application '{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-helm' deleted
- ```
-
-4. Delete the {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} CRD application.
-
- ```sh
- argocd app delete {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm --cascade --server localhost:9999 --insecure
- ```
-
- Example output:
- ```txt
- Are you sure you want to delete '{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm' and all its resources? [y/n] y
- application '{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}-helm' deleted
- ```
-
-5. Verify that the pods were removed from the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace.
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
- Example output:
- ```txt
- No resources found in {{< reuse "agw-docs/snippets/namespace.md" >}} namespace.
- ```
-
-6. Remove the `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace.
- ```sh
- kubectl delete namespace {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-7. Remove the `argocd` namespace.
- ```sh
- kubectl delete namespace argocd
- ```
-
-{{% /tab %}}
-{{< /tabs >}}
-
-
diff --git a/assets/docs/pages/operations/upgrade.md b/assets/docs/pages/operations/upgrade.md
deleted file mode 100644
index 8a9259ddc..000000000
--- a/assets/docs/pages/operations/upgrade.md
+++ /dev/null
@@ -1,207 +0,0 @@
-You can use this guide to upgrade the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane and data plane components, or to apply changes to the components' configuration settings.
-
-
-
-
-
-
-{{< conditional-text include-if="envoy" >}}
-
- {{< tabs tabTotal="3" items="Kubernetes Gateway API, Kubernetes, Istio" >}}
-{{% tab tabName="Kubernetes Gateway API" %}}
-1. Decide on the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version that you want to use.
-
- * For help, review the [Upgrade Notes in the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} docs for each version](https://gateway-api.sigs.k8s.io/guides/#v12-upgrade-notes).
- * Check if you need to install the [experimental channel for the features that you want to use](../../reference/versions/#experimental-features).
-
-2. Install the custom resources of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} version that you want to upgrade to, such as the standard {{< reuse "agw-docs/versions/k8s-gw-version.md" >}} version.
-
- * Standard channel:
-
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/standard-install.yaml
- ```
-
- * Experimental channel: Note that some CRDs are prefixed with `X` to indicate that the entire CRD is experimental and subject to change.
-
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml
- ```
-
- Example output:
-
- ```txt
- customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
- customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
- ```
-
-3. Check the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} CRDs. Remove any outdated CRDs.
-
- ```sh
- kubectl get crds -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.versions[*].name}{"\t"}{.metadata.annotations.gateway\.networking\.k8s\.io/bundle-version}{"\t"}{.metadata.annotations.gateway\.networking\.k8s\.io/channel}{"\n"}{end}' | grep gateway.networking.k8s.io
- ```
-
- Example output:
-
- ```txt
- gatewayclasses.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental
- gateways.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental
- grpcroutes.gateway.networking.k8s.io v1 v1.2.0 experimental
- httproutes.gateway.networking.k8s.io v1 v1beta1 v1.2.0 experimental
- ```
-{{% /tab %}}
-{{% tab tabName="Kubernetes" %}}
-For Kubernetes upgrades, consult your cloud infrastructure provider.
-{{% /tab %}}
-{{% tab tabName="Istio" %}}
-For Istio upgrades, consult the docs based on the way that you installed Istio. Example providers:
-
-* [Upstream Istio](https://istio.io/latest/docs/setup/upgrade/)
-* [Gloo Operator](https://docs.solo.io/gloo-mesh-enterprise/latest/istio/operator/upgrade/)
-* [Gloo Mesh Helm](https://docs.solo.io/gloo-mesh-enterprise/latest/istio/manual/upgrade/)
-
-{{% /tab %}}
- {{< /tabs >}}
-
-{{< /conditional-text >}}
-
-
-
-
-## Upgrade {#upgrade-steps}
-
-1. Set the version you want to upgrade to in an environment variable, such as the latest patch version (`{{< reuse "agw-docs/versions/n-patch.md" >}}`) .
-
- ```sh
- export NEW_VERSION={{< reuse "agw-docs/versions/n-patch.md" >}}
- ```
-
-2. Apply the new CRDs for the control and data plane by using Helm.
-
- 1. **Optional**: To check the CRDs locally, download the CRDs to a `helm` directory.
-
- ```sh
- helm template --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} --output-dir ./helm
- ```
-
- 2. Upgrade the CRDs in your cluster:
-
- ```sh
- helm upgrade -i --namespace {{< reuse "agw-docs/snippets/namespace.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway-crds.md" >}}
- ```
-
-3. Make any changes to your Helm values.
-
- 1. Get the Helm values file for your current version.
-
- ```sh
- helm get values {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml > values.yaml
- open values.yaml
- ```
-
- 2. Compare your current Helm chart values with the version that you want to upgrade to.
-
- * **Show all values**:
-
- ```sh
- helm show values oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- ```
-
- * **Get a file with all values**: You can get a `{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml` file for the upgrade version by pulling and inspecting the Helm chart locally.
-
- ```sh
- helm pull oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- tar -xvf {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}-{{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}.tgz
- open {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}}/values.yaml
- ```
-
- 3. Make any changes that you want by editing your `values.yaml` Helm values file or preparing the `--set` flags. For development v{{< reuse "agw-docs/versions/patch-dev.md" >}} builds, include the `controller.image.pullPolicy=Always` setting or refer to the exact image digest to avoid using cached images.
-
-4. Upgrade the {{< reuse "agw-docs/snippets/kgateway.md" >}} control plane Helm installation.
- * Make sure to include your Helm values when you upgrade either as a configuration file or with `--set` flags. Otherwise, any previous custom values that you set might be overwritten.
- * When using the development build v{{< reuse "agw-docs/versions/patch-dev.md" >}}, add the `--set controller.image.pullPolicy=Always` option to ensure you get the latest image. Alternatively, you can specify the exact image digest.
- * To use experimental Gateway API features, include the experimental feature gate, `--set controller.extraEnv.KGW_ENABLE_GATEWAY_API_EXPERIMENTAL_FEATURES=true`.
-
- ```sh
- helm upgrade -i -n {{< reuse "agw-docs/snippets/namespace.md" >}} {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} oci://{{< reuse "/agw-docs/snippets/helm-path.md" >}}/charts/{{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} \
- -f values.yaml \
- --version {{< reuse "agw-docs/versions/helm-version-upgrade.md" >}}
- ```
-
-5. Verify that the control plane runs the upgraded version.
-
- ```sh
- kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} get pod -l app.kubernetes.io/name={{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -o jsonpath='{.items[0].spec.containers[0].image}'
- ```
-
- Example output:
- ```
- cr.{{< reuse "agw-docs/snippets/kgateway.md" >}}.dev/controller:{{< reuse "agw-docs/versions/n-patch.md" >}}
- ```
-
-6. Confirm that the control plane is up and running.
-
- ```sh
- kubectl get pods -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
diff --git a/assets/docs/pages/quickstart.md b/assets/docs/pages/quickstart.md
deleted file mode 100644
index 00c279afc..000000000
--- a/assets/docs/pages/quickstart.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Get started with {{< reuse "/agw-docs/snippets/kgateway.md" >}}. {{< reuse "agw-docs/snippets/kgateway-about.md" >}}
-
-## Before you begin
-
-These quick start steps assume that you have a Kubernetes cluster, `kubectl`, and `helm` already set up. For quick testing, you can use [Kind](https://kind.sigs.k8s.io/).
-
-```sh
-kind create cluster
-```
-
-## Install
-
-The following steps get you started with a basic installation. For detailed instructions, see the [installation guides]({{< link-hextra path="/install" >}}).
-
-{{< reuse "agw-docs/snippets/get-started.md" >}}
-
-Good job! You now have the {{< reuse "/agw-docs/snippets/kgateway.md" >}} control plane running in your cluster.
-
-## Next steps
-
-{{< icon "kgateway" >}} [Set up an API gateway with an httpbin sample app]({{< link-hextra path="/install/sample-app/" >}}). This guide uses the Envoy-based {{< reuse "/agw-docs/snippets/kgateway.md" >}} proxy to set up an API gateway. Then, deploy a sample httpbin app, configure a basic HTTP listener on the API gateway, and route traffic to httpbin by using an HTTPRoute resource.
-
-## Cleanup
-
-No longer need {{< reuse "/agw-docs/snippets/kgateway.md" >}}? Uninstall with the following command:
-
-```sh
-helm uninstall {{< reuse "/agw-docs/snippets/helm-kgateway.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
diff --git a/assets/docs/pages/reference/add-docs.md b/assets/docs/pages/reference/add-docs.md
deleted file mode 100644
index c47009509..000000000
--- a/assets/docs/pages/reference/add-docs.md
+++ /dev/null
@@ -1,257 +0,0 @@
-To contribute new documentation to kgateway, follow these steps:
-
-- Identify the audience and intended use for the content.
-- Choose the type of content you wish to contribute.
-- Decide on a name, location, and other front matter for your content
-- Write your contribution following the kgateway contribution guidelines.
-- Submit your contribution as a PR from your fork to the `kgateway-dev/kgateway.dev` GitHub repository.
-- Follow the review process until your contribution is merged.
-
-{{< callout type="info" >}}
-Looking to contribute code to kgateway? See the [contributing guide in the Community repo](https://github.com/kgateway-dev/community/blob/main/CONTRIBUTING.md).
-{{< /callout >}}
-
-## Audience and intended use {#audience}
-
-The best documentation starts by knowing the intended users, their knowledge, and what you expect them to do with the information. Otherwise, you cannot determine the appropriate scope and depth of information to provide, its ideal structure, or the necessary supporting information. The following examples show this principle in action:
-
-- The user needs to perform a specific task: Provide the set of steps that are required to accomplish the task.
-
-- The user must understand a concept before they can perform a task: Before the task, tell them about the prerequisite information or provide a link to it.
-
-- The user needs to make a decision: Provide the conceptual information necessary to know when to make the decision, the available options, and when to choose one option instead of the other.
-
-- The user needs to understand complex feature relationships: Provide a diagram showing the relationships, rather than writing multiple pages of content that is tedious to read and understand.
-
-After you identified your audience and the information that they need, select a suitable [content type](#content-type).
-
-
-## Content types {#content-types}
-When you understand the audience and the intended use for the content that you want to add, you can choose the content type that best addresses the needs of the audience. The following table shows the supported content types, their intended audiences, and the goals each type strives to achieve:
-
-|Content type | Goals | Audiences |
-| -- | -- | -- |
-|Concepts | Concepts explain key principles of kgateway, its functionality, features, and underlying technologies. For example, you might want to describe the external authentication flow in kgateway and how the components interact with each other. Concepts do not include sequences of steps. Instead, links might be provided to corresponding guides that explain how to set up and use the feature that you described in your concept. | New users or users that are unfamiliar with the project and the feature it provides. |
-| Guides | Guides provide the steps or procedure to accomplish a certain task. For example, you might want to write a guide for how to set up external authentication in kgateway. Guides give only minimal information about how the feature works, but can include links to related concepts. | Users that want to try out kgateway. |
-| Setup pages | Setup pages focus on steps for how to install, configure, and set up kgateway. | New or existing uses who want to install kgateway.
-| Reference pages| Reference pages provide detailed information about certain kgateway components, its CLI, Helm values, and API. Most reference content is automatically generated from the code. | Users with advanced and deep technical knowledge of the project. |
-| FAQs | FAQs provide quick answers to common questions about the kgateway project. Generally, the FAQs are not very technical in nature. Answers can link to existing guides, concepts, or other content types for users to learn more. | users with specific questions who are looking for brief answers and resources to learn more. |
-| Troubleshooting | Troubleshooting topics provide either general debugging guides or error-specific help. For general debugging, share a process that helps users find, analyze, and resolve the cause of an error. For error-specific topics, provide details on what is happening with example messages, why it's happening, and how to fix the issue. | Users who encounter an error and need to debug. |
-
-
-## File names {#file-names}
-
-All documentation in the kgateway project is written in markdown and built by using the static site generator Hugo. In Hugo, the name of the file or folder becomes part of the link to your page. Becaues, of that, it is important to carefully choose the name for the file or folder that you want to add. If the file name consists of multiple words, separate them by hyphens. For example, to add a topic about external authentication, your file name might be `ext-auth.md`. All file names must be lowercase. Keep file and folder names as short as possible to ensure easy cross-linking between topics.
-
-
-## Front matter {#front-matter}
-
-Each file must start with a front matter that includes the title and weight of the file. Pick a title for your topic that has the keywords you want search engines to find. The weight configures the placement of the page in relation to other pages in the same directory, and therefore determines the order in which files are displayed in the left-hand navigation.
-
-In the following example, the topic shows up as `External authentication` in the left-hand navigation.
-
-```
----
-title: External authentication
-weight: 20
----
-```
-
-If you want to add a folder or "twistie" to the left-hand navigation of the docs that has multipe sub-topics, the folder must have at least one `_index.md` file. This file has the title of your twistie and can be used to provide general overview information about the section that you want to add. Note that you must add additional pages to your folder for the twistie to show up in the left-hand navigation. If your folder contains only an `_index.md` file, it shows up as a regular page. The following example shows a sample folder structure:
-
-```
-|-- security
-|----- _index.md // provides conceptional security information
-|----- access-logging.md // guide for how to set up access logging
-|----- cors.md // guide for how to set up CORS
-|----- csrf.md // guide for how to set up CSRF
-```
-
-
-## Hugo shortcodes {#shortcodes}
-
-As mentioned earlier, the documentation in the kgateway project is built by using the static site generator Hugo. Hugo uses reusable templates, commonly referred to as shortcodes, to display, style, and render site elements, such as tables, videos, or cards and to manage the content for these elements more easily. Supported shortcodes can be found in the [kgateway project repo](https://github.com/kgateway-dev/kgateway.dev/tree/main/layouts/shortcodes) as well as the [Hextra Hugo theme](https://github.com/imfing/hextra/tree/main/exampleSite/content/docs/guide/shortcodes).
-
-Review common shortcodes that you find throughout the documentation:
-
-### link-hextra
-
-Use the link-hextra shortcode to link to a topic within the documentation in a way that is compatible with the versioning strategy.
-
-```markdown
-[AI Backend API docs]({{* link-hextra path="/reference/api/#aibackend" */>}})
-```
-
-### conditional-text
-
-Use the conditional-text shortcode to conditionally display content based on whether the page is in the `content/docs/envoy` or `content/docs/agentgateway` section. This is particularly useful when creating reusable content in the `assets/agw-docs` directory that needs to differ between Envoy-based kgateway and agentgateway documentation. The shortcode automatically detects the current section from the page URL and shows or hides content accordingly.
-
-The following example shows how to use conditional-text in an assets file that can be reused in both sections:
-
-Content in `assets/agw-docs/snippets/example-install.md`:
-```markdown
-{{* conditional-text include-if="envoy" */>}}
-Install kgateway using the Envoy-based proxy configuration.
-{{* /conditional-text */>}}
-{{* conditional-text include-if="agentgateway" */>}}
-Install kgateway using the agentgateway configuration.
-{{* /conditional-text */>}}
-```
-
-When this snippet is reused via `{{* reuse "agw-docs/snippets/example-install.md" */>}}`:
-- In pages under `docs/envoy/`, only the first paragraph is displayed.
-- In pages under `docs/agentgateway/`, only the second paragraph is displayed.
-
-Supported parameters:
-- `include-if`: Shows content only when the current section matches the specified value (e.g., `"envoy"`, `"agentgateway"`, or `"envoy,agentgateway"` for multiple sections)
-- `exclude-if`: Shows content only when the current section does not match the specified value
-
-### reuse
-You can use the reuse shortcode to reuse content in multiple places while maintaining a single source of truth. A common use case for this shortcode is a reference to the latest version, product names, or short paragraphs. The source of the reused content is stored as a markdown file in the `assets/agw-docs` directory.
-
-The following example shows the example syntax for using this shortcode:
-```markdown
-The guide includes steps to install {{* reuse "agw-docs/snippets/product-name.md" */>}} in three ways.
-```
-
-The content of `product-name.md` is as follows:
-```
-kgateway
-```
-
-The resulting content in the web page will be rendered as:
-```markdown
-The guide includes steps to install kgateway in three ways.
-```
-### reuse-image and reuse-image-dark {#reuse-image}
-
-Similar to the reuse shortcode, the reuse-image and reuse-image-dark shortcodes are used to display images in the documentation. Images are stored in the `assets/img` folder.
-
-{{< callout type="warning" >}}
-You must use both shortcodes together to display an image. This way, the image is displayed in both light and dark mode. If you do not have a different image file, still include both shortcodes with the same `src` image file.
-{{< /callout >}}
-
-The following example shows the example syntax for using this shortcode:
-
-```markdown
-{{* reuse-image src="img/translation-loop.svg" */>}}
-{{* reuse-image-dark srcDark="img/translation-loop-dark.svg" */>}}
-```
-
-To support different screen sizes, make sure to use images of type `.svg` only.
-
-
-### cards
-
-Use the cards shortcode to display a card in the documentation that links to a specific topic within or outside the documentation. You can read more about this shortcode [here](https://imfing.github.io/hextra/docs/guide/shortcodes/cards/).
-
-Example card:
-
-{{< cards >}}
-{{< card link="../../../quickstart" title="Get started" >}}
-{{< /cards >}}
-
-Shortcode syntax
-```markdown
-{{* cards */>}}
-{{* card link="../../../quickstart" title="Get started" */>}}
-{{* /cards */>}}
-```
-
-
-### callout
-
-A box that displays important information to the user. You can read more about this shortcode [here](https://imfing.github.io/hextra/docs/guide/shortcodes/callout/).
-
-Example callout:
-
-{{< callout type="info" >}}
-This is a sample callout of type info.
-{{< /callout >}}
-
-Shortcode syntax:
-```markdown
-{{* callout type="info" */>}}
-This is a sample callout of type info.
-{{* /callout */>}}
-```
-
-### version
-
-Use the version shortcode to conditionally display content based on the documentation version being viewed.
-
-Example:
-```markdown
-
-Content to show only for the specified 2.1.x version.
-
-
-```
-
-Supported parameters:
-- `include-if`: Shows content only when the current version matches the specified version
-- `exclude-if`: Shows content only when the current version does not match the specified version
-
-Available versions: Check the `hugo.yaml` file's `versions` section in the [kgateway.dev repository](https://github.com/kgateway-dev/kgateway.dev/blob/main/hugo.yaml#L129) for the current versions.
-
-### gloss
-
-Use the gloss shortcode to add inline glossary tooltips to terms in your documentation. When users hover over or click a glossary term, a tooltip displays the term's definition from the glossary data file.
-
-The shortcode takes a glossary key as the first argument and optionally accepts inner content for the displayed text. If no inner content is provided, the key itself is used as the display text.
-
-Example:
-
-```markdown
-The {{* gloss "API Gateway" */>}}API Gateway{{* /gloss */>}} manages traffic routing.
-
-You can also use it without inner content: {{* gloss "Control Plane" */>}}
-```
-
-The glossary definitions are stored in `data/glossary.yaml`. Each entry should have a `short` field (displayed in the tooltip) and optionally a link field for a "Learn more" link.
-
-## Redirects {#redirects}
-
-If you want to redirect a page to a new location, you can add a redirect rule to the [`static/_redirects` file in the `kgateway.dev` repository](https://github.com/kgateway-dev/kgateway.dev/blob/main/static/_redirects).
-
-The format is as follows. For more information, see the [Cloudflare documentation](https://developers.cloudflare.com/pages/configuration/redirects/).
-
-```
-
-```
-
-Example:
-
-```yaml
-/docs/mcp /docs/main/agentgateway 301
-```
-
-## Create a PR in GitHub {#pr}
-
-The kgateway documentation follows the standard GitHub collaboration flow for pull requests (PRs). This well-established collaboration model helps open source projects manage the following types of contributions:
-
-- Add new files to the repository.
-- Edit existing files.
-- Review the added or modified files.
-- Manage multiple release or development branches.
-
-The contribution guidelines assume you can complete the following tasks:
-
-- Fork the [kgateway docs repository](https://github.com/kgateway-dev/kgateway.dev/).
-- Create a branch for your changes.
-- Add commits to that branch.
-- Open a PR to share your contribution.
-
-## Review {#review}
-
-The documentation maintainers of the kgateway project will review your pull request to ensure the PR follows the documentation contribution guidelines. Once reviewed and approved by the maintainers, your PR is merged into the documentation codebase and your changes will show up on the documentation site.
-
-## Generated docs {#generated-docs}
-
-The kgateway project automatically generates the following documentation from the code.
-
-* [API reference]({{< link-hextra path="/reference/api/" >}})
-* [Helm reference]({{< link-hextra path="/reference/helm/" >}})
-* [Control plane metrics](../../../observability/control-plane-metrics/)
-
-To learn more about how to generate these docs, see the [GitHub Workflows README](https://github.com/kgateway-dev/kgateway.dev/tree/main/.github/workflows/README.md).
diff --git a/assets/docs/pages/reference/contribution/preview.md b/assets/docs/pages/reference/contribution/preview.md
deleted file mode 100644
index 642bd3f34..000000000
--- a/assets/docs/pages/reference/contribution/preview.md
+++ /dev/null
@@ -1,31 +0,0 @@
-The kgateway documentation is built by using the static site generator Hugo. As you write your content, you can locally preview your changes.
-
-## Before you begin
-
-1. Download and install the [`hugo` CLI](https://github.com/gohugoio/hugo/releases/tag/v0.135.0) version 0.135.0. Make sure to download the `extended` version to ensure all features are available that are required to build the site.
-
-2. Make sure that `hugo` is installed.
- ```sh
- hugo version
- ```
-
- Example output:
- ```
- hugo v0.135.0-f30603c47f5205e30ef83c70419f57d7eb7175ab+extended darwin/arm64 BuildDate=2024-09-27T13:17:08Z VendorInfo=gohugoio
- ```
-
-3. Install the Node.js dependencies. If you do not have Node.js and `npm` installed on your machine, follow the instructions [here](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) to install them.
- ```sh
- npm install
- ```
-
-4. Install the version of [Golang](https://go.dev/doc/install) used in `go.mod` and make sure `go` is in your `$PATH`.
-
-## Build the site locally
-
-1. Build the site locally.
- ```sh
- hugo server -D
- ```
-
-2. Open the site. The local preview is available at [localhost:1313](localhost:1313).
diff --git a/assets/docs/pages/reference/contribution/styleguide.md b/assets/docs/pages/reference/contribution/styleguide.md
deleted file mode 100644
index 8eac9e2ff..000000000
--- a/assets/docs/pages/reference/contribution/styleguide.md
+++ /dev/null
@@ -1,60 +0,0 @@
-All documentation contributions in kgateway must follow general standards to ensure content is clear, concise, and understandable.
-
-## Language
-
-All documentation content must be written in English. Currently, kgateway does not support other languages.
-
-## Sentence case
-
-Use sentence case for any content that you add. Sentence case means to capitalize the first word in a sentence and end with a punctuation mark like a period. Do not capitalize words, unless it is a product name, API, or other word that commonly is capatilized.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| Use the HTTPS protocol to send traffic. | Use the https protcol to send traffic.
-| Configure external authentication. | Configure External Authentication. |
-
-## Title case for titles
-
-Use title case for the value of `title:` in the front matter of your markdown page. Title case capitalizes the first letter in any word.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| Local rate limiting | Local Rate Limiting |
-| Shadowing | shadowing |
-
-## Simple, present tense
-
-Use simple, present tense throughout the content that you want to add. Avoid past and future tense, unless it is required to convery the correct information.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| Verify that the pod runs. | Verify that the pod is running. |
-| When you click this button, the UI opens. | When you click this button, the UI will open. |
-| To create the CORS policy, follow this example. | In order to create the CORS policy, look at the example below and follow its instructions. |
-
-## Active voice
-
-Make sure to use active voice where the subject of the sentence performs the action that is described by the verb.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| You can enhance the security of your gateway with CORS policies. | Security of your gateway can be enhanced with CORS policies. |
-| During an update, the management plane cannot update Envoy filters. | During an update, there are Envoy filters that it can't update |
-
-## "I" and "we"
-
-Avoid "I" and "we" in your content contribution. Instead, phrase sentences in the second-person or use the term user.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| In this topic, set up traffic shadowing.| In this topic, we will set up a traffic shadowing. |
-| With kgateway, you can set up advanced traffic routing. | We offer advanced traffic routing.|
-
-## Future statements
-
-Avoid making promises or giving hints about the future releases and features. If you want want to talk about a feature that is still under development, mark it as experimental or beta and use proper callout shortcodes to draw the user's attention to that information.
-
-| Do ✅ | Don't ❌ |
-| -- | -- |
-| `` | We plan to deliver a new routing feature in the next release. |
-
diff --git a/assets/docs/pages/reference/glossary.md b/assets/docs/pages/reference/glossary.md
deleted file mode 100644
index 7073976f7..000000000
--- a/assets/docs/pages/reference/glossary.md
+++ /dev/null
@@ -1,199 +0,0 @@
-Welcome to the kgateway glossary! This page breaks down the key terms for API gateways, AI, service mesh, Kubernetes, and other cloud-native words you'll find while using kgateway. Think of it as your quick reference hub whenever something feels unfamiliar.
-
-## How to use this glossary
-
-To get a clear picture of how kgateway works, you might find it helpful to explore related key terms.
-
-- **Just starting?** Begin with API Gateway → Backends → Routes → TrafficPolicy.
-- **Focusing on AI?** Explore Agentgateway → A2A → LLM Gateway → MCP.
-- **Working with service mesh?** Study ambient mesh → data plane → control plane → security.
-
-In this glossary, some terms come directly from the Kubernetes, Gateway API, or cloud-native open source ecosystem. These terms are marked with a chain-link icon (🔗) and link to the docs for the relevant project.
-
-Throughout the docs, terms that are defined in this glossary are underlined. When you hover over the term, the definition pops up for quick reference.
-
-### Still not finding what you need?
-
-If a term is missing:
-
-1. Try the search bar.
-2. Check examples in the tutorials.
-3. Visit the [API reference]({{< link-hextra path="/reference/api/" >}}).
-4. Remember that some terms come from general Kubernetes or cloud-native concepts.
-
-*This glossary grows alongside kgateway. If you notice a missing term, consider contributing to help others!*
-
-## A–C
-
-### A2A
-**Agent-to-Agent Protocol (A2A)**
-
-A secure, policy-driven communication method for AI agents running in an ambient mesh. It enables lightweight, sidecar-free interactions between agents.
-
-🔗 *See official documentation*: https://a2a-protocol.org/latest/
-
-### Agentgateway
-An open-source data plane optimized for agentic AI workloads. Kgateway uses agentgateway to route and manage traffic for LLMs, inference services, and AI-native applications.
-
-**Learn more**: [Agentgateway docs]({{< link-hextra path="/" >}})
-
-### Agents
-Autonomous AI components that make decisions, communicate with services, and interact with other agents (with or without sidecars). In Kgateway, agents participate in the mesh and communicate over A2A or Envoy-based traffic.
-
-### Ambient Mesh
-A service mesh architecture that removes the need for sidecars. Instead of injecting proxies into every pod, ambient mesh uses waypoint proxies and ztunnels to simplify operations and reduce overhead.
-
-🔗 *See official documentation*: https://ambientmesh.io/
-
-### API Gateway
-The central entry point for controlling, securing, and routing API traffic.
-
-In kgateway, two types of proxies can act as API Gateways:
-
-- The **Envoy-based Kgateway proxy** (traditional API and service mesh traffic)
-- **Agentgateway** (AI/LLM-specific traffic)
-
-{{< reuse "agw-docs/snippets/control-plane-note.md" >}}
-
-### Backends
-Destination services or endpoints that kgateway routes traffic to, such as Kubernetes Services, Lambdas, external hosts, or custom backends. These backends are connected to routes for forwarding traffic.
-
-**Learn more**: [Backend guides]({{< link-hextra path="/traffic-management/destination-types/backends/" >}})
-
-### Cluster (Kubernetes)
-A collection of Kubernetes nodes (control plane + workers) that run your workloads and host kgateway.
-
-### Cluster (Envoy)
-A logical group of upstream endpoints used by Envoy for load balancing. The Envoy-based kgateway data plane automatically generates Envoy clusters based on your Backends and route configuration.
-
-### Control Plane
-The system that configures and manages the data plane.
-In kgateway, the control plane distributes routing rules, policies, and extension configuration to the supported data plane proxies: the Envoy-based kgateway proxy and the agentgateway proxy.
-
-{{< reuse "agw-docs/snippets/control-plane-note.md" >}}
-
-### CRDs (Custom Resource Definitions)
-Extend the Kubernetes API with custom resource types.
-
-🔗 *See official documentation*: https://kubernetes.io/docs/reference/glossary/?all=true#term-custom-resource-definition
-
-## D–F
-
-### Data Plane
-The layer that actually processes live traffic. Kgateway supports the following data plane proxies:
-
-- Envoy-based Kgateway proxies
-- Agentgateway (for AI workloads)
-
-{{< reuse "agw-docs/snippets/control-plane-note.md" >}}
-
-### Delegation
-A way to share routing responsibility across teams or namespaces. A parent route delegates part of its routing logic to child routes, allowing flexible ownership.
-
-### DirectResponse
-A policy that allows the gateway to immediately return a response without forwarding traffic to a backend. Useful for maintenance pages, blocking traffic, or custom messages.
-
-### Egress
-Outbound traffic leaving the mesh or cluster. Egress gateways often apply policies such as access control, filtering, or auditing.
-
-### Envoy
-A high-performance L7 proxy used as the primary data plane for API and service mesh workloads when you create a Gateway from the `kgateway` GatewayClass.
-
-### External Authorization
-An Envoy extension that offloads authorization decisions to an external service. Kgateway can integrate with these systems to enforce access control.
-
-## G–L
-
-### Gateway
-A Gateway API resource that represents the instantiation of a gateway implementation.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.Gateway
-
-### GatewayClass
-Defines a class of Gateways with a shared configuration or implementation. Depending on how you install kgateway, you may have one or more GatewayClass resources created for you.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GatewayClass
-
-### Gateway Extension
-A kgateway resource that integrates extended services such as external authorization, rate limits, and processors into the Gateway data plane configuration.
-
-**Learn more**: [GatewayExtension API docs]({{< link-hextra path="/reference/api/#gatewayextension" >}})
-
-### GatewayParameters
-Configures template, deployment, and runtime settings for a Gateway instance (including Envoy proxy configuration).
-
-**Learn more**: [Gateway setup guides]({{< link-hextra path="/setup/default/" >}})
-
-### GRPCRoute
-A Gateway API resource for configuring gRPC routing rules.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.GRPCRoute
-
-### HTTPRoute
-A Gateway API resource for configuring HTTP/HTTPS routing rules.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.HTTPRoute
-
-### Inference Extension Project
-Mechanisms for running inference or AI processing in traffic flows—typically implemented as Envoy filters or external processors.
-
-🔗 *See official documentation*: https://gateway-api-inference-extension.sigs.k8s.io/
-
-### Lambda
-Serverless compute functions in Amazon Web Services (AWS) that kgateway can route traffic to via Backends.
-
-### Large Language Model (LLM)
-AI models trained on massive datasets to generate human-like text. Kgateway manages LLM traffic by using the agentgateway data plane.
-
-### LLM Gateway / AI Gateway
-A traffic-management pattern specialized for LLM, agent, MCP, and AI inference traffic. Agentgateway acts as the data plane for this pattern.
-
-## M–O
-
-### MCP (Model Context Protocol)
-A protocol for exchanging model context, metadata, and tool information between LLM gateways, tools, and agents.
-
-### Observability (Logging, Monitoring, Tracing)
-Systems that help you understand the behavior of your network traffic. You can integrate an OpenTelemetry-based observability solution into kgateway to get telemetry data for your traffic, including access logs, metrics, and distributed traces.
-
-## P–R
-
-### Proxy
-A data plane process (Envoy or agentgateway) that receives, processes, and forwards traffic based on kgateway configuration.
-
-**Learn more**: [Architecture docs]({{< link-hextra path="/about/architecture/" >}})
-
-### Rate Limiting
-Controls how many requests can reach your services over time. Often implemented via Gateway Extensions using Envoy rate-limit services.
-
-### ReferenceGrant
-A Gateway API resource that controls cross-namespace references.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.ReferenceGrant
-
-### Resiliency
-Techniques like retries, timeouts, and circuit breakers that make applications more reliable when failures occur.
-
-## S–Z
-
-### Security
-Authentication, authorization, and encryption settings that protect your traffic and data.
-
-### Service Mesh
-A network layer for service-to-service communication. Kgateway integrates with Istio and ambient mesh to support mesh-based traffic patterns.
-
-### TCPRoute
-A Gateway API resource for configuring TCP routing rules.
-
-🔗 *See official documentation*: https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.TCPRoute
-
-### Traffic Management
-Features that shape, route, or modify traffic, such as load balancing, matching, filtering, and transformations.
-
-### TrafficPolicy
-A kgateway resource that defines advanced traffic management settings, retries, timeouts, mirroring, security policies, and more.
-
-**Learn more**: [TrafficPolicy concept docs]({{< link-hextra path="/about/policies/trafficpolicy/" >}})
-
-### Translation
-The kgateway control plane process that converts Gateway API resources and CRDs into xDS configuration for enforcement in the Envoy-based kgateway or agentgateway data planes.
diff --git a/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md b/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md
deleted file mode 100644
index 11db01ee7..000000000
--- a/assets/docs/pages/reference/helm/2.2.x/agentgateway-crds.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-{{< callout type="info" >}}
-No configurable values are currently available for this chart.
-{{< /callout >}}
\ No newline at end of file
diff --git a/assets/docs/pages/reference/helm/2.2.x/agentgateway.md b/assets/docs/pages/reference/helm/2.2.x/agentgateway.md
deleted file mode 100644
index 75c5fd356..000000000
--- a/assets/docs/pages/reference/helm/2.2.x/agentgateway.md
+++ /dev/null
@@ -1,43 +0,0 @@
-
-## Values
-
-| Key | Type | Description | Default |
-|-----|------|-------------|---------|
-| affinity | object | Set affinity rules for pod scheduling, such as 'nodeAffinity:'. | `{}` |
-| controller | object | Configure the agentgateway control plane deployment. | `{"extraEnv":{},"image":{"pullPolicy":"","registry":"","repository":"controller","tag":""},"logLevel":"info","replicaCount":1,"service":{"ports":{"agwGrpc":9978,"health":9093,"metrics":9092},"type":"ClusterIP"},"strategy":{},"xds":{"tls":{"enabled":false}}}` |
-| controller.extraEnv | object | Add extra environment variables to the controller container. | `{}` |
-| controller.image | object | Configure the controller container image. | `{"pullPolicy":"","registry":"","repository":"controller","tag":""}` |
-| controller.image.pullPolicy | string | Set the image pull policy for the controller. | `""` |
-| controller.image.registry | string | Set the image registry for the controller. | `""` |
-| controller.image.repository | string | Set the image repository for the controller. | `"controller"` |
-| controller.image.tag | string | Set the image tag for the controller. | `""` |
-| controller.logLevel | string | Set the log level for the controller. | `"info"` |
-| controller.replicaCount | int | Set the number of controller pod replicas. | `1` |
-| controller.service | object | Configure the controller service. | `{"ports":{"agwGrpc":9978,"health":9093,"metrics":9092},"type":"ClusterIP"}` |
-| controller.service.ports | object | Set the service ports for gRPC and health endpoints. | `{"agwGrpc":9978,"health":9093,"metrics":9092}` |
-| controller.service.type | string | Set the service type for the controller. | `"ClusterIP"` |
-| controller.strategy | object | Change the rollout strategy from the Kubernetes default of a RollingUpdate with 25% maxUnavailable, 25% maxSurge. E.g., to recreate pods, minimizing resources for the rollout but causing downtime: strategy: type: Recreate E.g., to roll out as a RollingUpdate but with non-default parameters: strategy: type: RollingUpdate rollingUpdate: maxSurge: 100% | `{}` |
-| controller.xds | object | Configure TLS settings for the xDS gRPC servers. | `{"tls":{"enabled":false}}` |
-| controller.xds.tls.enabled | bool | Enable TLS encryption for xDS communication. When enabled, the agent gateway xDS server (port 9978) will use TLS. When TLS is enabled, you must create a Secret named 'agentgateway-xds-cert' in the agentgateway installation namespace. The Secret must be of type 'kubernetes.io/tls' with 'tls.crt', 'tls.key', and 'ca.crt' data fields present. | `false` |
-| deploymentAnnotations | object | Add annotations to the agentgateway deployment. | `{}` |
-| discoveryNamespaceSelectors | list | List of namespace selectors (OR'ed): each entry can use 'matchLabels' or 'matchExpressions' (AND'ed within each entry if used together). Agentgateway includes the selected namespaces in config discovery. For more information, see the docs https://kgateway.dev/docs/latest/install/advanced/#namespace-discovery. | `[]` |
-| fullnameOverride | string | Override the full name of resources created by the Helm chart, which is 'agentgateway'. If you set 'fullnameOverride: "foo", the full name of the resources that the Helm release creates become 'foo', such as the deployment, service, and service account for the agentgateway control plane in the agentgateway-system namespace. | `""` |
-| gatewayClassParametersRefs | object | Map of GatewayClass names to GatewayParameters references that will be set on the default GatewayClasses managed by kgateway. Each entry must define both the name and namespace of the GatewayParameters resource. The default GatewayClasses managed by kgateway are: - agentgateway Example: gatewayClassParametersRefs: agentgateway: name: shared-gwp namespace: kgateway-system | `{}` |
-| image | object | Configure the default container image for the components that Helm deploys. You can override these settings for each particular component in that component's section, such as 'controller.image' for the agentgateway control plane. If you use your own private registry, make sure to include the imagePullSecrets. | `{"pullPolicy":"IfNotPresent","registry":"cr.agentgateway.dev","tag":""}` |
-| image.pullPolicy | string | Set the default image pull policy. | `"IfNotPresent"` |
-| image.registry | string | Set the default image registry. | `"cr.agentgateway.dev"` |
-| image.tag | string | Set the default image tag. | `""` |
-| imagePullSecrets | list | Set a list of image pull secrets for Kubernetes to use when pulling container images from your own private registry instead of the default agentgateway registry. | `[]` |
-| inferenceExtension | object | Configure the integration with the Gateway API Inference Extension project, which lets you use agentgateway to route to AI inference workloads like LLMs that run locally in your Kubernetes cluster. Documentation for Inference Extension can be found here: https://kgateway.dev/docs/latest/agentgateway/inference/ | `{"enabled":false}` |
-| inferenceExtension.enabled | bool | Enable Inference Extension support in the agentgateway controller. | `false` |
-| nameOverride | string | Add a name to the default Helm base release, which is 'agentgateway'. If you set 'nameOverride: "foo", the name of the resources that the Helm release creates become 'agentgateway-foo', such as the deployment, service, and service account for the agentgateway control plane in the agentgateway-system namespace. | `""` |
-| nodeSelector | object | Set node selector labels for pod scheduling, such as 'kubernetes.io/arch: amd64'. | `{}` |
-| podAnnotations | object | Add annotations to the agentgateway pods. | `{"prometheus.io/scrape":"true"}` |
-| podSecurityContext | object | Set the pod-level security context. For example, 'fsGroup: 2000' sets the filesystem group to 2000. | `{}` |
-| resources | object | Configure resource requests and limits for the container, such as 'limits.cpu: 100m' or 'requests.memory: 128Mi'. | `{}` |
-| securityContext | object | Set the container-level security context, such as 'runAsNonRoot: true'. | `{}` |
-| serviceAccount | object | Configure the service account for the deployment. | `{"annotations":{},"create":true,"name":""}` |
-| serviceAccount.annotations | object | Add annotations to the service account. | `{}` |
-| serviceAccount.create | bool | Specify whether a service account should be created. | `true` |
-| serviceAccount.name | string | Set the name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` |
-| tolerations | list | Set tolerations for pod scheduling, such as 'key: "nvidia.com/gpu"'. | `[]` |
diff --git a/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md b/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md
deleted file mode 100644
index 11db01ee7..000000000
--- a/assets/docs/pages/reference/helm/2.2.x/kgateway-crds.md
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-{{< callout type="info" >}}
-No configurable values are currently available for this chart.
-{{< /callout >}}
\ No newline at end of file
diff --git a/assets/docs/pages/reference/helm/2.2.x/kgateway.md b/assets/docs/pages/reference/helm/2.2.x/kgateway.md
deleted file mode 100644
index 865128ff5..000000000
--- a/assets/docs/pages/reference/helm/2.2.x/kgateway.md
+++ /dev/null
@@ -1,47 +0,0 @@
-
-## Values
-
-| Key | Type | Description | Default |
-|-----|------|-------------|---------|
-| affinity | object | Set affinity rules for pod scheduling, such as 'nodeAffinity:'. | `{}` |
-| controller | object | Configure the kgateway control plane deployment. | `{"extraEnv":{},"image":{"pullPolicy":"","registry":"","repository":"kgateway","tag":""},"logLevel":"info","replicaCount":1,"service":{"ports":{"grpc":9977,"health":9093,"metrics":9092},"type":"ClusterIP"},"strategy":{},"xds":{"tls":{"enabled":false}}}` |
-| controller.extraEnv | object | Add extra environment variables to the controller container. | `{}` |
-| controller.image | object | Configure the controller container image. | `{"pullPolicy":"","registry":"","repository":"kgateway","tag":""}` |
-| controller.image.pullPolicy | string | Set the image pull policy for the controller. | `""` |
-| controller.image.registry | string | Set the image registry for the controller. | `""` |
-| controller.image.repository | string | Set the image repository for the controller. | `"kgateway"` |
-| controller.image.tag | string | Set the image tag for the controller. | `""` |
-| controller.logLevel | string | Set the log level for the controller. | `"info"` |
-| controller.replicaCount | int | Set the number of controller pod replicas. | `1` |
-| controller.service | object | Configure the controller service. | `{"ports":{"grpc":9977,"health":9093,"metrics":9092},"type":"ClusterIP"}` |
-| controller.service.ports | object | Set the service ports for gRPC and health endpoints. | `{"grpc":9977,"health":9093,"metrics":9092}` |
-| controller.service.type | string | Set the service type for the controller. | `"ClusterIP"` |
-| controller.strategy | object | Change the rollout strategy from the Kubernetes default of a RollingUpdate with 25% maxUnavailable, 25% maxSurge. E.g., to recreate pods, minimizing resources for the rollout but causing downtime: strategy: type: Recreate E.g., to roll out as a RollingUpdate but with non-default parameters: strategy: type: RollingUpdate rollingUpdate: maxSurge: 100% | `{}` |
-| controller.xds | object | Configure TLS settings for the xDS gRPC servers. | `{"tls":{"enabled":false}}` |
-| controller.xds.tls.enabled | bool | Enable TLS encryption for xDS communication. When enabled, both the main xDS server (port 9977) and agent gateway xDS server (port 9978) will use TLS. When TLS is enabled, you must create a Secret named 'kgateway-xds-cert' in the kgateway installation namespace. The Secret must be of type 'kubernetes.io/tls' with 'tls.crt', 'tls.key', and 'ca.crt' data fields present. | `false` |
-| deploymentAnnotations | object | Add annotations to the kgateway deployment. | `{}` |
-| discoveryNamespaceSelectors | list | List of namespace selectors (OR'ed): each entry can use 'matchLabels' or 'matchExpressions' (AND'ed within each entry if used together). Kgateway includes the selected namespaces in config discovery. For more information, see the docs https://kgateway.dev/docs/latest/install/advanced/#namespace-discovery. | `[]` |
-| fullnameOverride | string | Override the full name of resources created by the Helm chart, which is 'kgateway'. If you set 'fullnameOverride: "foo", the full name of the resources that the Helm release creates become 'foo', such as the deployment, service, and service account for the kgateway control plane in the kgateway-system namespace. | `""` |
-| gatewayClassParametersRefs | object | Map of GatewayClass names to GatewayParameters references that will be set on the default GatewayClasses managed by kgateway. Each entry must define both the name and namespace of the GatewayParameters resource. The default GatewayClasses managed by kgateway are: - kgateway - kgateway-waypoint Example: gatewayClassParametersRefs: kgateway: name: shared-gwp namespace: kgateway-system | `{}` |
-| image | object | Configure the default container image for the components that Helm deploys. You can override these settings for each particular component in that component's section, such as 'controller.image' for the kgateway control plane. If you use your own private registry, make sure to include the imagePullSecrets. | `{"pullPolicy":"IfNotPresent","registry":"cr.kgateway.dev/kgateway-dev","tag":""}` |
-| image.pullPolicy | string | Set the default image pull policy. | `"IfNotPresent"` |
-| image.registry | string | Set the default image registry. | `"cr.kgateway.dev/kgateway-dev"` |
-| image.tag | string | Set the default image tag. | `""` |
-| imagePullSecrets | list | Set a list of image pull secrets for Kubernetes to use when pulling container images from your own private registry instead of the default kgateway registry. | `[]` |
-| inferenceExtension | object | Configure the integration with the Gateway API Inference Extension project, which lets you use kgateway to route to AI inference workloads like LLMs that run locally in your Kubernetes cluster. Documentation for Inference Extension can be found here: https://kgateway.dev/docs/latest/agentgateway/inference/ | `{"enabled":false}` |
-| inferenceExtension.enabled | bool | Enable Inference Extension. If enabled, agentgateway.enabled should also be set to true. Enabling inference extension without agentgateway is deprecated in v2.1 and will not be supported in v2.2. | `false` |
-| nameOverride | string | Add a name to the default Helm base release, which is 'kgateway'. If you set 'nameOverride: "foo", the name of the resources that the Helm release creates become 'kgateway-foo', such as the deployment, service, and service account for the kgateway control plane in the kgateway-system namespace. | `""` |
-| nodeSelector | object | Set node selector labels for pod scheduling, such as 'kubernetes.io/arch: amd64'. | `{}` |
-| podAnnotations | object | Add annotations to the kgateway pods. | `{"prometheus.io/scrape":"true"}` |
-| podSecurityContext | object | Set the pod-level security context. For example, 'fsGroup: 2000' sets the filesystem group to 2000. | `{}` |
-| policyMerge | object | Policy merging settings. Currently, TrafficPolicy's extAuth, extProc, and transformation policies support deep merging. E.g., to enable deep merging of extProc policy in TrafficPolicy: policyMerge: trafficPolicy: extProc: DeepMerge | `{}` |
-| resources | object | Configure resource requests and limits for the container, such as 'limits.cpu: 100m' or 'requests.memory: 128Mi'. | `{}` |
-| securityContext | object | Set the container-level security context, such as 'runAsNonRoot: true'. | `{}` |
-| serviceAccount | object | Configure the service account for the deployment. | `{"annotations":{},"create":true,"name":""}` |
-| serviceAccount.annotations | object | Add annotations to the service account. | `{}` |
-| serviceAccount.create | bool | Specify whether a service account should be created. | `true` |
-| serviceAccount.name | string | Set the name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` |
-| tolerations | list | Set tolerations for pod scheduling, such as 'key: "nvidia.com/gpu"'. | `[]` |
-| validation | object | Configure validation behavior for route and policy safety checks in the control plane. This setting determines how invalid configuration is handled to prevent security bypasses and to maintain multi-tenant isolation. | `{"level":"standard"}` |
-| validation.level | string | Validation level. Accepted values: "standard" or "strict" (case-insensitive). Standard replaces invalid routes with a direct 500 response and continues applying valid configuration. Strict adds xDS preflight validation and blocks snapshots that would NACK in Envoy. Default is "standard". | `"standard"` |
-| waypoint | object | Enable the waypoint integration. This enables kgateway to translate istio waypoints and use kgateway as a waypoint in an Istio Ambient service mesh setup. | `{"enabled":false}` |
diff --git a/assets/docs/pages/reference/ports.md b/assets/docs/pages/reference/ports.md
deleted file mode 100644
index 33d6d6894..000000000
--- a/assets/docs/pages/reference/ports.md
+++ /dev/null
@@ -1,63 +0,0 @@
-Review the ports that are used by kgateway.
-
-Kgateway deploys containers that listen on certain ports for incoming traffic. In the following sections, you can review the pods and services that make up kgateway, and the ports that these pods and services listen on.
-
-
-
-
-## Installation
-
-The {{< reuse "agw-docs/snippets/kgateway.md" >}} installation process uses a Helm chart to create the necessary custom resource definitions (CRDs), deployments, services, pods, etc. The services and pods listen on specific ports to enable communication between the components that make up {{< reuse "agw-docs/snippets/kgateway.md" >}}.
-
-## Components
-
-A standard installation of {{< reuse "agw-docs/snippets/kgateway.md" >}} includes the following components:
-
-* **{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} control plane**
- * Creates an Envoy configuration from multiple custom resources.
- * Serves Envoy configurations using xDS.
- * Validates Proxy configurations for the gateway proxy.
-* **{{< reuse "agw-docs/snippets/kgateway-capital.md" >}} data plane (gateway proxy)**
- * Receives and loads configuration from kgateway xDS.
- * Proxies incoming traffic.
-
-## Pods and ports
-
-The components are instantiated by using pods and services. The following table lists the deployed pods and ports in use by each pod.
-
-
-### Control plane ports
-
-| Pod | Port | Usage |
-|-----|------|-------|
-| {{< reuse "agw-docs/snippets/pod-name.md" >}} | 9976 | REST xDS |
-| {{< reuse "agw-docs/snippets/pod-name.md" >}} | 9977 | xDS Server |
-
-### Gateway proxy ports
-
-{{< reuse "agw-docs/snippets/reserved-ports.md" >}}
-
-
-
-
-
diff --git a/assets/docs/pages/reference/versions.md b/assets/docs/pages/reference/versions.md
deleted file mode 100644
index 5aa53aa62..000000000
--- a/assets/docs/pages/reference/versions.md
+++ /dev/null
@@ -1,72 +0,0 @@
-Review the following information about supported release versions for agentgateway. Agentgateway on Kubernetes runs with the [kgateway project](https://github.com/kgateway-dev/kgateway) control plane.
-
-## Supported versions
-
-| Kgateway | Release date | Kubernetes | Gateway API`*` | Envoy | Helm | Istio`†` |
-|----------|--------------|------------|----------------|-------|------|----------|
-| 2.2.x | 09 Feb 2026 | 1.31 - 1.35 | 1.4.x | Proxy 1.35, API v3 | >= 3.12 | 1.23 - 1.27 |
-| 2.1.x | 10 Oct 2025 | 1.31 - 1.34 | 1.4.x | Proxy 1.35, API v3 | >= 3.12 | 1.23 - 1.27 |
-| 2.0.x | 01 Apr 2025 | 1.27 - 1.31 | 1.2.x | Proxy 1.33, API v3 | >= 3.12 | 1.18 - 1.23 |
-
-
-
-`*` Gateway API versions: The agentgateway project is conformant to the Kubernetes Gateway API specification. For more details, see the [Gateway API docs](https://gateway-api.sigs.k8s.io/implementations/#agent-gateway-with-kgateway) and agentgateway conformance report per version, such as Gateway API [v1.4.0](https://github.com/kubernetes-sigs/gateway-api/tree/main/conformance/reports/v1.4.0/agentgateway-agentgateway).
-
-`†` Istio versions: Istio must run on a compatible version of Kubernetes. For example, Istio 1.27 is tested, but not supported, on Kubernetes 1.28. For more information, see the [Istio docs](https://istio.io/latest/docs/releases/supported-releases/).
-
-
-
-## Release cadence {#cadence}
-
-Stable builds for agentgateway on Kubernetes are released as minor versions approximately every three months. A stable branch for a minor version, such as {{< reuse "agw-docs/versions/short.md" >}}, is tagged from `main`, and stable builds are supported from that branch.
-
-## Release development {#release}
-
-New features for agentgateway are developed on `main` and available as development builds. Stable branches are created off of `main` for each minor version, such as `v2.0.x`.
-
-### Release process {#release-process}
-
-Development of a quality stable release on `main` typically follows this process:
-
-1. New feature development is suspended on `main`.
-2. Release candidates are created, such as `{{< reuse "agw-docs/versions/short.md" >}}.0-rc1`, `{{< reuse "agw-docs/versions/short.md" >}}.0-rc2`, and so on.
-3. A full suite of tests is performed for each release candidate. Testing includes all documented workflows, a test matrix of all supported platforms, and more.
-4. Documentation for that release is prepared, vetted, and staged.
-5. The stable minor version is released as part of a stable branch, such as `v2.0.x`.
-6. Feature development on `main` is resumed.
-
-### Feature development on main branch {#release-main}
-
-Feature development is performed on the `main` branch. Upon a merge to `main`, a development build is automatically released. The current development release is `{{< reuse "agw-docs/versions/patch-dev.md" >}}`.
-
-{{< callout type="warning" >}}
-Development releases are unstable, subject to change, and not recommended for production usage.
-{{< /callout >}}
-
-### Backports to stable branches {#release-backport}
-
-New features are not developed on or backported to stable branches, such as `v2.0.x`. However, critical patches, bug fixes, and documentation fixes are backported as needed.
-
-## Experimental features in Gateway API {#experimental-features}
-
-{{< reuse "agw-docs/snippets/k8sgwapi-exp.md" >}}
diff --git a/assets/docs/pages/reference/vulnerabilities.md b/assets/docs/pages/reference/vulnerabilities.md
deleted file mode 100644
index b878f4e1d..000000000
--- a/assets/docs/pages/reference/vulnerabilities.md
+++ /dev/null
@@ -1,90 +0,0 @@
-Review how the kgateway project handles the lifecycle of Common Vulnerability and Exposures (CVEs).
-
-## Reports
-
-The kgateway project appreciates the efforts of our users in helping us to discover and resolve security vulnerabilities. The following sources are used to determine product exposure to CVEs:
-
-* The kgateway team scans kgateway components to detect vulnerabilities.
-* The kgateway team participates in early disclosure and security workgroups of multiple backend communities.
-* Users may share output from their own security scanning tools for analysis and response from the kgateway team.
-
-### 📨 Where to report
-
-To report a security vulnerability, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`.
-
-### ✅ When to send a report
-
-Send a report when:
-
-* You discover that a kgateway component has a potential security vulnerability.
-* You are unsure whether or how a vulnerability affects kgateway.
-
-### 🔔 Check before sending
-
-If in doubt, send a private message about potential vulnerabilities such as:
-
-* Any crash, especially in Envoy.
-* Any potential Denial of Service (DoS) attack.
-
-### ❌ When NOT to send a report
-
-Do not send a report for vulnerabilities that are not part of the kgateway project, such as:
-
-* You want help configuring kgateway components for security purposes.
-* You want help applying security related updates to your kgateway configuration or environment.
-* Your issue is not related to security vulnerabilities.
-* Your issue is related to base image dependencies, such as Envoy.
-
-## Evaluation
-
-The kgateway team evaluates vulnerability reports for:
-
-* Severity level, which can affect the priority of the fix
-* Impact of the vulnerability on kgateway code as opposed to backend code
-* Potential dependencies on third-party or backend code that might delay the remediation process
-
-The kgateway team strives to keep private any vulnerability information with us as part of the remediation process. We only share information on a need-to-know basis to address the issue.
-
-## Remediation
-
-Remediation of a CVE involves introducing a fix to the affected code and releasing the associated component. This development process might happen in private GitHub repositories to keep information secure and prevent broader exploitation of the vulnerability.
-
-## Disclosures
-
-The kgateway team discloses remediated vulnerabilities publicly. Additionally, you can join an early disclosure group to help address vulnerabilities earlier in the remediation process.
-
-### Public disclosure
-
-On the day for the remediation to be disclosed, the kgateway team takes steps that might include the following:
-
-* Merge changes from any private repositories into the public codebase
-* Share security scan results for product images
-* Publish a release and any corresponding documentation for mitigating the vulnerability
-* Announce the remediated vulnerability in a public channel such as email or Slack
-
-### Early disclosure
-
-You can join a distribution list to get early disclosures of security vulnerability. This way, you can take action earlier in the process to help remediate the vulnerability and mitigate its effects in your environments.
-
-To request membership in the early disclosure group, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`. In your request, indicate how you meet the following membership criteria.
-
-#### Membership criteria
-
-1. Contribute significantly to the kgateway project, such as by being a maintainer, release manager, or active feature developer.
-2. Use kgateway in a way that justifies early disclosure of security vulnerabilities, such as redistributing kgateway or providing kgateway to many users outside your own organization.
-3. Monitor the email that you provide for the early disclosure distribution list.
-4. Participate in and attend meetings of the security working group.
-5. Keep any information from the distribution list private and on a need-to-know basis. Information is only for purposes of remediating the vulnerability. If you share information beyond the scope of this policy, you must notify the distribution list, including details of what information was shared when and to whom, so the kgateway team can assess how to proceed.
-
-#### Membership removal
-
-You must actively meet the membership criteria to remain part of the early disclosure distribution list. If your organization stops meeting one or more of these criteria, you can be removed from the distribution list.
-
-#### Other membership notes
-
-Membership in the [Envoy security group](https://github.com/envoyproxy/envoy/blob/main/SECURITY.md#security-reporting-process) is a separate process. Because kgateway integrates closely with the Envoy project, you might also consider joining the Envoy early disclosure group. Even if not, you are still expected to abide by their embargo policy when a kgateway vulnerability relates to the Envoy project.
-
-## Updates and questions
-
-The kgateway team reserves the right to change this process. The kgateway team's security processes are reviewed regularly to ensure compliance with industry standards and the current security landscape. For questions or additional details, email the private Google group `kgateway-vulnerability-reports@googlegroups.com`.
-
diff --git a/assets/docs/pages/resiliency/circuit-breakers.md b/assets/docs/pages/resiliency/circuit-breakers.md
deleted file mode 100644
index 6f43a656e..000000000
--- a/assets/docs/pages/resiliency/circuit-breakers.md
+++ /dev/null
@@ -1,81 +0,0 @@
-Set up protective limits on your gateway proxy to prevent your proxy from overwhelming slow or unhealthy upstream services.
-
-## About circuit breakers
-
-With circuit breakers, you can cap resources, such as the number of active connections, pending requests, concurrent requests, and retries, allowing Envoy to fail fast instead of letting queues grow unbounded. By shedding excess load early, circuit breakers help contain cascading failures, reduce latency under stress, and give upstream services time to recover, making them a key building block for resilient, self-protecting service meshes and gateways.
-
-For more information, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/upstream/circuit_breaking).
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-
-## Setup
-
-1. Create a BackendConfigPolicy that configures limits for the number of requests, connections, and retries for the httpbin app.
- ```yaml
- kubectl apply -f- <}}
-
-```sh
-kubectl delete backendconfigpolicy httpbin-circuit-breakers -n httpbin
-```
-
diff --git a/assets/docs/pages/resiliency/connection.md b/assets/docs/pages/resiliency/connection.md
deleted file mode 100644
index eef177c2d..000000000
--- a/assets/docs/pages/resiliency/connection.md
+++ /dev/null
@@ -1,186 +0,0 @@
-Configure and manage HTTP connections to an upstream service.
-
-## Supported HTTP connection settings
-
-You can use a BackendConfigPolicy to apply HTTP connection settings to a service in your cluster. These settings include general settings, such as connection timeouts or the maximum number of connections that an upstream service can receive. You can also configure settings for HTTP/2 and HTTP/1 requests.
-
-* [General connection settings](#general-settings)
-* [HTTP protocol options](#http)
-* [Additional HTTP 1.0 protocol options](#http1)
-
-### General connection settings {#general-settings}
-
-Configure the timeout and read/write buffer limits for a connection.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy
- namespace: gwtest
-spec:
- targetRefs:
- - name: httpbin
- group: ""
- kind: Service
- connectTimeout: 5s
- perConnectionBufferLimitBytes: 1024
-```
-
-| Setting | Description |
-| -- | -- |
-| `connectTimeout` | The timeout for new network connections to an upstream service. |
-| `perConnectionBufferLimitBytes` | Set the size of the read and write buffer per connection. By default, the gateway has a maximum of 1MiB for the read and write buffer for each connection. For large requests that must be buffered and that exceed the default buffer limit, the gateway proxy either disconnects the connection to the downstream service if headers were already sent, or returns a 500 HTTP response code. To make sure that large requests can be sent and received, you can specify the maximum number of bytes that you want to allow to be buffered between the gateway and the downstream service. |
-
-### HTTP protocol options {#http}
-
-You can use a BackendConfigPolicy to configure additional connection options when handling upstream HTTP requests. Note that these options are applied to HTTP/1 and HTTP/2 requests.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy
- namespace: gwtest
-spec:
- targetRefs:
- - name: httpbin
- group: ""
- kind: Service
- commonHttpProtocolOptions:
- idleTimeout: 10s
- maxHeadersCount: 15
- maxStreamDuration: 30s
- maxRequestsPerConnection: 100
-```
-
-| Setting | Description |
-| -- | -- |
-| `idleTimeout` | The idle timeout for connections. The idle timeout is defined as the period in which there are no active requests. When the idle timeout is reached, the connection is closed. Note that request-based timeouts mean that HTTP/2 PINGs do not keep the connection alive. If not specified, the idle timeout defaults to 1 hour. To disable idle timeouts, explicitly set this field to 0. **Warning**: Disabling the timeout has a highly likelihood of yielding connection leaks, such as due to lost TCP FIN packets.|
-| `maxHeadersCount` | The maximum number of headers that can be sent in a connection. If not specified, the number defaults to 100. Requests that exceed this limit receive a 431 response for HTTP/1 and cause a stream reset for HTTP/2. |
-| `maxStreamDuration` | The total duration to keep alive an HTTP request/response stream. If the time limit is reached, the stream is reset independent of any other timeouts. If not specified, this value is not set. |
-| `maxRequestsPerConnection` | The maximum number of requests that can be sent per connection. |
-
-
-#### Additional HTTP 1.0 protocol options {#http1}
-
-The BackendConfigPolicy allows you to apply additional configuration to HTTP/1 connections.
-
-```yaml
-kind: BackendConfigPolicy
-apiVersion: gateway.kgateway.dev/v1alpha1
-metadata:
- name: httpbin-policy
- namespace: gwtest
-spec:
- targetRefs:
- - name: httpbin
- group: ""
- kind: Service
- http1ProtocolOptions:
- enableTrailers: true
- overrideStreamErrorOnInvalidHttpMessage: true
- preserveHttp1HeaderCase: true
-```
-
-| Setting | Description |
-| -- | -- |
-| `enableTrailers` | Enables trailers for HTTP/1 requests. Trailers are headers that are sent after the request body is sent. By default, the HTTP/1 codec drops proxied trailers. |
-| `overrideStreamErrorOnInvalidHttpMessage` | When set to false, the proxy terminates HTTP/1.1 connections when an invalid HTTP message is received, such as malformatted headers. When set to true, the proxy leaves the HTTP/1.1 connection open where possible. |
-| `headerFormat` | By default, the proxy normalizes header keys to lowercase. Set to `PreserveCaseHeaderKeyFormat` to preserve the original casing after the request is proxied. Set to `properCaseHeaderKeyFormat` to capitalize the first character and any character following a special character if it's an alpha character. For example, `content-type` becomes `Content-Type`, and `foo$b#$are` becomes `Foo$B#$Are`. |
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Configure backend connections
-
-1. Create a BackendConfigPolicy that applies connection configuration to the httpbin app.
- ```yaml
- kubectl apply -f- <}} 19000
- ```
-
-3. Get the configuration of your gateway proxy as a config dump.
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
-4. Open the config dump and find the `kube_httpbin_httpbin_8000` cluster. Verify that you see all the connection settings that you enabled in your BackendConfigPolicy.
-
- Example output
- ```console
- ...
- "connect_timeout": "5s",
- "per_connection_buffer_limit_bytes": 1024,
- "metadata": {},
- "upstream_connection_options": {
- },
- "typed_extension_protocol_options": {
- "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": {
- "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions",
- "common_http_protocol_options": {
- "idle_timeout": "10s",
- "max_headers_count": 15,
- "max_stream_duration": "30s",
- "headers_with_underscores_action": "REJECT_REQUEST",
- "max_requests_per_connection": 100
- },
- "explicit_http_config": {
- "http_protocol_options": {
- "header_key_format": {
- "stateful_formatter": {
- "name": "envoy.http.stateful_header_formatters.preserve_case",
- "typed_config": {
- "@type": "type.googleapis.com/envoy.extensions.http.header_formatters.preserve_case.v3.PreserveCaseFormatterConfig"
- }
- }
- },
- "enable_trailers": true,
- "override_stream_error_on_invalid_http_message": true
- }
- }
- }
- }
- ...
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete backendconfigpolicy httpbin-connection -n httpbin
-```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/mirroring.md b/assets/docs/pages/resiliency/mirroring.md
deleted file mode 100644
index ddcb35fc7..000000000
--- a/assets/docs/pages/resiliency/mirroring.md
+++ /dev/null
@@ -1,186 +0,0 @@
-Copy live production traffic to a shadow environment or service so that you can try out, analyze, and monitor new software changes before deploying them to production.
-
-## About traffic mirroring
-
-When releasing changes to a service, you want to finely control how those changes get exposed to users. This [progressive delivery](https://redmonk.com/jgovernor/2018/08/06/towards-progressive-delivery/) approach to releasing software allows you to reduce the blast radius, especially when changes introduce unintended behaviors. Traffic mirroring, also referred to as traffic shadowing, is one way to observe the impact of new software releases and test out new changes before you roll them out to production. Other approaches to slowly introduce new software include canary releases, A/B testing, or blue-green deployments.
-
-When you turn on traffic shadowing for an app, kgateway makes a copy of all incoming requests. Kgateway still proxies the request to the backing destination along the request path. It also sends a copy of the request asynchronously to another shadow destination. When a response or failure happens, copies are not generated. This way, you can test how traffic is handled by a new release or version of your app with zero production impact. You can also compare the shadowed results against the expected results. You can use this information to decide how to proceed with a canary release.
-
-
-
-To observe and analyze shadowed traffic, you can use a tool like [Open Diffy](https://github.com/opendiffy/diffy). This tool create diff-compares on the responses. You can use this data to verify that the response is correct and to detect API forward/backward compatibility problems.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up mirroring
-
-1. Edit the httpbin service that you deployed earlier to add the `version: v1` selector label. This label ensures that traffic to the v1 version is always routed to this instances of the httpbin app.
- ```sh
- kubectl patch service httpbin -n httpbin --type='json' -p='[{"op": "add", "path": "/spec/selector/version", "value": "v1"}]'
- ```
-
-2. Deploy another version (`v2`) of httpbin. You use this app to receive the mirrored traffic from httpbin `v1`.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - mirror.example
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- filters:
- - type: RequestMirror
- requestMirror:
- backendRef:
- kind: Service
- name: httpbin2
- port: 8000
- backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-5. Send a few requests to the httpbin app on the `mirror.example` domain. Verify that you get back a 200 HTTP response code.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/headers \
- -H "host: mirror.example:8080"; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- for i in {1..5}; do curl -vi localhost:8080/headers \
- -H "host: mirror.example"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-6. Get the logs of the httpbin app and verify that you see the requests that you sent.
- ```sh
- kubectl logs -l version=v1 -n httpbin
- ```
-
- Example output:
- ```
- time="2025-03-14T19:43:01.1546" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:02.3565" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:03.0178" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.08 user_agent="curl/8.7.1" client_ip=10.0.6.27
- time="2025-03-14T19:43:03.3874" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:03.6862" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.07 user_agent="curl/8.7.1" client_ip=10.0.6.27
- ```
-
-7. Get the logs of the httpbin2 app and verify that you see the same requests.
- ```sh
- kubectl logs -l version=v2 -n httpbin
- ```
-
- Example output:
- ```
- time="2025-03-14T19:43:01.1548" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.17 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:02.3565" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.06 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:03.0173" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.15 user_agent="curl/8.7.1" client_ip=10.0.6.27
- time="2025-03-14T19:43:03.3869" status=200 method="GET" uri="/headers" size_bytes=443 duration_ms=0.16 user_agent="curl/8.7.1" client_ip=10.0.8.23
- time="2025-03-14T19:43:03.6858" status=200 method="GET" uri="/headers" size_bytes=508 duration_ms=0.05 user_agent="curl/8.7.1" client_ip=10.0.6.27
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete service httpbin2 -n httpbin
-kubectl delete deployment httpbin2 -n httpbin
-kubectl delete httproute httpbin-mirror -n httpbin
-```
-
-
diff --git a/assets/docs/pages/resiliency/outlier-detection.md b/assets/docs/pages/resiliency/outlier-detection.md
deleted file mode 100644
index c421e4b04..000000000
--- a/assets/docs/pages/resiliency/outlier-detection.md
+++ /dev/null
@@ -1,243 +0,0 @@
-Configure passive health checks and remove unhealthy hosts from the load balancing pool with an outlier detection policy.
-
-## About outlier detection
-
-Outlier detection is an important part of building resilient apps. An outlier detection policy sets up several conditions, such as retries and ejection percentages, that {{< reuse "agw-docs/snippets/kgateway.md" >}} uses to determine if a service is unhealthy. In case an unhealthy service is detected, the outlier detection policy defines how the service is removed from the pool of healthy destinations to send traffic to. Your apps then have time to recover before they are added back to the load-balancing pool and checked again for consecutive errors.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up outlier detection
-
-1. Scale the httpbin app to 2 replicas.
- ```sh
- kubectl scale deploy/httpbin -n httpbin --replicas=2
- ```
-
-2. Verify that you see two replicas of the httpbin app.
- ```sh
- kubectl get pods -n httpbin
- ```
-
- Example output:
- ```console
- NAME READY STATUS RESTARTS AGE
- httpbin-577649ddb-lsgp8 2/2 Running 0 31d
- httpbin-577649ddb-q9b92 2/2 Running 0 3s
- ```
-
-3. Send a few requests to the httpbin app. Because both httpbin replicas are exposed under the same service, requests are automatically load balanced between all healthy replicas.
- {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for one request:
- ```console
- * Request completely sent off
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- < access-control-allow-credentials: true
- access-control-allow-credentials: true
- < access-control-allow-origin: *
- access-control-allow-origin: *
- < content-length: 0
- content-length: 0
- < x-envoy-upstream-service-time: 1
- x-envoy-upstream-service-time: 1
- < server: envoy
- server: envoy
- <
- ....
- ```
-
-4. Review the logs for both replicas. Verify that you see log entries for the 5 requests spread across both replicas. For example, one replica might have 2 log entries and the other one 3.
- ```sh
- kubectl logs -l app=httpbin -n httpbin -f --prefix
- ```
-
- Example output for one request:
- ```console
- time="2025-09-15T21:11:52.8514" status=200 method="GET" uri="/status/200"
- size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- ```
-
-5. Create a BackendConfigPolicy with your outlier detection policy. The following example ejects an unhealthy upstream host for one hour if the host returns one 5XX HTTP response code. Note that the maximum number of ejected hosts is set to 80%. Because of that, only one replica of httpbin can be ejected at any given time. If two replicas were ejected, that would exceed the 80% maximum threshold (because the two replicas equal 100%).
- ```yaml
- kubectl apply -f- <}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- for i in {1..5}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-7. Force one httpbin replica to return a 503 HTTP response code. This response code triggers the outlier detection policy and automatically removes this httpbin replica from the load balancing pool for 1 hour.
- {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- curl -vik http://$INGRESS_GW_ADDRESS:8080/status/503 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/503 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console
- * Request completely sent off
- < HTTP/1.1 503 Service Unavailable
- HTTP/1.1 503 Service Unavailable
- < access-control-allow-credentials: true
- access-control-allow-credentials: true
- < access-control-allow-origin: *
- ...
- ```
-
-8. Send a few more requests to the httpbin app. In the logs for both replicas, verify that all requests now only go to the instance that is still considered healthy.
- {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- for i in {1..5}; do curl http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example log output of the healthy instance:
- ```console
- time="2025-09-15T21:19:02.0808" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- time="2025-09-15T21:19:02.2452" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- time="2025-09-15T21:19:02.4053" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- time="2025-09-15T21:19:02.6067" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- time="2025-09-15T21:19:02.7604" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- ```
-
- Example log output of the unhealthy instance:
- ```console
- time="2025-09-15T21:17:25.4035" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.04 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- ```
-
-9. Force the second httpbin replica to return a 503 HTTP response code. Note that the outlier detection only allows 80% of all upstream hosts to be ejected at a given time. Since both replicas would equal 100%, the outlier detection does not remove the host from the load balancing pool. The instance is still considered healthy and can receive requests. In your log output for the healthy instance, verify that you see the log entry for the 503 request.
- {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- curl -vik http://$INGRESS_GW_ADDRESS:8080/status/503 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/503 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example log output of the healthy instance:
- ```console
- time="2025-09-15T21:20:27.1117" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.X.X.XX
- ```
-
-10. Send a few more requests to the httpbin app. In the logs for both replicas, verify that all requests are still routed to the same instance as the instance was not removed from the load balancing pool.
- {{< tabs tabTotal="2" items="Cloud Provider Load Balancer,Port forward for local testing" >}}
- {{% tab tabName="Cloud Provider Load Balancer" %}}
- ```sh
- for i in {1..5}; do curl http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080" ; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port forward for local testing" %}}
- ```sh
- for i in {1..5}; do curl -vi localhost:8080/status/200 -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example log output for the healthy instance:
- ```console
- # Previous log output
- time="2025-09-15T21:20:27.1117" status=503 method="GET" uri="/status/503" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.0.9.76
- # New log output
- time="2025-09-15T21:25:11.4236" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.02 user_agent="curl/8.7.1" client_ip=10.0.15.215
- time="2025-09-15T21:25:11.5833" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.0.9.76
- time="2025-09-15T21:25:11.7473" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.03 user_agent="curl/8.7.1" client_ip=10.0.9.76
- time="2025-09-15T21:25:11.9098" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.0.15.215
- time="2025-09-15T21:25:12.0824" status=200 method="GET" uri="/status/200" size_bytes=0 duration_ms=0.01 user_agent="curl/8.7.1" client_ip=10.0.9.76
-
-11. Port-forward the Gateway pod on port 19000.
- ```sh
- kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
-12. Open the [stats Prometheus](http://localhost:19000/stats/prometheus) endpoint and look for the following metrics.
- * `envoy_cluster_outlier_detection_ejections_consecutive_5xx`: The number of times a host qualified for ejection. In this example, the number is 2, because both hosts qualified for ejection.
- * `envoy_cluster_outlier_detection_ejections_enforced_consecutive_5xx`: The number of times an ejection was forced. In this example, the number is 1, because the second host instance could not be ejected as it did not meet the maximum percentage setting in your outlier policy.
-
- Example output:
- ```console
- envoy_cluster_outlier_detection_ejections_consecutive_5xx{envoy_cluster_name="kube_httpbin_httpbin_8000"} 2
- envoy_cluster_outlier_detection_ejections_enforced_consecutive_5xx{envoy_cluster_name="kube_httpbin_httpbin_8000"} 1
- ```
-
-## Cleanup
-
-1. Scale down the httpbin app to 1 replica.
- ```sh
- kubectl scale deploy/httpbin -n httpbin --replicas=1
- ```
-
-2. Remove the BackendConfigPolicy.
- ```sh
- kubectl delete backendconfigpolicy httpbin-policy -n httpbin
- ```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/retry/about.md b/assets/docs/pages/resiliency/retry/about.md
deleted file mode 100644
index c48cd31ab..000000000
--- a/assets/docs/pages/resiliency/retry/about.md
+++ /dev/null
@@ -1,16 +0,0 @@
-A retry is the number of times a request is retried if it fails. This setting can be useful to avoid your apps from failing if they are temporarily unavailable. With retries, calls are retried a certain number of times before they are considered failed. Retries can enhance your app's availability by making sure that calls don't fail permanently because of transient problems, such as a temporarily overloaded service or network.
-
-## Configuration options
-
-You can configure retries by using a Kubernetes Gateway API-native configuration or a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} as shown in the following table
-
-
-| Type of timeout| Description | Configured via | Attach to |
-| -- | -- | -- | --- |
-| [Request retries]({{< link-hextra path="/resiliency/retry/retry/" >}}) | Specify the number of times and duration for the gateway to try a connection to an unresponsive backend service. |
|
-| [Per-try timeout]({{< link-hextra path="/resiliency/retry/per-try-timeout/" >}}) | Set a shorter timeout for retries than the overall request timeout. |
|
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/retry/per-try-timeout.md b/assets/docs/pages/resiliency/retry/per-try-timeout.md
deleted file mode 100644
index a61d1d81a..000000000
--- a/assets/docs/pages/resiliency/retry/per-try-timeout.md
+++ /dev/null
@@ -1,286 +0,0 @@
-Set separate timeouts for retries.
-
-## About per-try timeouts
-
-The per-retry timeout allows you to set a timeout for retried requests. If the timeout expires, Envoy cancels the retry attempt and immediately retries on another upstream host.
-
-By default, Envoy has a default overall request timeout of 15 seconds. A request timeout represents the time Envoy waits for the entire request to complete, including retries. Without a per-try timeout, retries might take longer than the overall request timeout, and therefore might not be executed as the request times out before the retry attempts can be performed. You can configure a larger [request timeout]({{< link-hextra path="/resiliency/timeouts/request/" >}}) to account for this case. However, you can also define timeouts for each retry so that you can protect against slow retry attempts from consuming the entire request timeout.
-
-
-Note that if you configured a global request timeout, the per-try timeout must be less than the global request timeout.
-
-Per-try timeouts can be configured on an HTTPRoute directly. To enable per-try timeouts on a Gateway listener level, use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} instead.
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-experimental.md" >}}
-{{< /callout >}}
-
-{{< callout >}}
-{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}}
-{{< /callout >}}
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up per-retry timeouts
-
-1. Install the experimental Kubernetes Gateway API CRDs.
-
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml
- ```
-
-2. Configure the per-retry timeout. You can apply the timeout to an HTTPRoute, or Gateway listener.
- {{< tabs tabTotal="3" items="HTTPRoute (Kubernetes GW API),HTTPRoute (TrafficPolicy),Gateway listener" >}}
- {{% tab tabName="HTTPRoute (Kubernetes GW API)" %}}
- Use the `timeouts.backendRequest` field to configure the per-try timeout. Note that you must set a retry policy also to configure a per-try timeout.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- retry:
- attempts: 3
- backoff: 1s
- timeouts:
- backendRequest: 5s
- EOF
- ```
- {{% /tab %}}
- {{% tab tabName="HTTPRoute (EnterpriseKgatewayTrafficPolicy)" %}}
- 1. Create an HTTPRoute to route requests along the `retry.example` domain to the httpbin app. Note that you add a name `timeout` to your HTTPRoute rule so that you can configure the per-try timeout for that rule later.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- name: timeout
- EOF
- ```
- 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to configure the per-try timeout. In this example, the per-try timeout is set to 5 seconds and assigned to the `timeout` HTTPRoute rule. Note that you must set a retry policy also to apply a per-try timeout.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: retry
- namespace: httpbin
- spec:
- targetRefs:
- - kind: HTTPRoute
- group: gateway.networking.k8s.io
- name: retry
- sectionName: timeout
- retry:
- attempts: 3
- perTryTimeout: 5s
- statusCodes:
- - 517
- EOF
- ```
-
- {{% /tab %}}
- {{% tab tabName="Gateway listener" %}}
- 1. Create an HTTPRoute to route requests along the `retry.example` domain to the httpbin app.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- EOF
- ```
- 2. Create {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to configure the per-try timeout. In this example, the per-try timeout is set to 5 seconds and assigned to the `http` Gateway listener that you set up as part of the [before you begin](#before-you-begin) section. Note that you must set a retry policy also to apply a per-try timeout.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: retry
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - kind: Gateway
- group: gateway.networking.k8s.io
- name: http
- sectionName: http
- retry:
- attempts: 2
- perTryTimeout: 5s
- statusCodes:
- - 517
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Send a request to the httpbin app along the `retry.example` domain. Verify that the `X-Envoy-Expected-Rq-Timeout-Ms` header is set to the 5 second timeout that you configured.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: retry.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/anything -H "host: retry.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console {hl_lines=[14,15]}
- ...
- {
- "args": {},
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "retry.example"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "5000"
- ],
- "X-Envoy-External-Address": [
- "127.0.0.1"
- ],
- "X-Forwarded-For": [
- "10.244.0.55"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "9178dc39-297f-438a-8bd9-4e8203c06b59"
- ]
- },
- ```
-
-3. Verify that the gateway proxy is configured with the per-try timeout.
- 1. Port-forward the gateway proxy on port 19000.
-
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
- 2. Get the configuration of your gateway proxy as a config dump.
-
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
- 3. Open the config dump and find the route configuration for the `kube_default_reviews_9080` Envoy cluster on the `listener~8080~retry_example` virtual host. Verify that the retry policy is set as you configured it.
-
- Example `jq` command:
- ```sh
- jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_httpbin_httpbin_8000")' gateway-config.json
- ```
-
- Example output:
- ```console {hl_lines=[12]}
- "routes": [
- {
- "match": {
- "prefix": "/"
- },
- "route": {
- "cluster": "kube_httpbin_httpbin_8000",
- "timeout": "5s",
- "retry_policy": {
- "retry_on": "cancelled,connect-failure,refused-stream,retriable-headers,retriable-status-codes,unavailable",
- "num_retries": 3,
- "per_try_timeout": "5s",
- "retry_back_off": {
- "base_interval": "1s"
- }
- },
- "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR"
- },
- "name": "listener~8080~retry_example-route-0-httproute-retry-httpbin-0-0-matcher-0"
- }
- ]
- ```
-
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n httpbin
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete httproute retry -n httpbin
-```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/retry/retry.md b/assets/docs/pages/resiliency/retry/retry.md
deleted file mode 100644
index c8f561b25..000000000
--- a/assets/docs/pages/resiliency/retry/retry.md
+++ /dev/null
@@ -1,496 +0,0 @@
-Specify the number of times and duration for the gateway to try a connection to an unresponsive backend service.
-You might commonly use retries alongside [Timeouts]({{< link-hextra path="/resiliency/timeouts/">}}) to ensure that your apps are available even if they are temporarily unavailable.
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-experimental.md" >}}
-{{< /callout >}}
-
-## About request retries
-
-A request retry is the number of times a request is retried if it fails. This setting can be useful to avoid your apps from failing if they are temporarily unavailable. With retries, calls are retried a certain number of times before they are considered failed. Retries can enhance your app's availability by making sure that calls don't fail permanently because of transient problems, such as a temporarily overloaded service or network.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}}
-
-## Step 1: Set up your environment for retries
-
-To use retries, you need to install the experimental channel. You can also set up two things that help you test retries: a sample app that can simulate a failure and an access log policy that tracks whether the request was retried.
-
-1. Install the experimental Kubernetes Gateway API CRDs.
-
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml
- ```
-
-2. Install a sample app that you can simulate a failure for, such as adding a `sleep` command to the [Bookinfo reviews app](https://istio.io/latest/docs/examples/bookinfo/).
-
- ```sh
- kubectl apply -f- <}}) and the [Envoy access logs response flags docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#response-flags).
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- accessLog:
- - fileSink:
- path: /dev/stdout
- jsonFormat:
- start_time: "%START_TIME%"
- method: "%REQ(:METHOD)%"
- path: "%REQ(:PATH)%"
- response_code: "%RESPONSE_CODE%"
- response_flags: "%RESPONSE_FLAGS%"
- upstream_host: "%UPSTREAM_HOST%"
- upstream_cluster: "%UPSTREAM_CLUSTER%"
- EOF
- ```
-
-## Step 2: Set up request retries {#setup-retries}
-
-Set up retries to the reviews app.
-
-1. Create an HTTPRoute resource to specify your retry rules. You can apply the retry policy on an HTTPRoute, HTTPRoute rule, or Gateway listener.
- {{< tabs tabTotal="3" items="HTTPRoute (Kubernetes GW API),HTTPRoute and rule (TrafficPolicy),Gateway listener" >}}
- {{% tab tabName="HTTPRoute (Kubernetes GW API)" %}}
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: reviews
- port: 9080
- retry:
- attempts: 3
- backoff: 1s
- timeouts:
- request: "20s"
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- | Field | Description |
- |-------|-------------|
- | `hostnames` | The hostnames to match the request, such as `retry.example`. |
- | `parentRefs` | The gateway to which the request is sent. In this example, you select the `http` gateway that you set up before you began. |
- | `rules` | The rules to apply to requests. |
- | `matches` | The path to match the request. In this example, you match any requests to the reviews app with `/`. |
- | `path` | The path to match the request. In this example, you match the request to the `/reviews/1` path. |
- | `backendRefs` | The backend service to which the request is sent. In this example, you select the `reviews` service that you set up in the previous step. |
- | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. |
- | `retry.backoff` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. |
- | `timeouts` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. |
- {{% /tab %}}
- {{% tab tabName="HTTPRoute (EnterpriseKgatewayTrafficPolicy)" %}}
- 1. Create an HTTPRoute that routes requests along the `retry.example` domain to the reviews app. Note that you add a name `timeout` to your HTTPRoute rule so that you can later attach the retry policy to that rule.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: reviews
- port: 9080
- name: timeout
- EOF
- ```
- 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies a retry policy to the `timeout` HTTPRoute rule.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: retry
- namespace: default
- spec:
- targetRefs:
- - kind: HTTPRoute
- group: gateway.networking.k8s.io
- name: retry
- sectionName: timeout
- retry:
- attempts: 3
- backoffBaseInterval: 1s
- retryOn:
- - 5xx
- - unavailable
- timeouts:
- request: 20s
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- | Field | Description |
- |-------|-------------|
- | `targetRefs.sectionName` | Select the HTTPRoute rule that you want to apply the policy to. |
- | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. |
- | `retry.backoffBaseInterval` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. |
- | `retry.retryOn` | The condition that must be met for the gateway proxy to retry the request. In this example, the request is retried if a 5xx HTTP response code is returned or if the upstream service is unavailable. |
- | `timeouts.request` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. |
-
- {{% /tab %}}
- {{% tab tabName="Gateway listener" %}}
- 1. Create an HTTPRoute that routes requests along the `retry.example` domain to the reviews app.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- backendRefs:
- - group: ""
- kind: Service
- name: reviews
- port: 9080
- EOF
- ```
- 2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies a retry policy to the `http` Gateway listener. You set up this Gateway in the [before you begin](#before-you-begin) section.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: retry
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - kind: Gateway
- group: gateway.networking.k8s.io
- name: http
- sectionName: http
- retry:
- attempts: 3
- backoffBaseInterval: 1s
- retryOn:
- - 5xx
- - unavailable
- EOF
- ```
-
- | Field | Description |
- |-------|-------------|
- | `targetRefs.sectionName` | Select the Gateway listener that you want to apply the policy to. |
- | `retry.attempts` | The number of times to retry the request. In this example, you retry the request 3 times. |
- | `retry.backoffBaseInterval` | The duration to wait before retrying the request. In this example, you wait 1 second before retrying the request. |
- | `retry.retryOn` | The condition that must be met for the gateway proxy to retry the request. In this example, the request is retried if a 5xx HTTP response code is returned or if the upstream service is unavailable. |
- | `timeouts.request` | The duration to wait before the request times out. This value is higher than the backoff value so that the request can be retried before it times out. In this example, you set the timeout to 20 seconds. |
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Verify that the gateway proxy is configured to retry the request.
-
- 1. Port-forward the gateway proxy on port 19000.
-
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
- 2. Get the configuration of your gateway proxy as a config dump.
-
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
- 3. Open the config dump and find the route configuration for the `kube_default_reviews_9080` Envoy cluster on the `listener~8080~retry_example` virtual host. Verify that the retry policy is set as you configured it.
-
- Example `jq` command:
-
- ```sh
- jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_default_reviews_9080")' gateway-config.json
- ```
-
- Example output:
- ```json
- {
- "name": "listener~8080~retry_example",
- "domains": [
- "retry.example"
- ],
- "routes": [
- {
- "match": {
- "prefix": "/"
- },
- "route": {
- "cluster": "kube_default_reviews_9080",
- "timeout": "20s",
- "retry_policy": {
- "retry_on": "gateway-error,connect-failure,reset",
- "num_retries": 3,
- "per_try_timeout": "1s",
- "retriable_status_codes": [
- 404
- ],
- "retry_back_off": {
- "base_interval": "0.025s"
- }
- },
- "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR"
- },
- "name": "listener~8080~retry_example-route-0-httproute-retry-default-0-0-matcher-0"
- }
- ]
- }
- ...
- ```
-
-3. Send a request to the reviews app. Verify that the request succeeds.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/reviews/1 -H "host: retry.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/reviews/1 -H "host: retry.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for a successful response:
-
- ```
- HTTP/1.1 200 OK
- ...
- {"id": "1","podname": "reviews-v1-598b896c9d-l7d8l","clustername": "null","reviews": [{ "reviewer": "Reviewer1", "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!"},{ "reviewer": "Reviewer2", "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare."}]}
- ```
-
-4. Check the gateway's access logs to verify that the request was not retried.
-
- ```sh
- kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http | tail -1 | jq
- ```
-
- Example output: Note that the `response_flags` field is `-`, which means that the request was not retried.
-
- ```json
- {
- "method": "GET",
- "path": "/reviews/1",
- "response_code": 200,
- "response_flags": "-",
- "start_time": "2025-06-16T17:24:04.268Z",
- "upstream_cluster": "kube_default_reviews_9080",
- "upstream_host": "10.244.0.24:9080"
- }
- ```
-
-## Step 3: Trigger a retry {#trigger-retry}
-
-Simulate a failure for the reviews app so that you can verify that the request is retried.
-
-1. Send the reviews app to sleep, to simulate an app failure.
-
- ```sh
- kubectl -n default patch deploy reviews-v1 --patch '{"spec":{"template":{"spec":{"containers":[{"name":"reviews","command":["sleep","20h"]}]}}}}'
- ```
-
-2. Send another request to the reviews app. This time, the request fails.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/reviews/1 -H "host: retry.example:80"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/reviews/1 -H "host: retry.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```
- HTTP/1.1 503 Service Unavailable
- ...
- upstream connect error or disconnect/reset before headers. retried and the latest reset reason: remote connection failure, transport failure reason: delayed connect error: Connection refused
- ```
-
-3. Check the gateway's access logs to verify that the request was retried.
-
- ```sh
- kubectl logs -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l gateway.networking.k8s.io/gateway-name=http | tail -1 | jq
- ```
-
- Example output: Note that the `response_flags` field now has values as follows:
-
- * `URX` means `UpstreamRetryLimitExceeded`, which verifies that the request was retried.
- * `UF` means `UpstreamOverflow`, which verifies that the request failed.
-
- ```json
- {
- "method": "GET",
- "path": "/reviews/1",
- "response_code": 503,
- "response_flags": "URX,UF",
- "start_time": "2025-06-16T17:26:07.287Z",
- "upstream_cluster": "kube_default_reviews_9080",
- "upstream_host": "10.244.0.25:9080"
- }
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the HTTPRoute resource.
-
- ```sh
- kubectl delete httproute retry -n default
- ```
-
-2. Delete the reviews app.
-
- ```sh
- kubectl delete deploy reviews-v1 -n default
- kubectl delete svc reviews -n default
- kubectl delete sa bookinfo-reviews -n default
- ```
-
-3. Delete the access log policy.
-
- ```sh
- kubectl delete httplistenerpolicy access-logs -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-4. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
- ```sh
- kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry
- kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} retry -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/tcp-keepalive.md b/assets/docs/pages/resiliency/tcp-keepalive.md
deleted file mode 100644
index 285f99b1f..000000000
--- a/assets/docs/pages/resiliency/tcp-keepalive.md
+++ /dev/null
@@ -1,78 +0,0 @@
-Manage idle and stale connections with TCP keepalive.
-
-## About TCP keepalive
-
-With keepalive, the kernel sends probe packets with only an acknowledgement flag (ACK) to the TCP socket of the destination after the connection was idle for a specific amount of time. This way, the connection does not have to be re-established repeatedly, which could otherwise lead to latency spikes. If the destination returns the packet with an acknowledgement flag (ACK), the connection is determined to be alive. If not, the probe can fail a certain number of times before the connection is considered stale. {{< reuse "agw-docs/snippets/kgateway-capital.md" >}} can then close the stale connection, which can help avoid longer timeouts and retries on broken or stale connections.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up TCP keepalive
-
-1. Create a BackendConfigPolicy that applies TCP keepalive settings to the httpbin service.
- ```yaml
- kubectl apply -f- <}} 19000
- ```
-
-3. Get the configuration of your gateway proxy as a config dump.
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
-4. Open the config dump and find the `kube_httpbin_httpbin_8000` cluster. Verify that you see all the connection settings that you enabled in your BackendConfigPolicy.
-
- Example output
- ```console {hl_lines=[5,6,7,8]}
- ...
- "connect_timeout": "5s",
- "metadata": {},
- "upstream_connection_options": {
- "tcp_keepalive": {
- "keepalive_probes": 3,
- "keepalive_time": 30,
- "keepalive_interval": 5
- }
- }
- },
- ...
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete backendconfigpolicy httpbin-keepalive -n httpbin
-```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/timeouts/about.md b/assets/docs/pages/resiliency/timeouts/about.md
deleted file mode 100644
index 9d230174d..000000000
--- a/assets/docs/pages/resiliency/timeouts/about.md
+++ /dev/null
@@ -1,19 +0,0 @@
-A timeout is the amount of time ([duration](https://protobuf.dev/reference/protobuf/google.protobuf/#duration)) that the gateway waits for replies from a backend service before the service is considered unavailable. This setting can be useful to avoid your apps from hanging or to fail if no response is returned in a specific timeframe. With timeouts, calls either succeed or fail within a predictable timeframe.
-
-The time an app needs to process a request can vary a lot. For this reason, applying the same timeout across services can cause a variety of issues. For example, a timeout that is too long can result in excessive latency from waiting for replies from failing services. On the other hand, a timeout that is too short can result in calls failing unnecessarily while waiting for an operation that needs responses from multiple services.
-
-## Configuration options
-
-You can configure different types of timeouts by using a Kubernetes Gateway API-native configuration, HTTPListenerPolicy, or a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} as shown in the following table.
-
-| Type of timeout| Description | Configured via | Attach to |
-| -- | -- | -- | --- |
-| [Request timeout]({{< link-hextra path="/resiliency/timeouts/request/" >}}) | Request timeouts configure the time Envoy allows for the entire request stream to be received from the client. |
|
-| [Idle timeout]({{< link-hextra path="/resiliency/timeouts/idle/" >}}) | An idle timeout is the time when Envoy terminates the connection to a downstream or upstream service if there no active streams.| HTTPListenerPolicy | Gateway |
-| [Idle stream timeout]({{< link-hextra path="/resiliency/timeouts/idle-stream/" >}}) | An idle stream timeout is the time Envoy allows a stream to exist without activity before it is terminated. | {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} |
HTTPRoute
HTTPRoute rule
|
-| [Per-try timeout]({{< link-hextra path="/resiliency/retry/per-try-timeout" >}}) | Set a shorter timeout for retries than the overall request timeout. |
|
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/timeouts/idle-stream.md b/assets/docs/pages/resiliency/timeouts/idle-stream.md
deleted file mode 100644
index f1bfc24ee..000000000
--- a/assets/docs/pages/resiliency/timeouts/idle-stream.md
+++ /dev/null
@@ -1,91 +0,0 @@
-Customize the default idle stream timeout of 5 minutes (300s).
-
-## About idle stream timeouts
-
-By default, Envoy closes all idle request and response streams after 5 minutes if no data is sent or received and returns a 408 Request Timeout HTTP response code. Idle stream timeouts are different from request timeouts. Request timeouts configure the time Envoy allows for the entire request stream to be received from the client. An idle stream timeout on the other hand is the time Envoy allows a stream to exist without activity before it is terminated. Idle stream timeouts are recommended to protect against clients that stall or that open the stream and never send any data.
-
-You can change the default idle stream timeout setting with a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. While idle streams are a concept in the HTTP/2 and HTTP/3 protocols, Envoy also maps an HTTP/1 request to a stream. Because of that, you can apply idle stream timeouts to HTTP/1 traffic too.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up idle stream timeouts
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your idle stream timeout settings. If you have an HTTPRoute with multiple HTTPRoute rules, you can use the `targetRefs.sectionName` to apply the timeout to a specific HTTPRoute rule. In this example, you apply the policy to the httpbin HTTPRoute.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: timeout
- namespace: httpbin
- spec:
- targetRefs:
- - kind: HTTPRoute
- group: gateway.networking.k8s.io
- name: httpbin
- timeouts:
- streamIdle: 600s
- EOF
- ```
-
-2. Verify that the gateway proxy is configured with the idle stream timeout.
- 1. Port-forward the gateway proxy on port 19000.
-
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
- 2. Get the configuration of your gateway proxy as a config dump.
-
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
- 3. Open the config dump and find the route configuration for the `kube_httpbin_httpbin_8000` Envoy cluster on the `listener~8080~www_example_com` virtual host. Verify that the timeout policy is set as you configured it.
-
- Example `jq` command:
- ```sh
- jq '.configs[] | select(."@type" == "type.googleapis.com/envoy.admin.v3.RoutesConfigDump") | .dynamic_route_configs[].route_config.virtual_hosts[] | select(.routes[].route.cluster == "kube_httpbin_httpbin_8000")' gateway-config.json
- ```
-
- Example output:
- ```console{hl_lines=[9]}
- "routes": [
- {
- "match": {
- "prefix": "/"
- },
- "route": {
- "cluster": "kube_httpbin_httpbin_8000",
- "cluster_not_found_response_code": "INTERNAL_SERVER_ERROR",
- "idle_timeout": "600s"
- },
- "metadata": {
- "filter_metadata": {
- "merge.TrafficPolicy.gateway.kgateway.dev": {
- "timeouts": [
- "gateway.kgateway.dev/TrafficPolicy/httpbin/timeout"
- ]
- }
- }
- },
- "name": "listener~8080~www_example_com-route-0-httproute-httpbin-httpbin-0-0-matcher-0"
- }
- ],
- ```
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} timeout -n httpbin
-```
-
-
-
-
-
diff --git a/assets/docs/pages/resiliency/timeouts/idle.md b/assets/docs/pages/resiliency/timeouts/idle.md
deleted file mode 100644
index e83893a9a..000000000
--- a/assets/docs/pages/resiliency/timeouts/idle.md
+++ /dev/null
@@ -1,96 +0,0 @@
-Customize the default idle timeout of 1 hour (3600s).
-
-## About idle timeouts
-
-By default, Envoy terminates the connection to a downstream or upstream service after one hour if there are no active streams. You can customize this idle timeout with an HTTPListenerPolicy. The policy updates the [`common_http_protocol_options` setting in Envoy](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/upstreams/http/v3/http_protocol_options.proto).
-
-Note that the idle timeout configures the timeout for the entire connection from a downstream service to the gateway proxy, and to the upstream service. If you want to set a timeout for a single stream, configure the [idle stream timeout]({{< link-hextra path="/resiliency/timeouts/idle-stream/" >}}) instead.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up idle timeouts
-
-1. Create an HTTPListenerPolicy with your idle timeout configuration. In this example, you apply an idle timeout of 30 seconds.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- idleTimeout: "30s"
- EOF
- ```
-
-2. Verify that the gateway proxy is configured with the idle timeout.
- 1. Port-forward the gateway proxy on port 19000.
-
- ```sh
- kubectl port-forward deployment/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
- 2. Get the configuration of your gateway proxy as a config dump.
-
- ```sh
- curl -X POST 127.0.0.1:19000/config_dump\?include_eds > gateway-config.json
- ```
-
- 3. Open the config dump and find the `http_connection_manager` configuration. Verify that the timeout policy is set as you configured it.
-
- Example `jq` command:
- ```sh
- jq '.configs[]
- | select(."@type" == "type.googleapis.com/envoy.admin.v3.ListenersConfigDump")
- | .dynamic_listeners[].active_state.listener.filter_chains[].filters[]
- | select(.name == "envoy.filters.network.http_connection_manager")' gateway-config.json
- ```
-
- Example output:
- ```console{hl_lines=[25]}
- {
- "name": "envoy.filters.network.http_connection_manager",
- "typed_config": {
- "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager",
- "stat_prefix": "http",
- "rds": {
- "config_source": {
- "ads": {},
- "resource_api_version": "V3"
- },
- "route_config_name": "listener~8080"
- },
- "http_filters": [
- {
- "name": "envoy.filters.http.router",
- "typed_config": {
- "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"
- }
- }
- ],
- "use_remote_address": true,
- "normalize_path": true,
- "merge_slashes": true,
- "common_http_protocol_options": {
- "idle_timeout": "30s"
- }
- }
- }
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete httplistenerpolicy idle-time -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-
diff --git a/assets/docs/pages/resiliency/timeouts/request.md b/assets/docs/pages/resiliency/timeouts/request.md
deleted file mode 100644
index 1567d21a9..000000000
--- a/assets/docs/pages/resiliency/timeouts/request.md
+++ /dev/null
@@ -1,211 +0,0 @@
-Change the default route-level timeout of 15 seconds with an HTTPRoute or {{< reuse "agw-docs/snippets/kgateway.md" >}} {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. To ensure that your apps are available even if they are temporarily unavailable, you can use timeouts alongside [Retries]({{< link-hextra path="/resiliency/retry/" >}}).
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up timeouts {#timeouts}
-
-Specify timeouts for a specific route.
-
-1. Configure a timeout for a specific route by using the Kubernetes Gateway API-native configuration in an HTTPRoute or by using {{< reuse "agw-docs/snippets/kgateway.md" >}}'s {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. In the following example, you set a timeout of 20 seconds for httpbin's `/headers` path. However, no timeout is set along the `/anything` path.
- {{< tabs tabTotal="2" items="Option 1: HTTPRoute (Kubernetes GW API),Option 2: TrafficPolicy" >}}
- {{% tab tabName="Option 1: HTTPRoute (Kubernetes GW API)" %}}
- ```yaml
- kubectl apply -n httpbin -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /headers
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- timeouts:
- request: "20s"
- - matches:
- - path:
- type: PathPrefix
- value: /anything
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- EOF
- ```
- {{% /tab %}}
- {{% tab tabName="Option 2: EnterpriseKgatewayTrafficPolicy" %}}
- 1. Install the experimental channel of the Kubernetes Gateway API to use this feature.
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml
- ```
-
- 2. Create the HTTPRoute with two routes, `/headers` and `/anything`, and add an HTTPRoute rule name to each path. You use the rule name later to apply the timeout to a particular route.
- ```yaml
- kubectl apply -n httpbin -f- <}}
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /headers
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- name: timeout
- - matches:
- - path:
- type: PathPrefix
- value: /anything
- backendRefs:
- - group: ""
- kind: Service
- name: httpbin
- port: 8000
- name: no-timeout
- EOF
- ```
-
- 3. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your timeout settings and use the `targetRefs.sectionName` to apply the timeout to a specific HTTPRoute rule. In this example, you apply the policy to the `timeout` rule that points to the `/headers` path in your HTTPRoute resource.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: timeout
- namespace: httpbin
- spec:
- targetRefs:
- - kind: HTTPRoute
- group: gateway.networking.k8s.io
- name: httpbin-timeout
- sectionName: timeout
- timeouts:
- request: 20s
- EOF
- ```
-
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Send a request to the httpbin app along the `/headers` path that you configured a custom timeout for. Verify that the request succeeds and that you see a `X-Envoy-Expected-Rq-Timeout-Ms` header with the custom timeout of 20 seconds (20000).
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/headers -H "host: timeout.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/headers -H "host: timeout.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for a successful response:
- ```console {hl_lines=[12,13]}
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com:8080"
- ],
- "User-Agent": [
- "curl/7.77.0"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "20000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "0ae53bc3-2644-44f2-8603-158d2ccf9f78"
- ]
- }
- }
- ```
-
-3. Send a request to the httpbin app along the `anything` path that does not have a custom timeout. Verify that the request succeeds and that you see a `X-Envoy-Expected-Rq-Timeout-Ms` header with the default timeout of 15 seconds (15000).
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: timeout.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/anything -H "host: timeout.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for a successful response:
- ```console {hl_lines=[12,13]}
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com:8080"
- ],
- "User-Agent": [
- "curl/7.77.0"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "0ae53bc3-2644-44f2-8603-158d2ccf9f78"
- ]
- }
- }
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete httproute httpbin-timeout -n httpbin
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} timeout -n httpbin
-```
-
-
-
-
-
diff --git a/assets/docs/pages/security/access-logging.md b/assets/docs/pages/security/access-logging.md
deleted file mode 100644
index c8e6cbf1b..000000000
--- a/assets/docs/pages/security/access-logging.md
+++ /dev/null
@@ -1,387 +0,0 @@
-Capture an access log for all the requests that enter the gateway.
-
-{{< callout >}}
-{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}}
-{{< /callout >}}
-
-## About access logging
-
-Access logs, sometimes referred to as audit logs, represent all traffic requests that pass through the gateway proxy. The access log entries can be customized to include data from the request, the routing destination, and the response.
-
-Access logs can be written to a file, the `stdout` stream of the gateway proxy container, or exported to a gRPC server for custom handling. The access logs capture information from requests that the Envoy HttpConnectionManager in your gateway proxy handles.
-
-### Envoy data that can be logged
-
-Envoy exposes a lot of data that can be used when customizing access logs. The following data properties are available for both TCP and HTTP access logging:
-
-* The downstream (client) address, connection information, TLS configuration, and timing
-* The backend (service) address, connection information, TLS configuration, timing, and Envoy routing information
-* Relevant Envoy configuration, such as rate of sampling (if used)
-* Filter-specific context that is published to Envoy's dynamic metadata during the filter chain
-
-### Additional HTTP properties
-
-When Envoy is used as an HTTP proxy, additional HTTP information is available for access logging, including:
-
-* Request data, including the method, path, scheme, port, user agent, headers, body, and more
-* Response data, including the response code, headers, body, and trailers, as well as a string representation of the response code
-* Protocol version
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Access logs to `stdout` {#access-log-stdout-filesink}
-
-You can set up access logs to write to a standard (stdout/stderr) stream. The following example writes access logs to a stdout in the pod of the selected `http` gateway.
-
-1. Create an HTTPListenerPolicy resource to define your access logging rules. The following example writes access logs to the `stdout` stream of the gateway proxy container by using a custom string format that is defined in the `jsonFormat` field.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- accessLog:
- - fileSink:
- path: /dev/stdout
- jsonFormat:
- start_time: "%START_TIME%"
- method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%"
- path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
- protocol: "%PROTOCOL%"
- response_code: "%RESPONSE_CODE%"
- response_flags: "%RESPONSE_FLAGS%"
- bytes_received: "%BYTES_RECEIVED%"
- bytes_sent: "%BYTES_SENT%"
- total_duration: "%DURATION%"
- resp_backend_service_time: "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
- req_x_forwarded_for: "%REQ(X-FORWARDED-FOR)%"
- user_agent: "%REQ(USER-AGENT)%"
- request_id: "%REQ(X-REQUEST-ID)%"
- authority: "%REQ(:AUTHORITY)%"
- backendHost: "%UPSTREAM_HOST%"
- backendCluster: "%UPSTREAM_CLUSTER%"
- EOF
- ```
-
- | Setting | Description |
- | ------- | ----------- |
- | `targetRefs`| Select the Gateway to enable access logging for. The example selects the `http` gateway that you created from the sample app guide. |
- | `accessLog` | Configure the details for access logging. You can use multiple `fileSink` configurations for multiple outputs. The example sets up a `fileSink` for standard logging (stdout) in JSON format at `/dev/stdout`. You can also send the access logs to a `grpcService` instead of `fileSink`. |
- | `path` | The path in the gateway proxy to write access logs to, such as `/dev/stdout`. |
- | `jsonFormat` | The structured JSON format to write logs in. For more information about the JSON format dictionaries and command operators you can use, see the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-dictionaries). To format as a string, use the `stringFormat` setting instead. If you omit or leave this setting blank, the [Envoy default format string](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) is used. |
- | `stringFormat` | The string format to write logs in. For more information about the string format and command operators you can use, see the [Envoy docs](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#config-access-log-format-strings). To format as JSON, use the `jsonFormat` setting instead. If you omit or leave this setting blank, the [Envoy default format string](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) is used. |
-
-2. Send a request to the httpbin app on the `www.example.com` domain. Verify that your request succeeds and that you get back a 200 HTTP response code.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/status/200 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- HTTP/1.1 200 OK
- access-control-allow-credentials: true
- access-control-allow-origin: *
- date: Fri, 07 Jun 2024 21:10:03 GMT
- x-envoy-upstream-service-time: 2
- server: envoy
- transfer-encoding: chunked
- ```
-
-3. Get the logs for the gateway pod and verify that you see a stdout JSON entry for each request that you sent to the httpbin app.
-
- ```sh
- kubectl -n {{< reuse "agw-docs/snippets/namespace.md" >}} logs deployments/http | tail -1 | jq
- ```
-
- Example output:
- ```json
- {
- "authority": "www.example.com:8080",
- "bytes_received": 0,
- "bytes_sent": 0,
- "method": "GET",
- "path": "/status/200",
- "protocol": "HTTP/1.1",
- "req_x_forwarded_for": null,
- "request_id": "a6758866-0f26-4c95-95d9-4032c365c498",
- "resp_backend_service_time": "0",
- "response_code": 200,
- "response_flags": "-",
- "start_time": "2024-08-19T20:57:57.511Z",
- "total_duration": 1,
- "backendCluster": "kube-svc:httpbin-httpbin-8000_httpbin",
- "backendHost": "10.36.0.14:8080",
- "user_agent": "curl/7.77.0"
- }
- ```
-
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete HTTPListenerPolicy access-logs -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-
-
-
diff --git a/assets/docs/pages/security/backend-tls.md b/assets/docs/pages/security/backend-tls.md
deleted file mode 100644
index 9445ed96d..000000000
--- a/assets/docs/pages/security/backend-tls.md
+++ /dev/null
@@ -1,453 +0,0 @@
-Originate a one-way TLS connection from the Gateway to a backend.
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-experimental.md" >}}
-{{< /callout >}}
-
-## About one-way TLS
-
-When you configure a TLS listener on your Gateway, the Gateway typically terminates incoming TLS traffic and forwards the unencrypted traffic to the backend service. However, you might have a service that only accepts TLS connections, or you want to forward traffic a secured Backend service that is external to the cluster.
-
-You can use the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} BackendTLSPolicy](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/) to configure TLS origination from the Gateway to a service in the cluster. This policy supports simple, one-way TLS use cases.
-
-However, to additionally set up different hostnames on the Backend that you want to route to via SNI, or to originate TLS connections to an external backend, use the {{< reuse "agw-docs/snippets/kgateway.md" >}} BackendConfigPolicy instead.
-
-## About this guide
-
-In this guide, you learn how to use the BackendTLSPolicy and BackendConfigPolicy resources originate one-way TLS connections for the following services:
-* [**In-cluster service**](#in-cluster-service): An NGINX server that is configured with a self-signed TLS certificate and deployed to the same cluster as the Gateway. You use a BackendTLSPolicy to originate TLS connections to NGINX.
-* [**External service**](#external-service): The `httpbin.org` hostname, which represents an external service that you want to originate a TLS connection to. You use a BackendConfigPolicy resource to originate TLS connections to that hostname.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}}
-
-## In-cluster service
-
-Deploy an NGINX server in your cluster that is configured for TLS traffic. Then, instruct the gateway proxy to terminate TLS traffic at the gateway and originate a new TLS connection from the gateway proxy to the NGINX server.
-
-{{< callout >}}
-{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}}
-{{< /callout >}}
-
-### Deploy the sample app
-
-The following example uses an NGINX server with a self-signed TLS certificate. For the configuration, see the [test directory in the kgateway GitHub repository](https://github.com/kgateway-dev/kgateway/tree/{{< reuse "agw-docs/versions/github-branch.md" >}}/test/kubernetes/e2e/features/backendtls/inputs).
-
-
-1. Deploy the NGINX server with a self-signed TLS certificate.
-
- ```shell
- kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml
- ```
-
-2. Verify that the NGINX server is running.
-
- ```shell
- kubectl get pods -l app.kubernetes.io/name=nginx
- ```
-
- Example output:
-
- ```
- NAME READY STATUS RESTARTS AGE
- nginx 1/1 Running 0 9s
- ```
-
-### Create a TLS policy {#create-backend-tls-policy}
-
-Create a TLS policy for the NGINX workload. You can use the Gateway API BackendTLSPolicy for simple, one-way TLS connections. For more advanced TLS connections or simply to reduce the number of resources if you use other backend connections, create a BackendConfigPolicy instead.
-
-{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}}
-{{% tab tabName="BackendConfigPolicy" %}}
-
-1. Create a Kubernetes Secret that has the public CA certificate for the NGINX server.
-
- ```yaml
- kubectl apply -f- <}} For more information, see the [BackendConfigPolicy API docs](../../reference/api/#backendconfigpolicy).
-
- | Setting | Description |
- |---------|-------------|
- | `targetRefs` | The service that you want the Gateway to originate a TLS connection to, such as the NGINX server.
**Agentgateway proxies**: Even if you use a Backend for selector-based destinations, you still need to target the backing Service and the `sectionName` of the port that you want the policy to apply to. |
- | `tls.sni` | The Server Name Indication (SNI) hostname that matches the NGINX server certificate. The SNI is used during the TLS handshake to specify which certificate the server should present. |
- | `tls.secretRef` | The Kubernetes Secret that has the public CA certificate for the NGINX server. |
-
-{{% /tab %}}
-
-{{% tab tabName="BackendTLSPolicy" %}}
-
-1. Create a Kubernetes ConfigMap that has the public CA certificate for the NGINX server.
-
- ```shell
- kubectl apply -f- <}}
- EOF
- ```
-
-2. Create the TLS policy. Note that to use the BackendTLSPolicy, you must have the experimental channel of the Kubernetes Gateway API version 1.4 or later.
- ```yaml
- kubectl apply -f - <}} For more information, see the [{{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} docs](https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/).
-
- | Setting | Description |
- |---------|-------------|
- | `targetRefs` | The service that you want the Gateway to originate a TLS connection to, such as the NGINX server.
**Agentgateway proxies**: Even if you use a Backend for selector-based destinations, you still need to target the backing Service and the `sectionName` of the port that you want the policy to apply to. |
- | `validation.hostname` | The hostname that matches the NGINX server certificate. |
- | `validation.caCertificateRefs` | The ConfigMap that has the public CA certificate for the NGINX server. |
-{{% /tab %}}
-
-{{< /tabs >}}
-
-### Create an HTTPRoute {#create-http-route}
-
-Create an HTTPRoute that routes traffic to the NGINX server on the `example.com` hostname and HTTPS port 8443. Note that the parent Gateway is the sample `http` Gateway resource that you created [before you began](#before-you-begin).
-
-```yaml
-kubectl apply -f - <}}
- hostnames:
- - "example.com"
- rules:
- - backendRefs:
- - name: nginx
- port: 8443
-EOF
-```
-
-### Verify the TLS connection {#verify-tls-connection}
-
-Now that your TLS backend and routing resources are configured, verify the TLS connection.
-
-1. Send a request to the NGINX server and verify that you get back a 200 HTTP response code.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/ -H "host: example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi http://localhost:8080/ -H "host: example.com:8080"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Host localhost:8080 was resolved.
- * IPv6: ::1
- * IPv4: 127.0.0.1
- * Trying [::1]:8080...
- * Connected to localhost (::1) port 8080
- > GET / HTTP/1.1
- > Host: example.com:8080
- > User-Agent: curl/8.7.1
- > Accept: */*
- >
- * Request completely sent off
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ```
-
-2. Enable port-forwarding on the Gateway.
-
- ```sh
- kubectl port-forward deploy/http -n kgateway-system 19000
- ```
-
-3. In your browser, open the Envoy stats page at [http://127.0.0.1:19000/stats](http://127.0.0.1:19000/stats).
-
-4. Search for the following stats that indicate the TLS connection is working. The count increases each time that the Gateway sends a request to the NGINX server.
-
- * `cluster.kube_default_nginx_8443.ssl.versions.TLSv1.2`: The number of TLSv1.2 connections from the Envoy gateway proxy to the NGINX server.
- * `cluster.kube_default_nginx_8443.ssl.handshake`: The number of successful TLS handshakes between the Envoy gateway proxy and the NGINX server.
-
-## External service
-
-Set up a Backend resource that represents your external service. Then, use a BackendTLSPolicy to instruct the gateway proxy to originate a TLS connection from the gateway proxy to the external service.
-
-1. Create a Backend resource that represents your external service. In this example, you use a static Backend that routes traffic to the `httpbin.org` site. Make sure to include the HTTPS port 443 so that traffic is routed to this port.
- ```yaml
- kubectl apply -f- <}}
- {{% tab tabName="BackendConfigPolicy" %}}
-
- {{< reuse "agw-docs/snippets/proxy-kgateway.md" >}}
- ```yaml
- kubectl apply -f- <}}
-
-3. Create an HTTPRoute that rewrites traffic on the `httpbin-external.example` domain to the `httpbin.org` hostname and routes traffic to your Backend.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "httpbin-external.example"
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /anything
- backendRefs:
- - name: httpbin-org
- kind: Backend
- group: gateway.kgateway.dev
- filters:
- - type: URLRewrite
- urlRewrite:
- hostname: httpbin.org
- EOF
- ```
-
-4. Send a request to the `httpbin-external.example` domain. Verify that the host is rewritten to `https://httpbin.org/anything` and that you get back a 200 HTTP response code.
-
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2">}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: httpbin-external.example"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi http://localhost:8080/anything -H "host: httpbin-external.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console {hl_lines=[1,2,20]}
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ...
- {
- "args": {},
- "data": "",
- "files": {},
- "form": {},
- "headers": {
- "Accept": "*/*",
- "Host": "httpbin.org",
- "User-Agent": "curl/8.7.1",
- "X-Amzn-Trace-Id": "Root=1-6881126a-03bfc90450805b9703e66e78",
- "X-Envoy-Expected-Rq-Timeout-Ms": "15000",
- "X-Envoy-External-Address": "10.0.15.215"
- },
- "json": null,
- "method": "GET",
- "origin": "10.0.X.XXX, 3.XXX.XXX.XXX",
- "url": "https://httpbin.org/anything"
- }
- ```
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-### In-cluster service
-
-{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}}
-{{% tab tabName="BackendConfigPolicy" %}}
-1. Delete the NGINX server.
-
- ```yaml
- kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml
- ```
-
-2. Delete the routing resources that you created for the NGINX server.
-
- ```sh
- kubectl delete backendconfigpolicy,secret,httproute -A -l app=nginx
- ```
-{{% /tab %}}
-{{% tab tabName="BackendTLSPolicy" %}}
-1. Delete the NGINX server.
-
- ```yaml
- kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/backendtls/testdata/nginx.yaml
- ```
-
-2. Delete the routing resources that you created for the NGINX server.
-
- ```sh
- kubectl delete backendtlspolicy,configmap,httproute -A -l app=nginx
- ```
-
-3. If you want to re-create a BackendTLSPolicy after deleting one, restart the control plane.
-
- **Note**: Due to a [known issue](https://github.com/kgateway-dev/kgateway/issues/11146), if you don't restart the control plane, you might notice requests that fail with a `HTTP/1.1 400 Bad Request` error after creating the new BackendTLSPolicy.
-
- ```sh
- kubectl rollout restart -n kgateway-system deployment/{{< reuse "agw-docs/snippets/pod-name.md" >}}
- ```
-{{% /tab %}}
-{{< /tabs >}}
-
-
-### External service
-
-Delete the resources that you created.
-
-{{< tabs tabTotal="2" items="BackendConfigPolicy,BackendTLSPolicy" >}}
-{{% tab tabName="BackendConfigPolicy" %}}
-```sh
-kubectl delete httproute httpbin-org
-kubectl delete backendconfigpolicy httpbin-org
-kubectl delete backend httpbin-org
-```
-{{% /tab %}}
-{{% tab tabName="BackendTLSPolicy" %}}
-```sh
-kubectl delete httproute httpbin-org
-kubectl delete backendtlspolicy httpbin-org
-kubectl delete backend httpbin-org
-```
-{{% /tab %}}
-{{< /tabs >}}
-
-
-
diff --git a/assets/docs/pages/security/cors.md b/assets/docs/pages/security/cors.md
deleted file mode 100644
index e5f24a4c1..000000000
--- a/assets/docs/pages/security/cors.md
+++ /dev/null
@@ -1,273 +0,0 @@
-Enforce client-site access controls with cross-origin resource sharing (CORS).
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-experimental.md" >}}
-{{< /callout >}}
-
-## About CORS
-
-Cross-Origin Resource Sharing (CORS) is a security feature that is implemented by web browsers and that controls how web pages in one domain can request and interact with resources that are hosted on a different domain. By default, web browsers only allow requests to resources that are hosted on the same domain as the web page that served the original request. Access to web pages or resources that are hosted on a different domain is restricted to prevent potential security vulnerabilities, such as cross-site request forgery (CRSF).
-
-When CORS is enabled in a web browser and a request for a different domain comes in, the web browser checks whether this request is allowed or not. To do that, it typically sends a preflight request (HTTP `OPTIONS` method) to the server or service that serves the requested resource. The service returns the methods that are permitted to send the actual cross-origin request, such as GET, POST, etc. If the request to the different domain is allowed, the response includes CORS-specific headers that instruct the web browser how to make the cross-origin request. For example, the CORS headers typically include the origin that is allowed to access the resource, and the credentials or headers that must be included in the cross-origin request.
-
-Note that the preflight request is optional. Web browsers can also be configured to send the cross-origin directly. However, access to the request resource is granted only if CORS headers were returned in the response. If no headers are returned during the preflight request, the web browser denies access to the resource in the other domain.
-
-CORS policies are typically implemented to limit access to server resources for JavaScripts that are embedded in a web page, such as:
-
-* A JavaScript on a web page at `example.com` tries to access a different domain, such as `api.com`.
-* A JavaScript on a web page at `example.com` tries to access a different subdomain, such as `api.example.com`.
-* A JavaScript on a web page at `example.com` tries to access a different port, such as `example.com:3001`.
-* A JavaScript on a web page at `https://example.com` tries to access the resources by using a different protocol, such as `http://example.com`.
-
-
-
-### Configuration options {#options}
-
-You can configure the CORS policy at two levels:
-
-* **HTTPRoute**: For the native way in Kubernetes Gateway API, configure a CORS policy in the HTTPRoute. You can choose to apply the CORS policy to all the routes that are defined in the HTTPRoute, or to a selection of `backendRefs`. This route-level policy takes precedence over any {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} CORS that you might configure. For more information, see the [Kubernetes Gateway API docs](https://gateway-api.sigs.k8s.io/reference/spec/#httpcorsfilter) and [CORS design docs](https://gateway-api.sigs.k8s.io/geps/gep-1767/).
-* **{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}**: For more flexibility to reuse the CORS policy across HTTPRoutes, specific routes and Gateways, configure a CORS policy in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. You can attach a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a Gateway, all HTTPRoutes via `targetRefs`, or an individual route via `extensionRef`. To attach to a `backendRef`, use a CORS policy in the HTTPRoute instead. For more information about attachment and merging rules, see the [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} concept docs](../../about/policies/trafficpolicy/).
-
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq-x-channel.md" >}}
-
-## Set up CORS policies
-
-Create a CORS policy for the httpbin app in an HTTPRoute or {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
-
-{{% version exclude-if="2.0.x" %}}
-
-### CORS in HTTPRoute
-
-Create an HTTPRoute resource for the httpbin app that applies a CORS filter. The following example allows requests from the `https://example.com/` origin.
-
-```yaml
-kubectl apply -f- <}}
- hostnames:
- - cors.example
- rules:
- - filters:
- - type: CORS
- cors:
- allowCredentials: true
- allowHeaders:
- - Origin
- allowMethods:
- - GET
- - POST
- - OPTIONS
- allowOrigins:
- - "https://example.com"
- exposeHeaders:
- - Origin
- - X-HTTPRoute-Header
- maxAge: 86400
- backendRefs:
- - name: httpbin
- port: 8000
-EOF
-```
-
-### CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource for the httpbin app that applies a CORS filter. The following example allows requests from the `https://example.com/` origin.
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: httpbin-cors
- namespace: httpbin
- spec:
- cors:
- allowCredentials: true
- allowHeaders:
- - "Origin"
- - "Authorization"
- - "Content-Type"
- allowMethods:
- - "GET"
- - "POST"
- - "OPTIONS"
- allowOrigins:
- - "https://example.com"
- exposeHeaders:
- - "Origin"
- - "X-TrafficPolicy-Header"
- maxAge: 86400
- EOF
- ```
-
-2. Attach the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to a route or Gateway. The following example creates an HTTPRoute for the httpbin app that has the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} attached via the `extensionRef` filter. For more information about attachment and merging rules, see the [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} concept docs]({{< link-hextra path="/about/policies/trafficpolicy/" >}}).
-
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - cors.example
- rules:
- - filters:
- - type: ExtensionRef
- extensionRef:
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- name: httpbin-cors
- backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-{{% /version %}}
-
-
-## Test CORS policies
-
-Now that you have CORS policies applied via an HTTPRoute or {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, you can test the policies.
-
-1. Send a request to the httpbin app on the `cors.example` domain and use `https://example.com/` as the origin. Verify that your request succeeds and that you get back the configured CORS headers.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -I -X OPTIONS http://$INGRESS_GW_ADDRESS:8080/get -H "host: cors.example:8080" \
- -H "Origin: https://example.com/" \
- -H "Access-Control-Request-Method: POST" \
- -H "Access-Control-Request-Headers: Origin"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -I -X OPTIONS localhost:8080/headers -H "host: cors.example:8080" \
- -H "Origin: https://example.com/" \
- -H "Access-Control-Request-Method: POST" \
- -H "Access-Control-Request-Headers: Origin"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output: Notice that the `access-control-*` values reflect your CORS policy and change depending on the resources that you created.
- * If you created an HTTPRoute with a CORS filter, you see the `Origin` and `X-HTTPRoute-Header` headers.
- * If you created a TrafficPolicy with a CORS filter, you see the `Origin` and `X-TrafficPolicy-Header` headers.
-
- **CORS in HTTPRoute**
-
- ```console {hl_lines=[7,8,9]}
- HTTP/1.1 200 OK
- x-correlation-id: aaaaaaaa
- date: Tue, 24 Jun 2025 13:19:53 GMT
- content-length: 0
-
- HTTP/1.1 200 OK
- access-control-allow-origin: https://example.com/
- access-control-allow-credentials: true
- access-control-allow-methods: GET, POST, OPTIONS
- access-control-allow-headers: Origin, Authorization, Content-Type
- access-control-max-age: 86400
- access-control-expose-headers: Origin, X-HTTPRoute-Header
- date: Tue, 24 Jun 2025 13:19:53 GMT
- server: envoy
- content-length: 0
- ...
- ```
-
- **CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}**
- ```console {hl_lines=[7,8,9]}
- HTTP/1.1 200 OK
- x-correlation-id: aaaaaaaa
- date: Tue, 24 Jun 2025 13:19:53 GMT
- content-length: 0
-
- HTTP/1.1 200 OK
- access-control-allow-origin: https://example.com/
- access-control-allow-credentials: true
- access-control-allow-methods: GET, POST, OPTIONS
- access-control-allow-headers: Origin, Authorization, Content-Type
- access-control-max-age: 86400
- access-control-expose-headers: Origin, X-TrafficPolicy-Header
- date: Tue, 24 Jun 2025 13:19:53 GMT
- server: envoy
- content-length: 0
- ```
-
-
-
-2. Send another request to the httpbin app. This time, you use `notallowed.com` as your origin. Although the request succeeds, you do not get back your configured CORS settings such as max age, allowed orgin, or allowed methods, because `notallowed.com` is not configured as a supported origin.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -I -X OPTIONS http://$INGRESS_GW_ADDRESS:8080/get -H "host: cors.example:8080" \
- -H "Origin: https://notallowed.com/" \
- -H "Access-Control-Request-Method: POST" \
- -H "Access-Control-Request-Headers: Origin"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -I -X OPTIONS localhost:8080/headers -H "host: cors.example:8080" \
- -H "Origin: https://notallowed.com/" \
- -H "Access-Control-Request-Method: POST" \
- -H "Access-Control-Request-Headers: Origin"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console
- HTTP/1.1 200 OK
- x-correlation-id: aaaaaaaa
- date: Tue, 24 Jun 2025 13:21:20 GMT
- content-length: 0
-
- HTTP/1.1 200 OK
- access-control-allow-credentials: true
- access-control-allow-headers: Origin
- access-control-allow-methods: GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS
- access-control-allow-origin: https://notallowed.com/
- access-control-max-age: 3600
- date: Tue, 24 Jun 2025 13:21:20 GMT
- content-length: 0
- x-envoy-upstream-service-time: 1
- server: envoy
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-
-**CORS in HTTPRoute**
-```sh
-kubectl delete httproute httpbin-cors -n httpbin
-```
-
-**CORS in {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}**
-```sh
-kubectl delete httproute httpbin-cors -n httpbin
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} httpbin-cors -n httpbin
-```
-
-
-
diff --git a/assets/docs/pages/security/csrf.md b/assets/docs/pages/security/csrf.md
deleted file mode 100644
index 58ae0c7c6..000000000
--- a/assets/docs/pages/security/csrf.md
+++ /dev/null
@@ -1,166 +0,0 @@
-Apply a CSRF filter to the gateway to help prevent cross-site request forgery attacks.
-
-## About CSRF
-
-According to [OWASP](https://owasp.org/www-community/attacks/csrf), CSRF is defined as follows:
-
-> Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. With a little help of social engineering (such as sending a link via email or chat), an attacker may trick the users of a web application into executing actions of the attacker's choosing. If the victim is a normal user, a successful CSRF attack can force the user to perform state changing requests like transferring funds, changing their email address, and so forth. If the victim is an administrative account, CSRF can compromise the entire web application.
-
-To help prevent CSRF attacks, you can enable the CSRF filter on your gateway or a specific route. For each route that you apply the CSRF policy to, the filter checks to make sure that a request's origin matches its destination. If the origin and destination do not match, a 403 Forbidden error code is returned.
-
-{{< callout type="info" >}}
-Note that because CSRF attacks specifically target state-changing requests, the filter only acts on HTTP requests that have a state-changing method such as `POST` or `PUT`.
-{{< /callout >}}
-
-{{< callout type="info" >}}
-To learn more about CSRF, you can try out the [CSRF sandbox](https://www.envoyproxy.io/docs/envoy/latest/start/sandboxes/csrf) in Envoy.
-{{< /callout >}}
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up CSRF
-
-Use a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to define your CSRF rules.
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource to define your CSRF rules. The following example allows request from only the `allowThisOne.example.com` origin.
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: csrf
- namespace: httpbin
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin
- csrf:
- percentageEnabled: 100
- additionalOrigins:
- - exact: allowThisOne.example.com
- ignoreCase: false
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}} For more information, see the [API docs]({{< link-hextra path="/reference/api/#csrfpolicy" >}}).
-
- | Field | Description |
- |-------|-------------|
- | `targetRefs` | The policy targets the `httpbin` HTTPRoute resource that you created before you began. |
- | `percentageEnabled` | The percentage of requests for which the CSRF policy is enabled. A value of `100` means that all requests are enforced by the CSRF rules. |
- | `additionalOrigins` | Additional origins that the CSRF policy allows, besides the destination origin. Possible values include `exact`, `prefix`, `suffix`, `contains`, `safeRegex`, and an `ignoreCase` boolean. At least one of `exact`, `prefix`, `suffix`, `contains`, or `safeRegex` must be set. The example allows requests from the `allowThisOne.example.com` exact origin. |
-
-2. Send a request to the httpbin app on the `www.example.com` domain. Verify that you get back a 403 HTTP response code because no origin is set in your request.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi -X POST http://$INGRESS_GW_ADDRESS:8080/post -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi -X POST localhost:8080/post -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```console
- HTTP/1.1 403 Forbidden
- ...
- Invalid origin
- ```
-
-3. Send another request to the httpbin app. This time, you include the `allowThisOne.example.com` origin header. Verify that you get back a 200 HTTP response code, because the origin matches the origin that you specified in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi -X POST http://$INGRESS_GW_ADDRESS:8080/post -H "host: www.example.com:8080" -H "origin: allowThisOne.example.com"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi -X POST localhost:8080/post -H "host: www.example.com" -H "origin: allowThisOne.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```console
- HTTP/1.1 200 OK
- ...
- {
- "args": {},
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Content-Length": [
- "0"
- ],
- "Host": [
- "csrf.example:8080"
- ],
- "Origin": [
- "allowThisOne.example.com"
- ],
- "User-Agent": [
- "curl/7.77.0"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "b1b53950-f7b3-47e6-8b7b-45a44196f1c4"
- ]
- },
- "origin": "10.X.X.XX:33896",
- "url": "http://csrf.example:8080/post",
- "data": "",
- "files": null,
- "form": null,
- "json": null
- }
- ```
-
-## Monitor CSRF metrics
-
-1. Port-forward the gateway proxy.
- ```sh
- kubectl port-forward -n {{< reuse "agw-docs/snippets/namespace.md" >}} deploy/http 19000
- ```
-
-2. Open the [`/stats`](http://localhost:19000/stats) endpoint.
-
-3. Find the statistics for `csrf`.
-
- Example output:
-
- ```console
- http.http.csrf.missing_source_origin: 1
- http.http.csrf.request_invalid: 0
- http.http.csrf.request_valid: 1
- ...
- ```
-
- * `missing_source_origin`: The number of requests that were sent without an origin. The number is `1` because you sent the first request without an origin.
- * `request_invalid`: The number of requests that were sent with an origin that did not match the destination origin. The number is `0` because you did not send an invalid request.
- * `request_valid`: The number of requests that were sent with an origin that matched the destination origin. The number is `1` because you sent a valid request in your second request.
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} csrf -n httpbin
-```
diff --git a/assets/docs/pages/security/external-auth.md b/assets/docs/pages/security/external-auth.md
deleted file mode 100644
index b30614d86..000000000
--- a/assets/docs/pages/security/external-auth.md
+++ /dev/null
@@ -1,327 +0,0 @@
-Bring your own {{< gloss "External Authorization" >}}external authorization{{< /gloss >}} service to protect requests that go through your Gateway.
-
-## About external auth {#about}
-
-{{< reuse "/agw-docs/snippets/kgateway-capital.md" >}} lets you integrate your own external authorization service to your Gateway, based on the [Envoy external authorization filter](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/security/ext_authz_filter). Then, this external authorization service makes authorization decisions for requests that go through the Gateway, as shown in the following diagram.
-
-```mermaid
-sequenceDiagram
- participant Client
- participant Gateway
- participant Ext Auth
- participant Backend
-
- Client->>Gateway: 1. HTTP Request
- Gateway->>Ext Auth: 2. Authorization Request
- Ext Auth-->>Gateway: 3. Authorization Decision
-
- alt Authorized
- Gateway->>Backend: 4. Forward Request
- Backend-->>Gateway: Response
- Gateway-->>Client: Response
- else Not Authorized
- Gateway-->>Client: 5. 403 Forbidden
- end
-```
-
-1. The Client sends a request to the Gateway.
-2. The Gateway forwards the request to the Ext Auth service.
-3. The Ext Auth service makes a decision as to whether the request is authorized, based on headers, parameters, or other credentials.
-4. If authorized, the Gateway forwards the request to the Backend app, which then sends back a response to the Client through the Gateway.
-5. If not authorized, the Gateway rejects the request and by default returns a 403 Forbidden response to the Client.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Bring your own external authorization service {#byo-ext-auth}
-
-First, deploy your own external authorization service as a backend service that is accessible to kgateway. To do so, you configure a custom GatewayExtension resource that points to your external authorization service via gRPC.
-
-{{< callout type="info" >}}
-Keep in mind that your external authorization service must conform to the [Envoy external auth proto](https://github.com/envoyproxy/envoy/blob/main/api/envoy/service/auth/v3/external_auth.proto). The external authorization service also configures the conditions for authorizing a request, such as the inclusion of a certain header or other credentials.
-{{< /callout >}}
-
-{{< callout type="info" >}}
-Note that in the following example, resources are created in the same namespace to simplify setup. For example, the external auth service and GatewayExtension are in the same `{{< reuse "agw-docs/snippets/namespace.md" >}}` namespace, and the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, HTTPRoute, and backing Service for the sample app are in the same `httpbin` namespace. To create the resources in different namespaces, make sure that you set up a [Kubernetes ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) from the GatewayExtension to the Services that back the external auth service.
-{{< /callout >}}
-
-1. Deploy your external authorization service. The following example uses the [Istio external authorization service](https://github.com/istio/istio/tree/master/samples/extauthz) for quick testing purposes. This service is configured to allow requests with the `x-ext-authz: allow` header.
-
- ```yaml
- kubectl apply -f - <}}
- name: ext-authz
- labels:
- app: ext-authz
- spec:
- replicas: 1
- selector:
- matchLabels:
- app: ext-authz
- template:
- metadata:
- labels:
- app: ext-authz
- app.kubernetes.io/name: ext-authz
- spec:
- containers:
- - image: gcr.io/istio-testing/ext-authz:1.25-dev
- name: ext-authz
- ports:
- - containerPort: 9000
- EOF
- ```
-
-2. Create a Service for the Deployment that your proxy can access.
-
- ```yaml
- kubectl apply -f - <}}
- name: ext-authz
- labels:
- app: ext-authz
- spec:
- ports:
- - port: 4444
- targetPort: 9000
- protocol: TCP
- appProtocol: kubernetes.io/h2c
- selector:
- app: ext-authz
- EOF
- ```
-
-3. Create a GatewayExtension resource that points to your external authorization Service. Note that the GatewayExtension is created in the same namespace as the external auth service. To use a different namespace, make sure that you set up a [Kubernetes ReferenceGrant](https://gateway-api.sigs.k8s.io/api-types/referencegrant/) from the GatewayExtension to the Services that back the external auth service.
-
- ```yaml
- kubectl apply -f - <}}
- name: basic-ext-auth
- labels:
- app: ext-authz
- spec:
- type: ExtAuth
- extAuth:
- grpcService:
- backendRef:
- name: ext-authz
- port: 4444
- EOF
- ```
-
-## Create external auth policy {#create-policy}
-
-You can apply a policy at two levels: the Gateway level or the HTTPRoute level. If you apply the policy at both levels, the request must pass both policies to be authorized.
-
-1. Send a test request to the httpbin sample app. Verify that you get back a 200 HTTP response code and that no authorization is required.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- ...
- ```
-
-2. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that applies the GatewayExtension with external authorization at the Gateway level. Note that you can also set the `targetRefs` to select an HTTPRoute, which is demonstrated in later steps. Create the TrafficPolicy in the same namespace as the targeted resource.
-
- ```yaml
- kubectl apply -f - <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- name: gateway-ext-auth-policy
- labels:
- app: ext-authz
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- extAuth:
- extensionRef:
- name: basic-ext-auth
- EOF
- ```
-
-3. Repeat your request to the httpbin sample app and verify that the request is denied.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output: Note the 403 Forbidden response, along with the special `x-ext-authz*` headers that the Istio external authorization service adds to the request to explain the decision.
-
- ```txt
- HTTP/1.1 403 Forbidden
- x-ext-authz-check-result: denied
- x-ext-authz-check-received: source:{address:{socket_address:{address:"127.0.0.1" port_value:52492}}} destination:{address:{socket_address:{address:"127.0.0.1" port_value:8080}}} request:{time:{seconds:1743195078 nanos:842835000} http:{id:"6918845494626045094" method:"GET" headers:{key:":authority" value:"www.example.com"} headers:{key:":method" value:"GET"} headers:{key:":path" value:"/headers"} headers:{key:":scheme" value:"http"} headers:{key:"accept" value:"*/*"} headers:{key:"user-agent" value:"curl/8.7.1"} headers:{key:"x-envoy-external-address" value:"127.0.0.1"} headers:{key:"x-forwarded-for" value:"10.244.0.7"} headers:{key:"x-forwarded-proto" value:"http"} headers:{key:"x-request-id" value:"be03e2fd-4513-489e-8933-67b90c59815a"} path:"/headers" host:"www.example.com" scheme:"http" protocol:"HTTP/1.1"}} metadata_context:{} route_metadata_context:{}
- x-ext-authz-additional-header-override: grpc-additional-header-override-value
- content-length: 76
- content-type: text/plain
- date: Fri, 28 Mar 2025 20:51:18 GMT
- server: envoy
-
- denied by ext_authz for not found header `x-ext-authz: allow` in the request
- ```
-
-4. Send another request, this time with the `x-ext-authz: allow` header. The Istio external authorization service is configured to allow requests with this header. Therefore, the request succeeds.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080" -H "x-ext-authz: allow"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com" -H "x-ext-authz: allow"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output: Note that the 200 response with several `X-Ext-Authz*` headers that explain the decision.
-
- ```txt
- HTTP/1.1 200 OK
- ...
- ```
- ```json {hl_lines=[18,19,21,22,24,25,27,28]}
- {
- "headers": {
- "Accept": [
- "*/*"
- ],
- "Host": [
- "www.example.com"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Envoy-External-Address": [
- "127.0.0.1"
- ],
- "X-Ext-Authz": [
- "allow"
- ],
- "X-Ext-Authz-Additional-Header-Override": [
- "grpc-additional-header-override-value"
- ],
- "X-Ext-Authz-Check-Received": [
- "source:{address:{socket_address:{address:\"127.0.0.1\" port_value:41472}}} destination:{address:{socket_address:{address:\"127.0.0.1\" port_value:8080}}} request:{time:{seconds:1743195175 nanos:308379000} http:{id:\"2185898822670104560\" method:\"GET\" headers:{key:\":authority\" value:\"www.example.com\"} headers:{key:\":method\" value:\"GET\"} headers:{key:\":path\" value:\"/headers\"} headers:{key:\":scheme\" value:\"http\"} headers:{key:\"accept\" value:\"*/*\"} headers:{key:\"user-agent\" value:\"curl/8.7.1\"} headers:{key:\"x-envoy-external-address\" value:\"127.0.0.1\"} headers:{key:\"x-ext-authz\" value:\"allow\"} headers:{key:\"x-forwarded-for\" value:\"10.244.0.7\"} headers:{key:\"x-forwarded-proto\" value:\"http\"} headers:{key:\"x-request-id\" value:\"8fc7e284-7c09-4080-9500-f8da4495949d\"} path:\"/headers\" host:\"www.example.com\" scheme:\"http\" protocol:\"HTTP/1.1\"}} metadata_context:{} route_metadata_context:{}"
- ],
- "X-Ext-Authz-Check-Result": [
- "allowed"
- ],
- "X-Forwarded-For": [
- "10.244.0.7"
- ],
- "X-Forwarded-Proto": [
- "http"
- ],
- "X-Request-Id": [
- "8fc7e284-7c09-4080-9500-f8da4495949d"
- ]
- }
- }
- ```
-
-5. Create another {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to disable external authorization for a particular HTTPRoute. This way, requests that do not require external authorization, such as health checks, are allowed through while the external authorization service is still in place for requests to other routes on the Gateway.
-
- ```yaml
- kubectl apply -f - <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- namespace: httpbin
- name: route-ext-auth-policy
- labels:
- app: ext-authz
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin
- extAuth:
- disable: {}
- EOF
- ```
-
-
-
-6. Send a request without the `x-ext-authz` header and verify that you get back a 200 OK response. This time, the TrafficPolicy with the disabled external authorization service takes precedence so that the request is allowed through.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- ...
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} for the Gateway and HTTPRoute.
-
- ```sh
- kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} -A -l app=ext-authz
- ```
-
-2. Delete the sample external authorization service and GatewayExtension resource.
-
- ```sh
- kubectl delete gatewayextension,deployment,service -n {{< reuse "agw-docs/snippets/namespace.md" >}} -l app=ext-authz
- ```
-
-
-
-
diff --git a/assets/docs/pages/security/ratelimit/global.md b/assets/docs/pages/security/ratelimit/global.md
deleted file mode 100644
index 44d2695d8..000000000
--- a/assets/docs/pages/security/ratelimit/global.md
+++ /dev/null
@@ -1,456 +0,0 @@
-
-Configure global rate limiting rules across all of your Gateways to protect the backing services in your cluster.
-
-## About {#about}
-
-Global rate limiting in {{< reuse "agw-docs/snippets/kgateway.md" >}} is powered by [Envoy's rate limiting service protocol](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/rate_limit_filter). With global rate limiting, you can apply distributed, consistent rate limits across multiple Gateways. Unlike local rate limiting, which operates per Gateway instance, global rate limiting uses a central service to coordinate rate limits. Therefore, to use global rate limiting, you must bring your own rate limit service that implements the Envoy protocol.
-
-With your own rate limit service in place, you get benefits such as:
-
-- Coordinated rate limiting across multiple Gateways.
-- Centralized rate limit management with shared counters.
-- Dynamic descriptor-based rate limits that can consider multiple request attributes.
-- Consistent user experience, regardless of which Gateway receives the request.
-
-### Request flow
-
-Review the following sequence diagram to understand the request flow with global rate limiting.
-
-```mermaid
-sequenceDiagram
- participant Client
- participant Gateway
- participant RateLimiter
- participant App
-
- Client->>Gateway: 1. Send request to protected App
- Gateway->>Gateway: 2. Receive request
- Gateway->>RateLimiter: 3. Extract descriptors & send to Rate Limit Service
- RateLimiter->>RateLimiter: 4. Apply configured limits for descriptors
- RateLimiter->>Gateway: Return decision
- alt Request allowed
- Gateway->>App: 5. Forward request to App
- App->>Gateway: Return response
- Gateway->>Client: Return response to Client
- else Rate limit reached
- Gateway->>Client: 6. Deny request & return rate limit message
- end
-```
-
-1. The Client sends a request to an App that is protected by the Gateway.
-2. The Gateway receives the request.
-3. The Gateway extracts descriptors and sends them to the Rate Limit Service.
-4. The Rate Limit Service applies configured limits for those descriptors and returns a decision to the Gateway.
-5. If allowed, the Gateway forwards the request to the App.
-6. If the rate limit is reached, the Gateway denies the request and returns a message to the Client.
-
-### Architecture
-
-The global rate limiting feature consists of three components:
-
-1. **{{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with rateLimit.global**: Configure your rate limit policy in a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}. The rate limit policy includes the descriptors to extract from requests for the Gateway to send to the Rate Limit Service.
-2. **GatewayExtension**: Connect {{< reuse "/agw-docs/snippets/kgateway.md" >}} with the Rate Limit Service by using a kgateway GatewayExtension.
-3. **Rate Limit Service** - An external service that you set up to implement the Envoy Rate Limit protocol. The Rate Limit Service has the actual rate limit values to enforce on requests, based on the descriptors that the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} includes.
-
-### Response headers
-
-When rate limiting is enabled, {{< reuse "agw-docs/snippets/kgateway.md" >}} adds the following headers to responses. These headers help clients understand their current rate limit status and adapt their behavior accordingly.
-
-| Header | Description | Example |
-|--------|-------------|---------|
-| x-ratelimit-limit | The rate limit ceiling for the given request | `10, 10;w=60` (10 requests per 60 seconds) |
-| x-ratelimit-remaining | The number of requests left for the time window | `5` (5 requests remaining) |
-| x-ratelimit-reset | The time in seconds until the rate limit resets | `30` (rate limit resets in 30 seconds) |
-| x-envoy-ratelimited | Present when the request is rate limited | `true` |
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Step 1: Deploy your Rate Limit Service {#byo-rate-limit-service}
-
-You can bring your own rate limit service that implements the Envoy Rate Limit gRPC protocol.
-
-To get started, you can try out a demo rate limit service from the kgateway project. For more information, see the [GitHub repo](https://github.com/kgateway-dev/kgateway/tree/main/test/kubernetes/e2e/features/rate_limit/testdata).
-
-1. Create the `kgateway-test-extensions` namespace.
-
- ```sh
- kubectl create namespace kgateway-test-extensions
- ```
-
-2. Deploy the rate limit service.
-
- ```bash
- kubectl apply -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/rate_limit/global/testdata/rate-limit-server.yaml
- ```
-
-## Step 2: Define the rate limits {#rate-limits}
-
-Define the actual rate limit values (requests per unit time) in your Rate Limit Service. For example, using the [Envoy Rate Limit](https://github.com/envoyproxy/ratelimit) service, you configure the rate limits in its configuration file.
-
-The kgateway example that you deployed in the previous step includes the following rate limit configuration as a Kubernetes ConfigMap.
-
-```sh
-kubectl describe configmap ratelimit-config -n kgateway-test-extensions
-```
-
-{{< reuse "agw-docs/snippets/review-table.md" >}}
-
-| Field | Description |
-|-------|-------------|
-| domain | Required. A globally unique identifier to group together a set of rate limit rules. This way, different teams can have their own set of rate limits that don't conflict with each other. Later, you set the domain to use in the kgateway GatewayExtension. If you have different domains for different teams, each team can create their own GatewayExtension that their {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} can reference. |
-| descriptors | A list of key-value pairs that the Rate Limit Service uses to select which rate limit to use on matching requests. Descriptors are case-sensitive. |
-| key | Required. The name for the descriptor to use when matching requests. Later, you use the descriptor key in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to decide which rate limits to apply to requests. The Rate Limit Service expects one of the following values for the descriptor key: `remote_address` for a client IP address (`RemoteAddress` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), `path` for path matching (`Path` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), a key name for header matching (`Header` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}), or a custom key name for matching on a generic key-value pair (`Generic` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}). |
-| value | Optional. Each descriptor can have a value for more specific matching. For example, you might have two descriptor keys that are both for an `X-User-ID` header, but one also has a value of `user1`. This way, you can apply different rate limits to the specific value, such as to further restrict or permit a particular user. Similarly, you can take this approach for remote addresses, paths, and generic key-value pairs such as for `service` plans. |
-| rate_limit | Optional. The actual rate limit rule to apply. The example sets different rate limits for each descriptor key. If a descriptor key does not have a rate limit, the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} cannot apply a rate limit to requests, and the requests that match the descriptor are allowed. |
-| unit | The unit of time for the rate limit, such as `second`, `minute`, `hour`, or `day`. |
-| requests_per_unit | The number of requests to allow per unit of time. |
-
-Example output:
-
-```yaml
-Data
-====
-config.yaml:
-----
-domain: api-gateway
-descriptors:
- - key: remote_address
- rate_limit:
- unit: minute
- requests_per_unit: 1
- - key: path
- value: "/path1"
- rate_limit:
- unit: minute
- requests_per_unit: 1
- - key: path
- value: "/path2"
- rate_limit:
- unit: minute
- requests_per_unit: 2
- - key: X-User-ID
- rate_limit:
- unit: minute
- requests_per_unit: 1
- - key: X-User-ID
- value: user1
- rate_limit:
- unit: minute
- requests_per_unit: 1
- - key: service
- value: premium-api
- rate_limit:
- unit: minute
- requests_per_unit: 2
-
-
-BinaryData
-====
-```
-
-## Step 3: Create a GatewayExtension {#gateway-extension}
-
-Create a GatewayExtension resource that points to your Rate Limit Service.
-
-1. Create a GatewayExtension.
-
- ```yaml
- kubectl apply -f - <}}
- name: global-ratelimit
- spec:
- type: RateLimit
- rateLimit:
- grpcService:
- backendRef:
- name: ratelimit
- namespace: kgateway-test-extensions
- port: 8081
- domain: "api-gateway"
- timeout: "100ms"
- failOpen: false
- EOF
- ```
-
- {{% reuse "agw-docs/snippets/review-table.md" %}} For more information, see the [API docs](../../../reference/api/#ratelimitprovider).
-
- | Field | Description | Required |
- |-------|-------------|----------|
- | grpcService | Configuration for connecting to the gRPC rate limit service. | Yes |
- | domain | Domain identity for the rate limit service. If you have different domains for different teams, each team can create their own GatewayExtension that their own {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} can reference. | Yes |
- | timeout | Timeout for rate limit service calls, such as `100ms`. | No |
- | failOpen | When `true`, requests continue even if the rate limit service is unavailable. | No (defaults to `false`) |
-
-2. Create a Kubernetes ReferenceGrant to allow the GatewayExtension to access the Rate Limit Service. Otherwise, you can create the GatewayExtension and {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} in the same namespace as the Rate Limit Service.
-
- ```yaml
- kubectl apply -f - <}}
- to:
- - group: ""
- kind: Service
- EOF
- ```
-
-## Step 4: Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} {#traffic-policy}
-
-Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} resource that applies rate limits to your routes. Note that the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} must be in the same namespace as the GatewayExtension to select it.
-
-The {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} configures the descriptors that define the dimensions for rate limiting. Each descriptor consists of one or more entries that help categorize and count requests. The descriptor entries match on the descriptor keys that you defined previously in the Rate Limit Service.
-
-Entries can be of one of the following types: `RemoteAddress`, `Path`, `Header`, or `Generic`. You can combine different entry types so that they are applied together as a rate limit, such as `RemoteAddress` and `Generic` or `Header` and `Path`. The following table describes the different descriptor entry types. For more information, see the [API docs](../../reference/api/#ratelimitpolicy).
-
-| Type | Description | Additional Fields |
-|------|-------------|-------------------|
-| Header | Extract the descriptor value from a request header. The header name must match a descriptor key in the Rate Limit Service. | `header`: The name of the header to extract. |
-| Generic | Use a static key-value pair that you define as the descriptor. | `generic.key`: The descriptor key that matches the descriptor key in the Rate Limit Service. `generic.value`: The static value for more specific matching. |
-| Path | Use the request path as the descriptor value. The `Path` entry type is mapped to the `path` descriptor key in the Rate Limit Service. | None |
-| RemoteAddress | Use the client's IP address as the descriptor value. The `RemoteAddress` entry type is mapped to the `remote_address` descriptor key in the Rate Limit Service. | None |
-
-Flip through the tabs for different example rate limit policies. Note that the examples apply to the Gateway that you created before you began, but you can also apply a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to an HTTPRoute or specific route.
-
-{{< tabs tabTotal="5" items="Client IP address, Request path, User ID, Nested global rate limits, Local and global rate limits" >}}
-
-{{% tab tabName="Client IP address" %}}
-
-Limit requests based on the client's IP address.
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: ip-rate-limit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- global:
- descriptors:
- - entries:
- - type: RemoteAddress
- extensionRef:
- name: global-ratelimit
-EOF
-```
-
-{{% /tab %}}
-
-{{% tab tabName="Request path" %}}
-
-Limit requests based on the request path, such as a request with `/path1` or `/path2` in the path as defined in the example Rate Limit Service actions.
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: request-path
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- global:
- descriptors:
- - entries:
- - type: Path
- extensionRef:
- name: global-ratelimit
-EOF
-```
-
-{{% /tab %}}
-
-{{% tab tabName="User ID" %}}
-
-Limit requests based on a user ID from an `X-User-ID` header.
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: user-rate-limit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- global:
- descriptors:
- - entries:
- - type: Header
- header: "X-User-ID"
- extensionRef:
- name: global-ratelimit
-EOF
-```
-
-{{% /tab %}}
-
-{{% tab tabName="Nested global rate limits" %}}
-
-Apply different limits based on both path and user ID. The following example requires nested descriptors to rate limit requests along the path and header.
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: combined-rate-limit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- global:
- descriptors:
- - entries:
- - type: Path
- - type: Header
- header: "X-User-ID"
- extensionRef:
- name: global-ratelimit
-EOF
-```
-
-To rate limit based on `/path1` value for path and `user1` value for header, the matching Rate Limit Service must have nested descriptors as follows:
-
-```yaml
-descriptors:
- # Level 1: Path
- - key: path
- value: "/path1"
- descriptors:
- # Level 2: User ID (nested under path)
- - key: X-User-ID
- value: "user1"
- rate_limit:
- unit: minute
- requests_per_unit: 2
-```
-
-{{% /tab %}}
-
-{{% tab tabName="Local and global rate limits" %}}
-
-Combine local and global rate limiting in the same {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} such as in the following example. For more information, see [Local rate limiting](../local).
-
-* Local: A rate limit of 5 requests per second is applied to all requests.
-* Global: A rate limit of 2 requests per minute is applied to requests with a `service` descriptor key of `premium-api`.
-
-```yaml
-kubectl apply -f - <}}
-kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
-metadata:
- name: local-global-rate-limit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
-spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 5
- tokensPerFill: 1
- fillInterval: "1s"
- global:
- descriptors:
- - entries:
- - type: Generic
- generic:
- key: "service"
- value: "premium-api"
- extensionRef:
- name: global-ratelimit
-```
-
-{{% /tab %}}
-
-{{< /tabs >}}
-
-## Step 5: Test the rate limits {#test-rate-limits}
-
-Test the rate limits by sending requests to the Gateway. The following steps assume that you created the **client IP address** example {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}, which limits requests to 1 request per minute for a particular client IP address.
-
-1. Send a test request to the httpbin sample app. The request succeeds because you did not exceed the rate limit of 1 request per minute.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```txt
- HTTP/1.1 200 OK
- ...
- ```
-
-2. Repeat the request. The request fails because you exceeded the rate limit of 1 request per minute.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -i http://$INGRESS_GW_ADDRESS:8080/headers -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -i localhost:8080/headers -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- ```txt
- HTTP/1.1 429 Too Many Requests
- ...
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete -f https://raw.githubusercontent.com/kgateway-dev/kgateway/refs/heads/main/test/e2e/features/rate_limit/global/testdata/rate-limit-server.yaml
-kubectl delete gatewayextension global-ratelimit -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} ip-rate-limit user-rate-limit combined-rate-limit local-global-rate-limit -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
diff --git a/assets/docs/pages/security/ratelimit/local.md b/assets/docs/pages/security/ratelimit/local.md
deleted file mode 100644
index a2b509cad..000000000
--- a/assets/docs/pages/security/ratelimit/local.md
+++ /dev/null
@@ -1,408 +0,0 @@
-Limit the number of requests that are allowed to enter the cluster before global {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} and external auth policies are applied.
-
-## About {#about}
-
-Local {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} is a coarse-grained rate limiting capability that is primarily used as a first line of defense mechanism to limit the number of requests that are forwarded to your rate limit servers.
-
-Without local rate limiting, all requests are directly forwarded to a rate limit server that you set up where the request is either denied or allowed based on the global rate limiting settings that you configured. However, during an attack, too many requests might be forwarded to your rate limit servers and can cause overload or even failure.
-
-To protect your rate limit servers from being overloaded and to optimize their resource utilization, you can set up local rate limiting in conjunction with global rate limiting. Because local rate limiting is enforced in each Envoy instance that makes up your gateway, no rate limit server is required in this setup. For example, if you have 5 Envoy instances that together represent your gateway, each instance is configured with the limit that you set.
-
-For more information about local rate limiting, see the [Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/local_rate_limit_filter).
-
-### Architecture
-
-The following image shows how local rate limiting works in {{< reuse "/agw-docs/snippets/kgateway.md" >}}. As clients send requests to a backend destination, they first reach the Envoy instance that represents your gateway. Local rate limiting settings are applied to an Envoy pod or process. Note that limits are applied to each pod or process. For example, if you have 5 Envoy instances that are configured with a local rate limit of 10 requests per second, the total number of allowed requests per second is 50 (5 x 10). In a global rate limiting setup, this limit is shared between all Envoy instances, so the total number of allowed requests per second is 10.
-
-Depending on your setup, each Envoy instance or pod is configured with a number of tokens in a token bucket. To allow a request, a token must be available in the bucket so that it can be assigned to a downstream connection. Token buckets are refilled occasionally as defined in the refill setting of the local rate limiting configuration. If no token is available, the connection is closed immediately, and a 429 HTTP response code is returned to the client.
-
-When a token is available in the token bucket it can be assigned to an incoming connection. The request is then forwarded to your rate limit server to enforce any global rate limiting settings. For example, the request might be further rate limited based on headers or query parameters. Only requests that are within the local and global rate limits are forwarded to the backend destination in the cluster.
-
-{{< reuse-image src="/img/local-rate-limiting.svg" caption="Local rate limiting" width="600px" >}}
-{{< reuse-image-dark srcDark="/img/local-rate-limiting.svg" caption="Local rate limiting" width="600px" >}}
-
-### Local rate limiting
-
-In {{< reuse "agw-docs/snippets/kgateway.md" >}}, you use a [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}]({{< link-hextra path="/about/policies/trafficpolicy/" >}}) to set up local rate limiting for your routes. You can choose between the following attachment options:
-* **A particular route in an HTTPRoute resource**: Use the `extensionRef` filter in the HTTPRoute to attach the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to the route you want to rate limit. For an example, see [Route configuration](#route).
-* **All routes in an HTTPRoute**: Use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to attach the policy to a particular HTTPRoute resource.
-* **All routes that the Gateway serves**: Use the `targetRefs` section in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to attach the policy to a Gateway. For an example, see [Gateway configuration](#gateway).
-
-Note that if you apply a policy to an HTTPRoute and to a Gateway at the same time, the HTTPRoute policy takes precedence. For more information, see [{{< reuse "agw-docs/snippets/trafficpolicy.md" >}}]({{< link-hextra path="/about/policies/trafficpolicy/#multiple-targetrefs-TrafficPolicies" >}}).
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Route configuration {#route}
-
-Set up local rate limiting for a particular route.
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your local rate limiting settings.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: local-ratelimit
- namespace: httpbin
- spec:
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
- EOF
- ```
-
- | Setting | Description |
- | ------- | ----------- |
- | `maxTokens` | The maximum number of tokens that are available to use. |
- | `tokensPerFill` | The number of tokens that are added during a refill. |
- | `fillIntervall` | The number of seconds, after which the token bucket is refilled. |
-
-2. Create an HTTPRoute that limits requests to the httpbin app along the `ratelimit.example` domain. To apply the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that created earlier, you use the `extensionRef` filter.
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - ratelimit.example
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /
- filters:
- - type: ExtensionRef
- extensionRef:
- name: local-ratelimit
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-3. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/200 -H "host: ratelimit.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Request completely sent off
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- < access-control-allow-credentials: true
- access-control-allow-credentials: true
- < access-control-allow-origin: *
- access-control-allow-origin: *
- < content-length: 0
- content-length: 0
- < x-envoy-upstream-service-time: 1
- x-envoy-upstream-service-time: 1
- < server: envoy
- server: envoy
- ```
-
-4. Send another request to the httpbin app. Note that this time the request is denied with a 429 HTTP response code and a `local_rate_limited` message in your CLI output. Because the route is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. If you wait for 100 seconds, the token bucket is refilled and a new connection can be accepted by the route.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: ratelimit.example:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/200 -H "host: ratelimit.example"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- ...
- * Mark bundle as not supporting multiuse
- < HTTP/1.1 429 Too Many Requests
- HTTP/1.1 429 Too Many Requests
- < x-ratelimit-limit: 1
- x-ratelimit-limit: 1
- < x-ratelimit-remaining: 0
- x-ratelimit-remaining: 0
- < x-ratelimit-reset: 79
- x-ratelimit-reset: 79
- ...
- Connection #0 to host 34.XXX.XX.XXX left intact
- local_rate_limited
- ```
-
-## Gateway configuration {#gateway}
-
-Instead of applying local rate limiting to a particular route, you can also apply it to an entire gateway. This way, the local rate limiting settings are applied to all the routes that the gateway serves.
-
-1. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with your local rate limiting settings. Use the `targetRefs` section to apply the policy to a specific Gateway. The policy automatically applies to all the routes that the Gateway serves.
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: local-ratelimit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
- EOF
- ```
-
- | Setting | Description |
- | ------- | ----------- |
- | `targetRefs`| Select the Gateway that you want to apply your local rate limiting configuration to. In this example, the policy is applied to all the routes that the `http` gateway serves. |
- | `maxTokens` | The maximum number of tokens that are available to use. |
- | `tokensPerFill` | The number of tokens that are added during a refill. |
- | `fillIntervall` | The number of seconds, after which the token bucket is refilled. |
-
-3. Send a request to the httpbin app alongside the `www.example.com` domain that you set up as part of the getting started tutorial. Verify that the request succeeds.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/200 -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Request completely sent off
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- < access-control-allow-credentials: true
- access-control-allow-credentials: true
- < access-control-allow-origin: *
- access-control-allow-origin: *
- < content-length: 0
- content-length: 0
- < x-envoy-upstream-service-time: 1
- x-envoy-upstream-service-time: 1
- < server: envoy
- server: envoy
- ```
-
-4. Send another request to the httpbin app. Note that this time the request is denied with a 429 HTTP response code and a `local_rate_limited` message in your CLI output. Because the gateway is configured with only 1 token that is refilled every 100 seconds, the token was assigned to the connection of the first request. No tokens were available to be assigned to the second request. If you wait for 100 seconds, the token bucket is refilled and a new connection can be accepted by the gateway.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: www.example.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/200 -H "host: www.example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- ...
- * Mark bundle as not supporting multiuse
- < HTTP/1.1 429 Too Many Requests
- HTTP/1.1 429 Too Many Requests
- < x-ratelimit-limit: 1
- x-ratelimit-limit: 1
- < x-ratelimit-remaining: 0
- x-ratelimit-remaining: 0
- < x-ratelimit-reset: 79
- x-ratelimit-reset: 79
- ...
- Connection #0 to host 34.XXX.XX.XXX left intact
- local_rate_limited
- ```
-
-## Disable rate limiting for a route {#disable-route}
-
-Sometimes, you might want to disable {{< gloss "Rate Limiting" >}}rate limiting{{< /gloss >}} for a route. For example, you might have system critical routes that should be accessible even under high traffic conditions, such as a health check or admin endpoints. You can exclude a route from rate limiting by setting `rateLimit.local` to `{}` in the {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}.
-
-1. Create a Gateway-level {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to enforce local rate limiting on all routes. For more information, refer to the [Gateway configuration](#gateway).
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: local-ratelimit
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- rateLimit:
- local:
- tokenBucket:
- maxTokens: 1
- tokensPerFill: 1
- fillInterval: 100s
- EOF
- ```
-
-2. Create an HTTPRoute for the route that you want to exclude from rate limiting, such as `/anything` on the `httpbin` app. Note that because no {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} applies to this HTTPRoute yet, the Gateway-level rate limit policy is enforced for the `/anything` route.
-
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - www.example.com
- rules:
- - matches:
- - path:
- type: PathPrefix
- value: /anything
- backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-3. Send two requests to verify that the route is rate limited due to the Gateway-level {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that allows only 1 request per 100 seconds.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- for i in {1..2}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- for i in {1..2}; do curl -vi localhost:8080/anything -H "host: www.example.com"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output: Verify that the first request succeeds and the second request is rate limited.
-
- Request 1:
- ```
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ...
- ```
-
- Request 2:
- ```
- < HTTP/1.1 429 Too Many Requests
- HTTP/1.1 429 Too Many Requests
- < x-ratelimit-limit: 1
- x-ratelimit-limit: 1
- < x-ratelimit-remaining: 0
- x-ratelimit-remaining: 0
- < x-ratelimit-reset: 79
- x-ratelimit-reset: 79
- ...
- Connection #0 to host 34.XXX.XX.XXX left intact
- local_rate_limited
- ```
-
-4. Create a {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} to disable rate limiting for the HTTPRoute.
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}}
- metadata:
- name: disable-ratelimit
- namespace: httpbin
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: HTTPRoute
- name: httpbin-anything
- rateLimit:
- local: {}
- EOF
- ```
-
-5. Repeat the requests. This time, the requests succeed because the HTTPRoute is excluded from rate limiting.
-
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- for i in {1..2}; do curl -vi http://$INGRESS_GW_ADDRESS:8080/anything -H "host: www.example.com:8080"; done
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- for i in {1..2}; do curl -vi localhost:8080/anything -H "host: www.example.com"; done
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
-
- Request 1:
- ```
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ...
- ```
-
- Request 2:
- ```
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ...
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} local-ratelimit -n httpbin
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} local-ratelimit -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} disable-ratelimit -n httpbin
-kubectl delete httproute httpbin-ratelimit -n httpbin
-kubectl delete httproute httpbin-anything -n httpbin
-```
-
-
-
-
diff --git a/assets/docs/pages/setup/additional-settings.md b/assets/docs/pages/setup/additional-settings.md
deleted file mode 100644
index 0bf510cf5..000000000
--- a/assets/docs/pages/setup/additional-settings.md
+++ /dev/null
@@ -1,59 +0,0 @@
-Annotate your Gateway listener to enable additional TLS settings, such as the minimum and maximum TLS version, cipher suites, or allowed certificate hashes.
-
-```yaml
-apiVersion: gateway.networking.k8s.io/v1
-kind: Gateway
-metadata:
- name: example-gateway
- namespace: default
-spec:
- gatewayClassName: kgateway
- listeners:
- - name: https
- protocol: HTTPS
- port: 443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- - name: https-mtls-strict-validation
- protocol: HTTPS
- port: 8443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- options:
- kgateway.dev/alpn-protocols: "h2"
- kgateway.dev/cipher-suites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
- kgateway.dev/ecdh-curves: "X25519,P-256"
- kgateway.dev/min-tls-version: "1.2"
- kgateway.dev/max-tls-version: "1.3"
- kgateway.dev/verify-subject-alt-names: "example.com"
- kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B"
- - name: https-insecure-fallback
- protocol: HTTPS
- port: 9443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
-```
-
-
-The following settings are supported:
-
-| Setting | Description |
-| -- | -- |
-| `kgateway.dev/alpn-protocols` | A comma-delimited list of the application protocol that the Gateway can use during a TLS handshake. In this example, HTTP/2 is used.|
-| `kgateway.dev/cipher-suites` | A comma-delimited list of the cipher suites that the Gateway can use during a TLS handshake. The example shows the TLSv1_2 and TLSv1_3 cipher suites.|
-| `kgateway.dev/ecdh-curves` | A comma-delimited list of key exchange protocols. If unset, the Envoy default of `X25519` and `P-256` are used. When adding a new protocol to this list, ensure it is backwards compatible in the case that the client does not specifically support the new protocol. This example adds the Post-Quantum safe key exchange protocol `X25519MLKEM768`, but falls back to the classic `X25519` or `P-256` protocols if the client does not support it. If you want to allow only the Post-Quantum safe protocol, remove the safe protocols and specify `X25519MLKEM768` only. |
-| `kgateway.dev/min-tls-version` | Enforce a minimum TLS version for the listener to use. In this example, TLS version 1.2 is used. |
-| `kgateway.dev/max-tls-version` | Enforce a maximum TLS version for the Gateway to use. In this example, TLS version 1.3 is used. |
-| `kgateway.dev/verify-certificate-hash` | A comma-delimited list of the certificate hash (fingerprint) that must be present in the peer certificate that is presented during the TLS handshake. Use this setting for [mTLS listeners]({{< link-hextra path="/setup/listeners/mtls/" >}}) only. |
-| `kgateway.dev/verify-subject-alt-names` | A comma-delimited list of the Subject Alternative Names that must be present in the peer certificate that is presented during the TLS handshake. Use this setting for [mTLS listeners]({{< link-hextra path="/setup/listeners/mtls/" >}}) only. |
-
-
diff --git a/assets/docs/pages/setup/customize.md b/assets/docs/pages/setup/customize.md
deleted file mode 100644
index 75c574248..000000000
--- a/assets/docs/pages/setup/customize.md
+++ /dev/null
@@ -1,167 +0,0 @@
-The configuration that is used to spin up a gateway proxy is stored in several custom resources, including {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}, and a gateway proxy template. By default, {{< reuse "agw-docs/snippets/kgateway.md" >}} creates these resources for you during the installation so that you can spin up gateway proxies with the [default proxy configuration]({{< link-hextra path="/setup/default/" >}}). You have the following options to change the default configuration for your gateway proxies:
-
-| Option | Description |
-| -- | -- |
-| Create your own {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource (recommended) | To adjust the settings on the gateway proxy, you can create your own {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. This approach allows you to spin up gateway proxies with different configurations. Keep in mind that you must maintain the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources that you created manually. The values in these resources are not automatically updated during upgrades. |
-| Change default proxy settings | You can change some of the values for the default gateway proxy updating the values in the {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart. The values that you set in your Helm chart are automatically rolled out to the gateway proxies. |
-| Create self-managed gateways with custom proxy templates | {{< reuse "agw-docs/snippets/byo-gateway.md" >}} |
-
-## Customize the gateway proxy
-
-The example in this guide uses the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to change settings on the gateway proxy. To find other customization examples, see the [Gateway customization guides]({{< link-hextra path="/setup/customize/" >}}).
-
-1. Create a {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource to add any custom settings to the gateway. The following example makes the following changes:
-
- * The Envoy log level is set to `debug` (default value: `info`).
- * The Kubernetes service type is changed to NodePort (default value: `LoadBalancer`).
- * The `gateway: custom` label is added to the gateway proxy service that exposes the proxy (default value: `gloo=kube-gateway`).
- * The `externalTrafficPolicy` is set to `Local` to preserve the original client IP address.
- * The `gateway: custom` label is added to the gateway proxy pod (default value: `gloo=kube-gateway` ).
- * The security context of the gateway proxy is changed to use the 50000 as the supplemental group ID and user ID (default values: `10101` ).
-
- For other settings, see the [API docs]({{< link-hextra path="/reference/api/#gatewayparametersspec" >}}) or check out the [Gateway customization guides]({{< link-hextra path="/setup/customize/" >}}).
-
- ```yaml
- kubectl apply -f- <}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- metadata:
- name: custom-gw-params
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- spec:
- kube:
- envoyContainer:
- bootstrap:
- logLevel: debug
- service:
- type: NodePort
- extraLabels:
- gateway: custom
-
- externalTrafficPolicy: Local
-
- podTemplate:
- extraLabels:
- gateway: custom
- securityContext:
- fsGroup: 50000
- runAsUser: 50000
- EOF
- ```
-
-2. Create a Gateway resource that references your custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- infrastructure:
- parametersRef:
- name: custom-gw-params
- group: {{< reuse "agw-docs/snippets/trafficpolicy-group.md" >}}
- kind: {{< reuse "agw-docs/snippets/gatewayparameters.md" >}}
- listeners:
- - protocol: HTTP
- port: 80
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-3. Verify that a pod is created for your gateway proxy and that it has the pod settings that you defined in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource.
-
- ```sh
- kubectl get pods -l app.kubernetes.io/name=custom -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml
- ```
-
- If the pod does not come up, try running `kubectl get events -n kgateway-system` to see if the Kubernetes API server logged any failures. If no events are logged, ensure that the `kgateway` GatewayClass is present in your cluster and that the Gateway resource shows an `Accepted` status.
-
- Example output:
-
- ```yaml {linenos=table,hl_lines=[13,20,21,22],linenostart=1,filename="gateway-pod.yaml"}
- apiVersion: v1
- kind: Pod
- metadata:
- annotations:
- prometheus.io/path: /metrics
- prometheus.io/port: "9091"
- prometheus.io/scrape: "true"
- creationTimestamp: "2024-08-07T19:47:27Z"
- generateName: custom-7d9bf46f96-
- labels:
- app.kubernetes.io/instance: custom
- app.kubernetes.io/name: custom
- gateway: custom
- gateway.networking.k8s.io/gateway-name: custom
- kgateway: kube-gateway
- ...
- priority: 0
- restartPolicy: Always
- schedulerName: default-scheduler
- securityContext:
- fsGroup: 50000
- runAsUser: 50000
- ...
- ```
-
-4. Get the details of the service that exposes the gateway proxy. Verify that the service is of type NodePort and that the extra label was added to the service.
-
- ```sh
- kubectl get service custom -n kgateway-system -o yaml
- ```
-
- Example output:
-
- ```yaml {linenos=table,hl_lines=[10,36],linenostart=1,filename="gateway-service.yaml"}
- apiVersion: v1
- kind: Service
- metadata:
- creationTimestamp: "2024-08-07T19:47:27Z"
- labels:
- app.kubernetes.io/instance: custom
- app.kubernetes.io/managed-by: Helm
- app.kubernetes.io/name: custom
- app.kubernetes.io/version: kgateway-proxy-v{{< reuse "agw-docs/versions/n-patch.md" >}}
- gateway: custom
- gateway.networking.k8s.io/gateway-name: custom
- kgateway: kube-gateway
- helm.sh/chart: kgateway-proxy-v{{< reuse "agw-docs/versions/n-patch.md" >}}
- name: custom
- namespace: kgateway-system
- ownerReferences:
- - apiVersion: gateway.networking.k8s.io/v1
- controller: true
- kind: Gateway
- name: custom
- uid: d29417ba-60f9-410c-a023-283b250f3d57
- resourceVersion: "7371789"
- uid: 67945b5f-e55f-42bb-b5f2-c35932659831
- spec:
- ports:
- - name: http
- nodePort: 30579
- port: 80
- protocol: TCP
- targetPort: 8080
- selector:
- app.kubernetes.io/instance: custom
- app.kubernetes.io/name: custom
- gateway.networking.k8s.io/gateway-name: custom
- sessionAffinity: None
- type: NodePort
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete gateway custom -n kgateway-system
-kubectl delete {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} custom-gw-params -n kgateway-system
-```
diff --git a/assets/docs/pages/setup/customize/aws-elb/alb.md b/assets/docs/pages/setup/customize/aws-elb/alb.md
deleted file mode 100644
index 8543147d7..000000000
--- a/assets/docs/pages/setup/customize/aws-elb/alb.md
+++ /dev/null
@@ -1,183 +0,0 @@
-In this guide you explore how to expose the kgateway proxy with an AWS application load balancer (ALB).
-
-{{< callout type="warning" >}}
-The AWS Load Balancer Controller only supports the creation of an ALB through an Ingress Controller and not through the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}. Because of this, you must create the ALB separately through an Ingress resource that connects it to the service that exposes your gateway proxy.
-{{< /callout >}}
-
-## Before you begin
-
-1. Create or use an existing AWS account.
-2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway. You do not need to set up a Gateway as you create a custom Gateway as part of this guide.
-3. Follow the [Sample app guide]({{< link-hextra path="/install/sample-app/" >}}) to deploy the httpbin sample app.
-
-## Step 1: Deploy gateway proxy resources
-
-1. Create a Gateway resource with an HTTP listener. You later pair this Gateway with an AWS ALB.
- ```yaml
- kubectl apply -n kgateway-system -f- <}}
-
-5. Use an Ingress resource to define your ALB. When you apply this resource, the AWS Load Balancer Controller creates the ALB in your account.
- ```yaml
- kubectl apply -f- <}}
- If you later change your Ingress resource configuration, you might need to delete and re-create your Ingress resource for AWS to pick up the changes.
- {{< /callout >}}
-
-6. Review the load balancer in the AWS EC2 dashboard.
- 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2).
- 2. In the left navigation, go to **Load Balancing > Load Balancers**.
- 3. Find and open the ALB that was created for you, with a name such as `k8s-gateway-alb-`. Note that it might take a few minutes for the ALB to provision.
- 4. On the **Resource map** tab, verify that the load balancer points to healthy EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name.
- {{< reuse-image src="img/alb.png" >}}
- {{< reuse-image-dark srcDark="img/alb.png" >}}
-
-## Step 3: Test the ALB
-
-1. In the **Details** pane of the ALB, get the **DNS name** that was assigned to your ALB and save it as an environment variable.
- ```sh
- export INGRESS_GW_ADDRESS=
- ```
-
-2. Send a request to the httpbin app. Verify that you get back a 200 HTTP response code.
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:80/headers -H "host: albtest.com:80"
- ```
-
- Example output:
- ```console
- ...
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the Ingress, HTTPRoute, DirectResponse, and Gateway resources.
- ```sh
- kubectl delete ingress alb -n kgateway-system
- kubectl delete httproute httpbin-alb -n httpbin
- kubectl delete httproute httpbin-healthcheck -n httpbin
- kubectl delete directresponse httpbin-healthcheck-dr -n httpbin
- kubectl delete gateway alb -n kgateway-system
- ```
-
-2. Delete the AWS IAM resources that you created.
- ```sh
- aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME}
- eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME}
- ```
-
-3. Uninstall the Helm release for the `aws-load-balancer-controller`.
- ```sh
- helm uninstall aws-load-balancer-controller -n kube-system
- ```
-
-
-
-
-
diff --git a/assets/docs/pages/setup/customize/aws-elb/nlb.md b/assets/docs/pages/setup/customize/aws-elb/nlb.md
deleted file mode 100644
index 9eeeb5e9b..000000000
--- a/assets/docs/pages/setup/customize/aws-elb/nlb.md
+++ /dev/null
@@ -1,293 +0,0 @@
-In this guide you explore how to expose the kgateway proxy with an AWS network load balancer (NLB). The following use cases are covered:
-
-* **NLB HTTP**: Create an HTTP listener on the NLB that exposes an HTTP endpoint on your gateway proxy. Traffic from the NLB to the proxy is not secured.
-* **TLS passthrough**: Expose an HTTPS endpoint of your gateway with an NLB. The NLB passes through HTTPS traffic to the gateway proxy where the traffic is terminated.
-
-{{< callout type="warning" >}}
-Keep in mind the following considerations when working with an NLB:
-* An AWS NLB has an idle timeout of 350 seconds that you cannot change. This limitation can increase the number of reset TCP connections.
-{{< /callout >}}
-
-## Before you begin
-
-1. Create or use an existing AWS account.
-2. Follow the [Get started guide]({{< link-hextra path="/quickstart/" >}}) to install kgateway, set up a gateway resource, and deploy the httpbin sample app.
-
-## Step 1: Deploy the AWS Load Balancer controller
-
-{{< reuse "agw-docs/snippets/aws-elb-controller-install.md" >}}
-
-## Step 2: Deploy your gateway proxy
-
-1. Create a GatewayParameters resource with custom AWS annotations. These annotations instruct the AWS load balancer controller to expose the gateway proxy with a public-facing AWS NLB.
- ```yaml
- kubectl apply -f- <}}
- {{% tab %}}
-
- Create a simple NLB that accepts HTTP traffic on port 80 and forwards this traffic to the HTTP listener on your gateway proxy.
-
- {{< reuse-image src="/img/elb-http.svg" >}}
- {{< reuse-image-dark srcDark="/img/elb-http.svg" >}}
-
- This Gateway resource references the custom GatewayParameters resource that you created.
- ```yaml
- kubectl apply -f- <}}
- {{< reuse-image-dark srcDark="/img/elb-tls-passthrough.svg" >}}
-
- 1. Create a self-signed TLS certificate to configure your gateway proxy with an HTTPS listener.
- {{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}}
-
- 2. Create a Gateway with an HTTPS listener that terminates incoming TLS traffic. Make sure to reference the custom GatewayParameters resource and the Kubernetes secret that contains the TLS certificate information.
- ```yaml
- kubectl apply -f- <}}
-
-3. Verify that your gateway is created.
- ```sh
- kubectl get gateway aws-cloud -n kgateway-system
- ```
-
-4. Verify that the gateway service is exposed with an AWS NLB and assigned an AWS hostname.
- ```sh
- kubectl get services aws-cloud -n kgateway-system
- ```
-
- Example output:
- ```console
- NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
- aws-cloud LoadBalancer 172.20.39.233 k8s-kgateway-awscloud-edaaecf0c5-2d48d93624e3a4bf.elb.us-east-2.amazonaws.com 80:30565/TCP 12s
- ```
-
-5. Review the NLB in the AWS EC2 dashboard.
- 1. Go to the [AWS EC2 dashboard](https://console.aws.amazon.com/ec2).
- 2. In the left navigation, go to **Load Balancing > Load Balancers**.
- 3. Find and open the NLB that was created for you, with a name such as `k8s-kgateway-awscloud-`.
- 4. On the **Resource map** tab, verify that the load balancer points to EC2 targets in your cluster. For example, you can click on the target EC2 name to verify that the instance summary lists your cluster name.
-
-## Step 3: Test traffic to the NLB {#test-traffic}
-
-{{< tabs items="Simple HTTP NLB,TLS passthrough" >}}
-{{% tab %}}
-
-1. Create an HTTPRoute resource and associate it with the gateway that you created.
- ```yaml
- kubectl apply -f- <}}
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Delete the Ingress and Gateway resources.
- ```sh
- kubectl delete gatewayparameters custom-gw-params -n kgateway-system
- kubectl delete gateway aws-cloud -n kgateway-system
- kubectl delete httproute httpbin-elb -n httpbin
- kubectl delete secret tls -n kgateway-system
- ```
-
-2. Delete the AWS IAM resources that you created.
- ```sh
- aws iam delete-policy --policy-arn=arn:aws:iam::${AWS_ACCOUNT_ID}:policy/${IAM_POLICY_NAME}
- eksctl delete iamserviceaccount --name=${IAM_SA} --cluster=${CLUSTER_NAME}
- ```
-
-3. Uninstall the Helm release for the `aws-load-balancer-controller`.
- ```sh
- helm uninstall aws-load-balancer-controller -n kube-system
- ```
-
-
-
-
-
diff --git a/assets/docs/pages/setup/default.md b/assets/docs/pages/setup/default.md
deleted file mode 100644
index e85725d24..000000000
--- a/assets/docs/pages/setup/default.md
+++ /dev/null
@@ -1,29 +0,0 @@
-Learn about the different {{< reuse "agw-docs/snippets/kgateway.md" >}} and Kubernetes resources that make up your gateway proxy deployment.
-
-## GatewayClass
-
-The GatewayClass is a {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}}-native resource that defines the controller that spins up and configures gateway proxies in your environment.
-
-When you install {{< reuse "agw-docs/snippets/kgateway.md" >}}, the following GatewayClass resources are automatically created with the following configuration.
-
-{{< reuse "agw-docs/snippets/class-setup.md" >}}
-
-## Gateway proxy template
-
-When you create a Gateway resource, a default gateway proxy template for [agentgateway](https://github.com/kgateway-dev/kgateway/blob/{{< reuse "agw-docs/versions/github-branch.md" >}}/pkg/kgateway/helm/agentgateway/templates/deployment.yaml) proxies is used to automatically spin up and bootstrap a gateway proxy deployment and service in your cluster. The template includes agentgateway configuration that binds the gateway proxy deployment to the Gateway resource that you created. In addition, the settings in the [{{< reuse "agw-docs/snippets/gatewayparameters.md" >}}](#gatewayparameters) resource are used to configure the gateway proxy.
-
-The resulting gateway proxy is managed for you and its configuration is automatically updated based on the settings in the GatewayParameters resource. To publicly expose the gateway proxy deployment, a service of type LoadBalancer is created for you. Depending on the cloud provider that you use, the LoadBalancer service is assigned a public IP address or hostname that you can use to reach the gateway. To expose an app on the gateway, you must create an HTTPRoute resource and define the matchers and filter rules that you want to apply before forwarding the request to the app in your cluster. You can review the [Get started]({{< link-hextra path="/quickstart/" >}}), [traffic management]({{< link-hextra path="/traffic-management/" >}}), [security]({{< link-hextra path="/security/" >}}), and [resiliency]({{< link-hextra path="/resiliency/" >}}) guides to find examples for how to route and secure traffic to an app.
-
-You can change the default configuration of your gateway proxy by creating custom {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources, or updating the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} values in your {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart. If you change the values in the Helm chart, {{< reuse "agw-docs/snippets/kgateway.md" >}} automatically applies the changes to the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resources.
-
-{{< callout type="info" >}}
-Do not edit or change the default {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource directly. Always update the values in the {{< reuse "agw-docs/snippets/kgateway.md" >}} Helm chart so that they persist between upgrades.
-{{< /callout >}}
-
-## {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} {#gatewayparameters}
-
-{{< reuse "agw-docs/snippets/gatewayparameters-about.md" >}}
-
-## Reserved ports
-
-{{< reuse "agw-docs/snippets/reserved-ports.md" >}}
diff --git a/assets/docs/pages/setup/hpa.md b/assets/docs/pages/setup/hpa.md
deleted file mode 100644
index 4aba3b404..000000000
--- a/assets/docs/pages/setup/hpa.md
+++ /dev/null
@@ -1,99 +0,0 @@
-You can bring your own Horizontal Pod Autoscaler (HPA) plug-in to {{< reuse "agw-docs/snippets/kgateway.md" >}}. This way, you can automatically scale gateway proxy pods up and down based on certain thresholds, like memory and CPU consumption.
-
-To allow integration with HPA plug-ins, do not specify any custom replicas in the {{< reuse "agw-docs/snippets/gatewayparameters.md" >}} resource. This way, your HPA plug-in can scale the proxy based on your autoscaling strategy.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq.md" >}}
-
-## Set up your own HPA plug-in
-
-1. Deploy the Kubernetes `metrics-server` in your cluster. The `metrics-server` retrieves metrics, such as CPU and memory consumption for your workloads. These metrics can be used by the HPA plug-in to determine if the pod must be scaled up or down.
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
- kubectl -n kube-system patch deployment metrics-server \
- --type=json \
- -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
- ```
-
- Example output:
- ```console
- serviceaccount/metrics-server created
- clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
- clusterrole.rbac.authorization.k8s.io/system:metrics-server created
- rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
- clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server:system:auth-delegator created
- clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
- service/metrics-server created
- deployment.apps/metrics-server configured
- apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
- ```
-
-2. Review the metrics for the http Gateway.
- ```sh
- kubectl top pod -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep http
- ```
-
- Example output:
- ```
- http-594455765c-5szpq 3m 19Mi
- ```
-
-6. Create a HorizontalPodAutoscaler resource that scales your gateway proxy up to 10 replicas if the memory consumption exceeds 10Mi. You can adjust this value depending on the memory value that you retrieved in the previous step.
- ```yaml
- kubectl apply -f- <}}
- spec:
- scaleTargetRef:
- apiVersion: apps/v1
- kind: Deployment
- name: http
- minReplicas: 1
- maxReplicas: 10
- metrics:
- - type: Resource
- resource:
- name: memory
- target:
- type: AverageValue
- averageValue: 10Mi
- EOF
- ```
-
-7. Wait a few minutes for Kubernetes to scale up your gateway proxies. Then, check the number of `http` pods that were created. Because every pod exceeds the memory threshold that you defined in the HPA policy, Kubernetes scales up the pods to the 10 maximum replicas.
- ```sh
- kubectl top pod -n {{< reuse "agw-docs/snippets/namespace.md" >}} | grep http
- ```
-
- Example output:
- ```
- http-594455765c-5szpq 3m 19Mi
- http-594455765c-gvf9g 3m 19Mi
- http-594455765c-h2zb9 3m 19Mi
- http-594455765c-mghsf 3m 19Mi
- http-594455765c-n6prj 3m 19Mi
- http-594455765c-nvs6c 3m 19Mi
- http-594455765c-srfcz 3m 19Mi
- http-594455765c-ssvjx 3m 19Mi
- http-594455765c-tx2z6 3m 19Mi
- http-594455765c-vxjbp 3m 19Mi
- ```
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete hpa hpa -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
-```
-
-
-
-
-
diff --git a/assets/docs/pages/setup/http10.md b/assets/docs/pages/setup/http10.md
deleted file mode 100644
index e78f5963b..000000000
--- a/assets/docs/pages/setup/http10.md
+++ /dev/null
@@ -1,62 +0,0 @@
-Configure your gateway proxy to accept older HTTP protocols.
-
-## About HTTP/1.0 and HTTP/0.9
-
-By default, Envoy-based gateway proxies return a 426 Upgrade Required HTTP response code for HTTP/1.0 and HTTP/0.9 requests. HTTP/0.9 was a simple, rudimentary protocol that was introduced in 1991 and supported only the `GET` HTTP method. Other methods, such as `POST`, `PUT`, and `DELETE` were later introduced in HTTP/1.0.
-
-Both protocol versions are rarely used nowadays. However, some applications might still require support for these versions for backwards compatibililty. To allow the gateway proxy to accept these types of requests, you can create an HTTPListenerPolicy and attach it to your Gateway.
-
-{{< callout >}}
-{{< reuse "agw-docs/snippets/proxy-kgateway.md" >}}
-{{< /callout >}}
-
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq-listeners.md" >}}
-
-## Set up HTTP 1.0 support
-
-1. Create an HTTPListenerPolicy with the `acceptHttp10` field. In the `targetRefs`, attach the policy to the Gateway that you want to support the HTTP/1.0 protocol.
- ```yaml
- kubectl apply -f- <}}
- spec:
- targetRefs:
- - group: gateway.networking.k8s.io
- kind: Gateway
- name: http
- acceptHttp10: true
- EOF
- ```
-
-2. Port-forward the gateway proxy on port 19000 to open the Envoy admin interface.
- ```sh
- kubectl port-forward deploy/http -n {{< reuse "agw-docs/snippets/namespace.md" >}} 19000
- ```
-
-3. Open the [Envoy admin interface](http://localhost:19000/config_dump) and look for the `http_protocol_options` filter in your Envoy filter chain. Then, verify that the `accept_http_10` field is set to `true`.
-
- Example output:
- ```console
- "http_protocol_options": {
- "accept_http_10": true
- }
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete httplistenerpolicy accept-http10 -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-```
-
-
-
-
-
diff --git a/assets/docs/pages/setup/listener-mtls.md b/assets/docs/pages/setup/listener-mtls.md
deleted file mode 100644
index 4ed47a9c0..000000000
--- a/assets/docs/pages/setup/listener-mtls.md
+++ /dev/null
@@ -1,731 +0,0 @@
-Add a [FrontendTLSConfig](https://gateway-api.sigs.k8s.io/reference/1.4/spec/#frontendtlsconfig) to a Gateway to create a mutual TLS (mTLS) listener.
-
-## About FrontendTLS
-
-When configuring an mTLS listener on a Gateway, the client application and the Gateway must exchange certificates to verify their identities before a connection can be established. After a TLS connection is established, the TLS connection is terminated at the Gateway and the unencrypted HTTP traffic is forwarded to the backend destination.
-
-FrontendTLS supports the following configurations:
-
-* **Default (required)**: Create the default client certificate validation configuration for all Gateway listeners that handle HTTPS traffic. For an example, see the [Default configuration for all listeners](#default) guide.
-* **perPort (optional)**: Override the default configuration with port-specific configuration. The configuration is applied only to matching ports that handle HTTPS traffic. For all other ports that handle HTTPS traffic, the default configuration continues to apply. For an example, see the [Per port configuration](#perport) guide.
-
-In addition, you can choose between the following validation modes:
-* **AllowValidOnly**: A connection between a client and the gateway proxy can only be established if the gateway can validate the client's TLS certificate successfully. For an example, see the [Default configuration for all listeners](#default) guide.
-* **AllowInsecureFallback**: The gateway proxy can establish a TLS connection, even if the client TLS certificate could not be validated successfully. For an example, see the [Per port configuration](#perport) guide.
-
-## About this guide
-
-In this guide, you learn how to apply default certificate validation configuration for all HTTPS listeners on a Gateway and how to override this configuration for a specific port. You further explore secure and insecure certificate validation modes, and use TLS annotations to limit connections to clients that present certificates with a specific Subject Alt Name and certificate hash.
-
-Throughout this guide, you use self-signed TLS certificates for the Certificate Authority. These certificates are used to sign the TLS certificates for the gateway proxy (server) and httpbin client.
-
-{{< callout type="warning" >}}
-Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trust Certificate Authority.
-{{< /callout >}}
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/cert-prereqs.md" >}}
-
-5. Install the experimental channel of the Kubernetes Gateway API. This API is required to use the FrontendTLS configuration on a Gateway.
- ```sh
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml
- ```
-
-
-## Create TLS certificates
-
-Create self-signed TLS certificates that you use for the mutual TLS connection between your client application (`curl`) and the gateway proxy.
-
-{{< callout type="warning" >}}
-Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trust Certificate Authority.
-{{< /callout >}}
-
-
-
-1. Create the `example_certs` directory and navigate into this directory.
- ```sh
- mkdir example_certs && cd example_certs
- ```
-
-2. Create self-signed certificates for the Certificate Authority (CA) that you later use to sign the server and client certificates.
- ```sh
- # Create CA private key
- openssl genrsa -out ca-key.pem 2048
-
- # Create CA certificate (valid for 1 year)
- openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \
- -subj "/CN=Test CA/O=Test Org"
- ```
-
-3. Create the server certificates for the Gateway that is signed by the CA that you created in the previous step. The Gateway uses these certificates to terminate incoming TLS connections.
- ```sh
- # Create server private key
- openssl genrsa -out server-key.pem 2048
-
- # Create server certificate signing request
- openssl req -new -key server-key.pem -out server.csr \
- -subj "/CN=example.com/O=Test Org"
-
- # Create server certificate signed by CA (valid for 1 year)
- openssl x509 -req -days 365 -in server.csr -CA ca-cert.pem -CAkey ca-key.pem \
- -CAcreateserial -out server-cert.pem \
- -extensions v3_req -extfile <(echo "[v3_req]"; echo "subjectAltName=DNS:example.com,DNS:*.example.com")
- ```
-
-4. Store the server certificate and key in a Kubernetes secret.
- ```yaml
- # Base64 encode server certificate and key
- SERVER_CERT=$(cat server-cert.pem | base64 -w 0)
- SERVER_KEY=$(cat server-key.pem | base64 -w 0)
-
- # Create the secret
- kubectl create secret tls https-cert \
- --cert=server-cert.pem \
- --key=server-key.pem \
- -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-5. Store the CA certificates in a configmap. The gateway proxy later uses these certificates to validate the client certificate that is presented during the TLS handshake.
- ```sh
- kubectl create configmap ca-cert \
- --from-file=ca.crt=ca-cert.pem \
- -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-6. Create a client certificate and private key. You use these credentials later when sending a request to the gateway proxy. The client certificate is signed by the same CA that you used for the gateway proxy.
- ```sh
- # Create client private key
- openssl genrsa -out client-key.pem 2048
-
- # Create client certificate signing request
- openssl req -new -key client-key.pem -out client.csr \
- -subj "/CN=client.example.com/O=Test Org"
-
- # Create client certificate signed by CA (valid for 1 year)
- openssl x509 -req -days 365 -in client.csr -CA ca-cert.pem -CAkey ca-key.pem \
- -CAcreateserial -out client-cert.pem \
- -extensions v3_req -extfile <(echo "[v3_req]"; echo "subjectAltName=DNS:example.com,DNS:*.example.com")
- ```
-
-7. Continue with configuring a [Default configuration for all listeners](#default). Alternatively, you can explore how to [override the default configuration for a specific port](#perport).
-
-
-## Default configuration for all listeners {#default}
-
-1. Create a Gateway with a default frontend TLS configuration that applies to all listeners that handle HTTPS traffic. The following example configures two HTTPS listeners on the Gateway. Both listeners use the same server TLS credentials to terminate incoming HTTPS connections. The validation mode is set to `AllowValidOnly` to allow connection only if a valid certificate is presented during the TLS handshake.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- tls:
- frontend:
- default:
- validation:
- mode: AllowValidOnly
- caCertificateRefs:
- - name: ca-cert
- kind: ConfigMap
- group: ""
- listeners:
- - name: https-8443
- protocol: HTTPS
- port: 8443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- - name: https-8444
- protocol: HTTPS
- port: 8444
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-2. Create an HTTPRoute that routes incoming traffic on the `example.com` domain to the mTLS Gateway that you created.
- ```yaml
- kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
-5. Get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing">}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} mtls -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward deploy/mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 8444:8444
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-6. Send a request to the httpbin app without a client certificate on both 8443 and 8444 ports. Verify that the TLS handshake fails, because a TLS certificate is required to establish the connection.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get
-
- curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get
-
- curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com"
-
- curl -v -k https://localhost:8444/get \
- --resolve example.com:8444:127.0.0.1 \
- -H "Host: example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-
- Example output:
- ```
- * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer)
- * Connection #0 to host localhost left intact
- curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- ```
-
-7. Repeat the request. This time, you include the client certificate that you created earlier.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k https://localhost:8444/get \
- --resolve example.com:8444:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for port 8444:
- ```
- * Connection #0 to host localhost left intact
- * Added example.com:8444:127.0.0.1 to DNS cache
- * Host localhost:8444 was resolved.
- * IPv6: ::1
- * IPv4: 127.0.0.1
- * Trying [::1]:8444...
- * Connected to localhost (::1) port 8444
- * ALPN: curl offers h2,http/1.1
- * (304) (OUT), TLS handshake, Client hello (1):
- * (304) (IN), TLS handshake, Server hello (2):
- * (304) (IN), TLS handshake, Unknown (8):
- * (304) (IN), TLS handshake, Request CERT (13):
- * (304) (IN), TLS handshake, Certificate (11):
- * (304) (IN), TLS handshake, CERT verify (15):
- * (304) (IN), TLS handshake, Finished (20):
- * (304) (OUT), TLS handshake, Certificate (11):
- * (304) (OUT), TLS handshake, CERT verify (15):
- * (304) (OUT), TLS handshake, Finished (20):
- * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
- * ALPN: server accepted h2
- * Server certificate:
- * subject: CN=example.com; O=Test Org
- * start date: Jan 13 20:19:17 2026 GMT
- * expire date: Jan 13 20:19:17 2027 GMT
- * issuer: CN=Test CA; O=Test Org
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * using HTTP/2
- * [HTTP/2] [1] OPENED stream for https://localhost:8444/get
- * [HTTP/2] [1] [:method: GET]
- * [HTTP/2] [1] [:scheme: https]
- * [HTTP/2] [1] [:authority: example.com]
- * [HTTP/2] [1] [:path: /get]
- * [HTTP/2] [1] [user-agent: curl/8.7.1]
- * [HTTP/2] [1] [accept: */*]
- > GET /get HTTP/2
- > Host: example.com
- > User-Agent: curl/8.7.1
- > Accept: */*
-
- * Request completely sent off
- < HTTP/2 200
- < access-control-allow-credentials: true
- < access-control-allow-origin: *
- < content-type: application/json; encoding=utf-8
- < date: Tue, 13 Jan 2026 21:59:07 GMT
- < content-length: 515
- < x-envoy-upstream-service-time: 1
- < server: envoy
- ...
- ```
-
-
-## Per port configuration {#perport}
-
-In this example, you override the default certificate validation configuration for port 8444.
-
-1. Update your Gateway to add in port-specific validation configuration for port 8444. In the following example, you override the default certificate validation for port 8444. This configuration allows requests, even if an invalid certificate was presented during the TLS handshake. Port 8443 continues to only allow connections if a valid certificate is presented.
- ```yaml {hl_lines=[18,19,20,21,22,23,24,25,26]}
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- tls:
- frontend:
- default:
- validation:
- mode: AllowValidOnly
- caCertificateRefs:
- - name: ca-cert
- kind: ConfigMap
- group: ""
- perPort:
- - port: 8444
- tls:
- validation:
- mode: AllowInsecureFallback
- caCertificateRefs:
- - name: ca-cert
- kind: ConfigMap
- group: ""
- listeners:
- - name: https-8443
- protocol: HTTPS
- port: 8443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- - name: https-8444
- protocol: HTTPS
- port: 8444
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-2. If you have not done so yet, get the external address of the gateway and save it in an environment variable. Note that it might take a few seconds for the gateway address to become available.
- {{< tabs tabTotal="2" items="Cloud Provider LoadBalancer,Port-forward for local testing">}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} mtls -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward deploy/mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:8443 8444:8444
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-3. Send a request to the httpbin app on both ports without a valid certificate. Verify that the request on port 8443 fails, because the default validation configuration does not allow to establish a connection without a valid certificate. The connection on port 8444 however is established as the port-specific validation configuration mode is set to `AllowInsecureFallback`.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get
-
- curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get
-
- curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com"
-
- curl -v -k https://localhost:8444/get \
- --resolve example.com:8444:127.0.0.1 \
- -H "Host: example.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output for port 8443:
- ```
- * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer)
- * Connection #0 to host localhost left intact
- curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- ```
-
- Example output for port 8444:
- ```
- ...
- * Request completely sent off
- < HTTP/2 200
- ...
- ```
-
-4. Repeat the request with a valid certificate. Verify that both requests succeed.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k --resolve "example.com:8444:${INGRESS_GW_ADDRESS}" https://example.com:8444/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k --resolve "example.com:8444:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8444/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- curl -v -k https://localhost:8444/get \
- --resolve example.com:8444:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-## Additional TLS settings
-
-You can configure your mTLS listener to limit connections to clients that present a certificate with a specific certificate hash and Subject Alternative Names. Alternatively, you can configure your listeners to enforce other TLS settings, such as a minimum or maximum TLS version, specific cipher suites, or CSDH curves. For more information, see [Additional TLS settings]({{< link-hextra path="/setup/listeners/tls-settings/" >}}).
-
-
-1. Get the certificate hash of the client certificate.
- ```sh
- openssl x509 -in client-cert.pem -noout -fingerprint -sha256
- ```
-
- Example output:
- ```
- sha256 Fingerprint=46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B
- ```
-
-2. Update port 8443 on the Gateway to allow connections only if the client certificate includes a specific hash and Subject Alt Name.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- tls:
- frontend:
- default:
- validation:
- mode: AllowValidOnly
- caCertificateRefs:
- - name: ca-cert
- kind: ConfigMap
- group: ""
- listeners:
- - name: https-8443
- protocol: HTTPS
- port: 8443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- options:
- kgateway.dev/verify-subject-alt-names: "example.com"
- kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B"
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- | Setting | Description |
- | -- | -- |
- | `kgateway.dev/verify-certificate-hash` | A comma-delimited list of the certificate hash (fingerprint) that must be present in the peer certificate that is presented during the TLS handshake. |
- | `kgateway.dev/verify-subject-alt-names` | A comma-delimited list of the Subject Alternative Names that must be present in the peer certificate that is presented during the TLS handshake. |
-
-3. Send a request to the httpbin app with your client certificate. Verify that the request succeeds.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Added example.com:8443:172.18.0.10 to DNS cache
- * Hostname example.com was found in DNS cache
- * Trying 172.18.0.10:8443...
- * Connected to example.com (172.18.0.10) port 8443
- * ALPN: curl offers h2,http/1.1
- * (304) (OUT), TLS handshake, Client hello (1):
- * (304) (IN), TLS handshake, Server hello (2):
- * (304) (IN), TLS handshake, Unknown (8):
- * (304) (IN), TLS handshake, Request CERT (13):
- * (304) (IN), TLS handshake, Certificate (11):
- * (304) (IN), TLS handshake, CERT verify (15):
- * (304) (IN), TLS handshake, Finished (20):
- * (304) (OUT), TLS handshake, Certificate (11):
- * (304) (OUT), TLS handshake, CERT verify (15):
- * (304) (OUT), TLS handshake, Finished (20):
- * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
- * ALPN: server accepted h2
- * Server certificate:
- * subject: CN=example.com; O=Test Org
- * start date: Jan 14 16:29:20 2026 GMT
- * expire date: Jan 14 16:29:20 2027 GMT
- * issuer: CN=Test CA; O=Test Org
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * using HTTP/2
- * [HTTP/2] [1] OPENED stream for https://example.com:8443/get
- * [HTTP/2] [1] [:method: GET]
- * [HTTP/2] [1] [:scheme: https]
- * [HTTP/2] [1] [:authority: example.com:8443]
- * [HTTP/2] [1] [:path: /get]
- * [HTTP/2] [1] [user-agent: curl/8.7.1]
- * [HTTP/2] [1] [accept: */*]
- > GET /get HTTP/2
- > Host: example.com:8443
- > User-Agent: curl/8.7.1
- > Accept: */*
- >
- * Request completely sent off
- < HTTP/2 200
- ...
- ```
-
-4. Change the annotation values in the Gateway to a value that does not exist in the client certificate. For example, you can change the Subject Alt Name to `mtls.com`.
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- tls:
- frontend:
- default:
- validation:
- mode: AllowValidOnly
- caCertificateRefs:
- - name: ca-cert
- kind: ConfigMap
- group: ""
- listeners:
- - name: https-8443
- protocol: HTTPS
- port: 8443
- tls:
- mode: Terminate
- certificateRefs:
- - name: https-cert
- kind: Secret
- options:
- kgateway.dev/verify-subject-alt-names: "mtls.com"
- kgateway.dev/verify-certificate-hash: "46:DB:0D:C2:E1:4F:0A:05:8C:4F:05:8D:77:B1:8D:7C:1A:BE:18:4F:AF:81:BF:E2:B1:CD:03:43:7F:D8:65:4B"
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
-5. Repeat the request to the httpbin app with your client certificate. Verify that the request now fails.
- {{< tabs tabTotal="3" items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:${INGRESS_GW_ADDRESS}" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -v -k --resolve "example.com:8443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://example.com:8443/get \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
-
- ```
-
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -v -k https://localhost:8443/get \
- --resolve example.com:8443:127.0.0.1 \
- -H "Host: example.com" \
- --cert client-cert.pem \
- --key client-key.pem \
- --cacert ca-cert.pem
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- * Failed receiving HTTP2 data: 56(Failure when receiving data from the peer)
- * Connection #0 to host localhost left intact
- curl: (56) LibreSSL SSL_read: LibreSSL/3.3.6: error:1404C45C:SSL routines:ST_OK:reason(1116), errno 0
- ```
-
-
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-```sh
-kubectl delete httproute httpbin-https -n httpbin
-kubectl delete gateway mtls -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete secret https-cert -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-kubectl delete configmap ca-cert -n {{< reuse "agw-docs/snippets/namespace.md" >}}
-rm -rf ../example_certs
-```
-
\ No newline at end of file
diff --git a/assets/docs/pages/setup/listeners/http.md b/assets/docs/pages/setup/listeners/http.md
deleted file mode 100644
index 74ae63cd4..000000000
--- a/assets/docs/pages/setup/listeners/http.md
+++ /dev/null
@@ -1,330 +0,0 @@
-Create an HTTP listener on your API Gateway. Then, your API Gateway listens for HTTP traffic on the specified port and hostname that you configure. This Gateway can be used as the main ingress for the apps in your cluster. You can also create multiple Gateways to listen for traffic on different ports and hostnames.
-
-Next, you set up an HTTPRoute resource to route requests through the Gateway to backing services in your cluster. HTTPRoutes can refer to any gateway independent of the namespace they are in.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/prereq-listeners.md" >}}
-
-## Set up an HTTP listener {#setup-http}
-
-Set up an HTTP listener on your Gateway.
-
-If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}).
-* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}}
-* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later.
-
-1. Create a Gateway resource with an HTTP listener.
-
- {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
- ```yaml
- kubectl apply -f- <}}
- labels:
- example: httpbin-mydomain
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- listeners:
- - protocol: HTTP
- port: 8080
- hostname: mydomain.com
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |---|---|
- |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. |
- |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure an HTTP Gateway that listens for incoming traffic for the `mydomain.com` domain on port 8080. The Gateway can serve HTTP routes from any namespace. |
-
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
-
- 1. Create a Gateway that enables the attachment of ListenerSets.
-
- ```yaml
- kubectl apply -f- <}}
- labels:
- example: httpbin-mydomain
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- allowedListeners:
- namespaces:
- from: All
- listeners:
- - protocol: HTTP
- port: 80
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |---|---|
- |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. |
- |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. |
- |`spec.listeners`| {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 8080 in the ListenerSet that you create later. |
-
- 2. Create a ListenerSet that configures an HTTP listener for the Gateway.
-
- ```yaml
- kubectl apply -f- <}}
- kind: Gateway
- group: gateway.networking.k8s.io
- listeners:
- - protocol: HTTP
- port: 8080
- hostname: mydomain.com
- name: http-listener-set
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. |
- |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure an HTTP gateway that listens for incoming traffic for the `mydomain.com` domain on port 8080. The gateway can serve HTTP routes from any namespace. |
-
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Check the status of the Gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the Gateway is accepted and does not conflict with other Gateway configuration.
- ```sh
- kubectl get gateway my-http-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml
- ```
-
-3. Create an HTTPRoute resource for the httpbin app that is served by the Gateway that you created.
-
- {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
- ```yaml
- kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
- ```yaml
- kubectl apply -f- <}}
-
-4. Verify that the HTTPRoute is applied successfully.
- ```sh
- kubectl get httproute/httpbin-mydomain -n httpbin -o yaml
- ```
-
- Example output: Notice in the `status` section that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute.
-
- ```yaml
- ...
- status:
- parents:
- - conditions:
- - lastTransitionTime: "2025-04-29T20:48:51Z"
- message: ""
- observedGeneration: 3
- reason: Accepted
- status: "True"
- type: Accepted
- - lastTransitionTime: "2025-04-29T20:48:51Z"
- message: ""
- observedGeneration: 3
- reason: ResolvedRefs
- status: "True"
- type: ResolvedRefs
- controllerName: kgateway.dev/kgateway
- parentRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: my-http-gateway
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-5. Verify that the listener now has a route attached.
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```sh
- kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 1
- ```
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
-
- ```sh
- kubectl get xlistenerset -n httpbin my-http-listenerset -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 1
- ```
-
- Note that because the HTTPRoute is attached to the ListenerSet, the Gateway does not show the route in its status.
-
- ```sh
- kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 0
- ```
-
- If you create another HTTPRoute that attaches to the Gateway and uses the same listener as the ListenerSet, then the route is reported in the status of both the Gateway (attachedRoutes: 1) and the ListenerSet (attachedRoutes: 2).
-
- {{% /tab %}}
- {{< /tabs >}}
-
-6. Get the external address of the gateway and save it in an environment variable.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-http-gateway -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward deployment/my-http-gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8080:8080
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-7. Send a request to the httpbin app and verify that you get back a 200 HTTP response code.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vi http://$INGRESS_GW_ADDRESS:8080/status/200 -H "host: mydomain.com:8080"
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vi localhost:8080/status/200 -H "host: mydomain.com"
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-
- Example output:
- ```console
- * Mark bundle as not supporting multiuse
- < HTTP/1.1 200 OK
- HTTP/1.1 200 OK
- < access-control-allow-credentials: true
- access-control-allow-credentials: true
- < access-control-allow-origin: *
- access-control-allow-origin: *
- < date: Fri, 03 Nov 2023 20:02:48 GMT
- date: Fri, 03 Nov 2023 20:02:48 GMT
- < content-length: 0
- content-length: 0
- < x-envoy-upstream-service-time: 1
- x-envoy-upstream-service-time: 1
- < server: envoy
- server: envoy
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-{{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
-{{% tab tabName="Gateway listeners" %}}
-```sh
-kubectl delete -A gateways,httproutes -l example=httpbin-mydomain
-```
-{{% /tab %}}
-{{% tab tabName="ListenerSet (experimental)" %}}
-```sh
-kubectl delete -A gateways,httproutes,xlistenersets -l example=httpbin-mydomain
-```
-{{% /tab %}}
-{{< /tabs >}}
-
-
-
-
-
diff --git a/assets/docs/pages/setup/listeners/https.md b/assets/docs/pages/setup/listeners/https.md
deleted file mode 100644
index 24c9d3de1..000000000
--- a/assets/docs/pages/setup/listeners/https.md
+++ /dev/null
@@ -1,369 +0,0 @@
-Create an HTTPS listener on your API gateway. Then, your API gateway listens for secured HTTPS traffic on the specified port and hostname that you configure.
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/cert-prereqs.md" >}}
-
-## Create a TLS certificate
-
-{{< reuse "agw-docs/snippets/listeners-https-create-cert.md" >}}
-
-## Set up an HTTPS listener {#setup-https}
-
-Set up an HTTPS listener on your Gateway.
-
-If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}).
-* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}}
-* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later.
-
-1. Create a gateway resource with an HTTPS listener. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}
-
- {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
- ```yaml
- kubectl apply -f- <}}
- labels:
- example: httpbin-https
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- listeners:
- - protocol: HTTPS
- port: 443
- name: https
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |---|---|
- |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} |
- |`spec.listeners`|Configure the listeners for this Gateway. The Gateway can serve HTTPS routes from any namespace. |
- |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the Gateway and the unencrypted request is forwarded to the service in the cluster. |
- |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the Gateway. The Gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.|
-
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
-
- 1. Create a Gateway that enables the attachment of ListenerSets.
-
- ```yaml
- kubectl apply -f- <}}
- labels:
- example: httpbin-https
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- allowedListeners:
- namespaces:
- from: All
- listeners:
- - protocol: HTTPS
- port: 80
- name: https
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |---|---|
- |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} |
- |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. |
- |`spec.listeners`| {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 443 in the ListenerSet that you create later. |
-
- 2. Create a ListenerSet that configures an HTTPS listener for the Gateway.
-
- ```yaml
- kubectl apply -f- <}}
- labels:
- example: httpbin-https
- spec:
- parentRef:
- name: https
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- kind: Gateway
- group: gateway.networking.k8s.io
- listeners:
- - protocol: HTTPS
- port: 443
- hostname: https.example.com
- name: https-listener-set
- tls:
- mode: Terminate
- certificateRefs:
- - name: https
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. |
- |`spec.listeners`|Configure the listeners for this ListenerSet. In this example, you configure an HTTPS gateway that listens for incoming traffic for the `https.example.com` domain on port 443. The gateway can serve HTTP routes from any namespace. |
- |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the gateway and the unencrypted request is forwarded to the service in the cluster. |
- |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the gateway. The gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.|
-
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Check the status of the Gateway to make sure that your configuration is accepted. Note that in the output, a `NoConflicts` status of `False` indicates that the Gateway is accepted and does not conflict with other Gateway configuration.
- ```sh
- kubectl get gateway https -n {{< reuse "agw-docs/snippets/namespace.md" >}} -o yaml
- ```
-
-3. Create an HTTPRoute resource for the httpbin app that is served by the gateway or ListenerSet that you created.
-
- {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
- ```yaml
- kubectl apply -f- <}}
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
- ```yaml
- kubectl apply -f- <}}
- kind: XListenerSet
- group: gateway.networking.x-k8s.io
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-4. Verify that the HTTPRoute is applied successfully.
- ```sh
- kubectl get httproute/httpbin-https -n httpbin -o yaml
- ```
-
- Example output: Notice in the `status` section that the parentRef is either the Gateway or the ListenerSet, depending on how you attached the HTTPRoute.
-
- ```yaml
- ...
- status:
- parents:
- - conditions:
- - lastTransitionTime: "2025-04-29T20:48:51Z"
- message: ""
- observedGeneration: 3
- reason: Accepted
- status: "True"
- type: Accepted
- - lastTransitionTime: "2025-04-29T20:48:51Z"
- message: ""
- observedGeneration: 3
- reason: ResolvedRefs
- status: "True"
- type: ResolvedRefs
- controllerName: kgateway.dev/kgateway
- parentRef:
- group: gateway.networking.k8s.io
- kind: Gateway
- name: https
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-5. Verify that the listener now has a route attached.
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```sh
- kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 1
- ```
- {{% /tab %}}
- {{% tab tabName="ListenerSet (experimental)" %}}
-
- ```sh
- kubectl get xlistenerset -n {{< reuse "agw-docs/snippets/namespace.md" >}} my-https-listenerset -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 1
- ```
-
- Note that because the HTTPRoute is attached to the ListenerSet, the Gateway does not show the route in its status.
-
- ```sh
- kubectl get gateway -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o yaml
- ```
-
- Example output:
-
- ```yaml
- ...
- listeners:
- - attachedRoutes: 0
- ```
-
- If you create another HTTPRoute that attaches to the Gateway and uses the same listener as the ListenerSet, then the route is reported in the status of both the Gateway (attachedRoutes: 1) and the ListenerSet (attachedRoutes: 2).
-
- {{% /tab %}}
- {{< /tabs >}}
-
-6. Get the external address of the gateway and save it in an environment variable.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} https -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward svc/https -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:443
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-7. Send a request to the httpbin app and verify that you see the TLS handshake and you get back a 200 HTTP response code.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- curl -vik --resolve "https.example.com:443:${INGRESS_GW_ADDRESS}" https://https.example.com:443/status/200
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vik --connect-to https.example.com:443:localhost:8443 https://https.example.com:443/status/200
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * ALPN, offering h2
- * ALPN, offering http/1.1
- * successfully set certificate verify locations:
- * CAfile: /etc/ssl/cert.pem
- * CApath: none
- * TLSv1.2 (OUT), TLS handshake, Client hello (1):
- * TLSv1.2 (IN), TLS handshake, Server hello (2):
- * TLSv1.2 (IN), TLS handshake, Certificate (11):
- * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
- * TLSv1.2 (IN), TLS handshake, Server finished (14):
- * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
- * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
- * TLSv1.2 (OUT), TLS handshake, Finished (20):
- * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
- * TLSv1.2 (IN), TLS handshake, Finished (20):
- * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
- * ALPN, server accepted to use h2
- * Server certificate:
- * subject: CN=*; O=gateway
- * start date: Nov 5 01:54:04 2023 GMT
- * expire date: Nov 2 01:54:04 2033 GMT
- * issuer: CN=*; O=root
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * Using HTTP2, server supports multi-use
- * Connection state changed (HTTP/2 confirmed)
- * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
- * Using Stream ID: 1 (easy handle 0x15200e800)
- * > GET /status/200 HTTP/2
- * > Host: https.example.com
- * > user-agent: curl/7.77.0
- * > accept: */*
- * >
- * * Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
- * < HTTP/2 200
- * HTTP/2 200
- * ...
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-{{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
-{{% tab tabName="Gateway listeners" %}}
-```sh
-kubectl delete -A gateways,httproutes,secret -l example=httpbin-https
-rm -rf example_certs
-```
-{{% /tab %}}
-{{% tab tabName="ListenerSet (experimental)" %}}
-```sh
-kubectl delete -A gateways,httproutes,xlistenersets,secret -l example=httpbin-https
-rm -rf example_certs
-```
-{{% /tab %}}
-{{< /tabs >}}
-
-
-
-
-
diff --git a/assets/docs/pages/setup/listeners/overview.md b/assets/docs/pages/setup/listeners/overview.md
deleted file mode 100644
index 3a2768181..000000000
--- a/assets/docs/pages/setup/listeners/overview.md
+++ /dev/null
@@ -1,96 +0,0 @@
-Set up listeners on your API Gateway. A listener configures how your API Gateway accepts and processes incoming requests.
-
-In the Kubernetes Gateway API, you can create listeners in two main ways:
-
-* Inline as part of the Gateway resource.
-* As a separate resource called a ListenerSet.
-
-## Inline on the Gateway {#inline}
-
-A common, simple approach is to write the listener inline on the Gateway resource. You have the flexibility to write different protocols, ports, and even TLS certificates. Each listener can specify its own hostname, or inherit the hostname of the Gateway. Gateways support up to 64 listeners.
-
-Most examples in both the {{< reuse "agw-docs/snippets/kgateway.md" >}} and Kubernetes Gateway API docs use the inline approach.
-
-## ListenerSets (experimental) {#listenersets}
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-2-1-only.md" >}} {{< reuse "agw-docs/versions/warn-experimental.md" >}} As such, the ListenerSet CRD is prefixed with `X` to indicate that it is experimental.
-{{< /callout >}}
-
-With ListenerSets, you can group together listeners that have their own unique configuration, such as different protocols, ports, hostnames, or TLS settings. Then, the ListenerSet refers to a Gateway, which can be in a different namespace than the ListenerSet. The same Gateway can also have multiple ListenerSets.
-
-Similar to Gateways, ListenerSets can have a maximum of 64 listeners. However, because you can attach multiple ListenerSets to a single Gateway, now a single Gateway can have more than 64 listeners. Keep in mind that more listeners can impact how long it takes to propagate configuration changes on the Gateway. If you have more than 1,000 listeners, consider attaching ListenerSets to multiple Gateways.
-
-### ListenerSet use cases {#listenerset-use-cases}
-
-As such, you might use ListenerSets for the following advantages:
-
-- **Multitenancy**: You can let different teams create their own ListenerSets, but share the same Gateway and backing load balancing infrastructure.
-- **Inheritance**: Because ListenerSets inherit routes and policies from the Gateway, you can standardize the configuration of listeners across a multitenant environment. Teams still have the flexibility to overwrite settings in the ListenerSet.
-- **Large scale deployments**: By using ListenerSets, Gateways can have more than 64 listeners attached. Teams can also share the same ListenerSet configuration to avoid duplication.
-- **Certificates for more listeners per gateway**: Because you can now have more than 64 listeners per Gateway, a single Gateway can forward secured traffic to more backends that might have their own certificates. This approach aligns with projects that might require service-level certificates, such as Istio Ambient Mesh or Knative.
-
-The following diagram presents a simple illustration of how ListenerSets can help you decentralize route configuration in a multitenant environment at scale.
-
-* Team 1 and Team 2 each manage their own Service and HTTPRoute resources within their respective namespaces.
-* Each HTTPRoute refers to a namespace-local ListenerSet. This way, each team controls how their routes are exposed, such as the protocol, port, and TLS certificate settings.
-* The ListenerSets from both teams share a common Gateway in a separate namespace. A separate Gateway team can setup and manage centralized infrastructure or enforce policies as appropriate.
-
-
-```mermaid
-flowchart TD
-
- subgraph team1 namespace
- SVC1[Services]
- HR1[HTTPRoutes]
- LS1[ListenerSet]
- end
-
- subgraph team2 namespace
- SVC2[Services]
- HR2[HTTPRoutes]
- LS2[ListenerSet]
- end
-
- subgraph shared namespace
- GW[Gateway]
- end
-
- HR1 -- "parentRef" --> LS1
- LS1 -- "parentRef" --> GW
- HR1 -- "backendRef" --> SVC1
-
- HR2 -- "parentRef" --> LS2
- LS2 -- "parentRef" --> GW
- HR2 -- "backendRef" --> SVC2
-```
-
-### Prerequisites {#prerequisites}
-
-To use ListenerSets, you must have the following environment:
-
-1. Install the Kubernetes Gateway API v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}} or later experimental channel, which includes the `XListenerSet` CRD.
-
- ```sh
- kubectl apply --server-side --kustomize "https://github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}"
- ```
-
-2. Follow the [Get Started guide]({{< link-hextra path="/quickstart/" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}.
-
-3. If you already have a {{< reuse "agw-docs/snippets/kgateway.md" >}} installation, restart the `{{< reuse "agw-docs/snippets/pod-name.md" >}}` deployment to pick up the new CRDs.
-
- ```sh
- kubectl rollout restart deployment/{{< reuse "agw-docs/snippets/pod-name.md" >}} -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- ```
-
-### More information {#more-info}
-
-The listener setup guides in this section include tabs for examples of using both the inline and ListenerSet approaches.
-
-For more information about ListenerSets, see the [Kubernetes Gateway API docs](https://gateway-api.sigs.k8s.io/geps/gep-1713/).
-
-
-
-
-
-
diff --git a/assets/docs/pages/setup/listeners/sni.md b/assets/docs/pages/setup/listeners/sni.md
deleted file mode 100644
index daca081cb..000000000
--- a/assets/docs/pages/setup/listeners/sni.md
+++ /dev/null
@@ -1,548 +0,0 @@
-Serve multiple hosts on the same HTTPS listener.
-
-## About SNI
-
-Each host comes with its own TLS certificates that the Gateway uses to authenticate and authorize client requests.
-
-Serving multiple hosts on a single listener is also referred to as Server Name Indication (SNI) routing. SNI is an extension to the TLS protocol and allows clients to indicate which hostname they want to connect to at the start of the TLS handshake. After the HTTPS/TLS traffic is accepted at the gateway, the TLS connection is terminated, and the unencrypted HTTP/TCP request is forwarded to the destination.
-
-## About this guide
-
-In this guide, you learn how to set up an HTTPS Gateway that serves two different domains, `httpbin.example.com` and `petstore.example.com` on the same port 443. When sending a request to the Gateway, you indicate the hostname you want to connect to. Based on the selected hostname, the Gateway presents the hostname-specific certificate.
-
-{{< reuse-image src="img/sni-listener.svg" width="700px">}}
-{{< reuse-image-dark srcDark="img/sni-listener-dark.svg" width="700px" >}}
-
-## Before you begin
-
-{{< reuse "agw-docs/snippets/cert-prereqs.md" >}}
-
-## Deploy sample apps
-
-Deploy the Petstore sample app. This app is used alongside the httpbin app from the [Get started]({{< link-hextra path="/quickstart" >}}) guide to demonstrate the SNI routing capabilities.
-
-1. Deploy the Petstore app.
- ```sh
- kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo/v1.16.x/example/petstore/petstore.yaml
- ```
-
- Example output:
- ```console
- deployment.apps/petstore created
- service/petstore created
- ```
-
-2. Verify that the Petstore app is up and running.
- ```sh
- kubectl get pods
- ```
-
- Example output:
- ```
- NAME READY STATUS RESTARTS AGE
- petstore-66cddd5bb4-x7vdd 1/1 Running 0 26s
- ```
-
-## Set up TLS certificates for multiple domains
-
-Create TLS certificates for the `httpbin.example.com` and `petstore.example.com` domains that are signed by a self-signed root CA.
-
-{{< callout type="warning" >}}
-Self-signed certificates are used for demonstration purposes. Do not use self-signed certificates in production environments. Instead, use certificates that are issued from a trusted Certificate Authority.
-{{< /callout >}}
-
-{{< callout type="info" >}}
-When generating your Envoy certificates, make sure to use encryption algorithms that are supported in Envoy. To learn more about supported algorithms that you can use for your certificates and keys, see the Envoy documentation.
-{{< /callout >}}
-
-1. Create a root certificate and private key to sign the certificates for your services.
- ```shell
- mkdir example_certs
- openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs/example.com.key -out example_certs/example.com.crt
- ```
-
-2. Generate a TLS certificate and key for the `httpbin.example.com` domain.
- ```shell
- openssl req -out example_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
- openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 0 -in example_certs/httpbin.example.com.csr -out example_certs/httpbin.example.com.crt
- ```
-
-3. Generate a TLS certificate and key for the `petstore.example.com` domain.
- ```shell
- openssl req -out example_certs/petstore.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs/petstore.example.com.key -subj "/CN=petstore.example.com/O=petstore organization"
- openssl x509 -req -sha256 -days 365 -CA example_certs/example.com.crt -CAkey example_certs/example.com.key -set_serial 1 -in example_certs/petstore.example.com.csr -out example_certs/petstore.example.com.crt
- ```
-
-4. Verify that you have the required certificates and keys.
- ```shell
- ls example_cert*
- ```
-
- Example output:
- ```
- petstore.example.com.crt petstore.example.com.key example.com.crt httpbin.example.com.crt httpbin.example.com.key
- petstore.example.com.csr example.com.key httpbin.example.com.csr
- ```
-
-6. Store the credentials for the `httpbin.example.com` domain in a Kubernetes secret.
- ```shell
- kubectl create -n {{< reuse "agw-docs/snippets/namespace.md" >}} secret tls httpbin-credential \
- --key=example_certs/httpbin.example.com.key \
- --cert=example_certs/httpbin.example.com.crt
- ```
-
-7. Store the credentials for the `petstore.example.com` domain in a Kubernetes secret.
- ```shell
- kubectl create -n {{< reuse "agw-docs/snippets/namespace.md" >}} secret tls petstore-credential \
- --key=example_certs/petstore.example.com.key \
- --cert=example_certs/petstore.example.com.crt
- ```
-
-## Set up SNI routing
-
-Set up an SNI Gateway that serves multiple hosts on the same port.
-
-If you plan to set up your listener as part of a ListenerSet, keep the following considerations in mind. For more information, see [ListenerSets (experimental)]({{< link-hextra path="/setup/listeners/overview/#listenersets" >}}).
-* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}}
-* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later.
-
-1. Create an SNI Gateway. The Gateway defines two hosts on the same HTTPS listener. Each host is configured with the host-specific TLS certificate that you set up earlier. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- listeners:
- - protocol: HTTPS
- port: 443
- name: httpbin
- hostname: "httpbin.example.com"
- tls:
- mode: Terminate
- certificateRefs:
- - name: httpbin-credential
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- - protocol: HTTPS
- port: 443
- name: petstore
- hostname: "petstore.example.com"
- tls:
- mode: Terminate
- certificateRefs:
- - name: petstore-credential
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}|
- |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure two HTTPS listeners. One listener is for the httpbin app and the other is for the petstore app. Each listener refers to a secret that holds the TLS certificate and key for the hostname that the listener is configured for. |
- |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the Gateway and the unencrypted request is forwarded to the service in the cluster. |
- |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the Gateway. The Gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.|
-
- {{% /tab %}}
- {{% tab tabName="ListenerSet (experimental)" %}}
-
- 1. Create a Gateway that enables the attachment of ListenerSets.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- allowedListeners:
- namespaces:
- from: All
- listeners:
- - protocol: HTTP
- port: 80
- name: http
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}|
- |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace, which is helpful in multitenant environments. You can also limit the allowed listeners. To limit to listeners in the same namespace as the Gateway, set this value to `Same`. To limit to listeners with a particular label, set this value to `Selector`. |
- | `spec.listeners` | {{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on HTTP port 80, which differs from the HTTPS port 443 in the ListenerSet that you create later. |
-
- 2. Create a ListenerSet that configures an HTTPS listener for each app that the Gateway serves.
-
- ```yaml
- kubectl apply -f- <}}
- spec:
- parentRef:
- name: sni
- namespace: {{< reuse "agw-docs/snippets/namespace.md" >}}
- kind: Gateway
- group: gateway.networking.k8s.io
- listeners:
- - protocol: HTTPS
- port: 443
- name: httpbin
- hostname: "httpbin.example.com"
- tls:
- mode: Terminate
- certificateRefs:
- - name: httpbin-credential
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- - protocol: HTTPS
- port: 443
- name: petstore
- hostname: "petstore.example.com"
- tls:
- mode: Terminate
- certificateRefs:
- - name: petstore-credential
- kind: Secret
- allowedRoutes:
- namespaces:
- from: All
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.parentRef`|The name of the Gateway to attach the ListenerSet to. |
- |`spec.listeners`|Configure the listeners for this gateway. In this example, you configure two HTTPS listeners. One listener is for the httpbin app and the other is for the petstore app. Each listener refers to a secret that holds the TLS certificate and key for the hostname that the listener is configured for. |
- |`spec.listeners.tls.mode`|The TLS mode that you want to use for incoming requests. In this example, HTTPS requests are terminated at the gateway and the unencrypted request is forwarded to the service in the cluster. |
- |`spec.listeners.tls.certificateRefs`|The Kubernetes secret that holds the TLS certificate and key for the gateway. The gateway uses these credentials to establish the TLS connection with a client, and to decrypt incoming HTTPS requests.|
-
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Create an HTTPRoute that routes incoming requests on the `httpbin.example.com` domain to the httpbin app.
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "httpbin.example.com"
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
-
- {{% /tab %}}
- {{% tab tabName="ListenerSet (experimental)" %}}
-
- ```yaml
- kubectl apply -f- <}}
- kind: XListenerSet
- group: gateway.networking.x-k8s.io
- hostnames:
- - "httpbin.example.com"
- rules:
- - backendRefs:
- - name: httpbin
- port: 8000
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-3. Create an HTTPRoute that routes incoming requests on the `petstore.example.com` domain to the petstore app.
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```yaml
- kubectl apply -f- <}}
- hostnames:
- - "petstore.example.com"
- rules:
- - backendRefs:
- - name: petstore
- port: 8080
- EOF
- ```
-
- {{% /tab %}}
- {{% tab tabName="ListenerSet (experimental)" %}}
-
- ```yaml
- kubectl apply -f- <}}
- kind: XListenerSet
- group: gateway.networking.x-k8s.io
- hostnames:
- - "petstore.example.com"
- rules:
- - backendRefs:
- - name: petstore
- port: 8080
- EOF
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-4. Get the external address of the Gateway and save it in an environment variable. Note that it might take a few seconds for the Gateway address to become available.
- {{< tabs items="Cloud Provider LoadBalancer,Port-forward for local testing" tabTotal="2" >}}
- {{% tab tabName="Cloud Provider LoadBalancer" %}}
- ```sh
- export INGRESS_GW_ADDRESS=$(kubectl get svc -n {{< reuse "agw-docs/snippets/namespace.md" >}} sni -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
- echo $INGRESS_GW_ADDRESS
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- kubectl port-forward svc/sni -n {{< reuse "agw-docs/snippets/namespace.md" >}} 8443:443
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-5. Send a request to the `httpbin.example.com` domain with the client certificate that you created earlier. Verify that the gateway presents the TLS certificate for the `httpbin.example.com` domain during the TLS handshake.
- {{< tabs items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" tabTotal="3" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -vik --resolve "httpbin.example.com:443:${INGRESS_GW_ADDRESS}" https://httpbin.example.com:443/anything
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -vik --resolve "httpbin.example.com:443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://httpbin.example.com:443/anything
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vik --connect-to httpbin.example.com:443:localhost:8443 https://httpbin.example.com:443/anything
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Added httpbin.example.com:443:3.XXX.XXX.XX to DNS cache
- * Hostname httpbin.example.com was found in DNS cache
- * Trying 3.128.214.17:443...
- * Connected to httpbin.example.com (3.XXX.XXX.XX) port 443
- * ALPN: curl offers h2,http/1.1
- * (304) (OUT), TLS handshake, Client hello (1):
- * (304) (IN), TLS handshake, Server hello (2):
- * (304) (IN), TLS handshake, Unknown (8):
- * (304) (IN), TLS handshake, Certificate (11):
- * (304) (IN), TLS handshake, CERT verify (15):
- * (304) (IN), TLS handshake, Finished (20):
- * (304) (OUT), TLS handshake, Finished (20):
- * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
- * ALPN: server accepted h2
- * Server certificate:
- * subject: CN=httpbin.example.com; O=httpbin organization
- * issuer: O=example Inc.; CN=example.com
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * using HTTP/2
- * [HTTP/2] [1] OPENED stream for https://httpbin.example.com:443/headers
- * [HTTP/2] [1] [:method: GET]
- * [HTTP/2] [1] [:scheme: https]
- * [HTTP/2] [1] [:authority: httpbin.example.com]
- * [HTTP/2] [1] [:path: /headers]
- * [HTTP/2] [1] [user-agent: curl/8.7.1]
- * [HTTP/2] [1] [accept: */*]
- > GET /headers HTTP/2
- > Host: httpbin.example.com
- > User-Agent: curl/8.7.1
- > Accept: */*
- >
- * Request completely sent off
- < HTTP/2 200
- HTTP/2 200
- ...
- "Accept": [
- "*/*"
- ],
- "Host": [
- "httpbin.example.com"
- ],
- "User-Agent": [
- "curl/8.7.1"
- ],
- "X-Envoy-Expected-Rq-Timeout-Ms": [
- "15000"
- ],
- "X-Forwarded-Proto": [
- "https"
- ],
- "X-Request-Id": [
- "33654cba-7198-4b7c-a850-8629fd230145"
- ]
- }
- }
- ```
-
-6. Send a request to the `petstore.example.com` domain with the client certificate that you created earlier. Verify that the gateway presents the TLS certificate for the `petstore.example.com` domain during the TLS handshake.
- {{< tabs items="LoadBalancer IP address,LoadBalancer hostname,Port-forward for local testing" tabTotal="3" >}}
- {{% tab tabName="LoadBalancer IP address" %}}
- ```sh
- curl -vik --resolve "petstore.example.com:443:${INGRESS_GW_ADDRESS}" https://petstore.example.com:443/api/pets
- ```
- {{% /tab %}}
- {{% tab tabName="LoadBalancer hostname" %}}
- ```sh
- curl -vik --resolve "petstore.example.com:443:$(dig +short $INGRESS_GW_ADDRESS | head -n1)" https://petstore.example.com:443/api/pets
- ```
- {{% /tab %}}
- {{% tab tabName="Port-forward for local testing" %}}
- ```sh
- curl -vik --connect-to petstore.example.com:443:localhost:8443 https://petstore.example.com:443/api/pets
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
- Example output:
- ```
- * Added petstore.example.com:443:3.XXX.XXX.XX to DNS cache
- * Hostname petstore.example.com was found in DNS cache
- * Trying 3.128.214.17:443...
- * Connected to petstore.example.com (3.XXX.XXX.XX) port 443
- * ALPN: curl offers h2,http/1.1
- * (304) (OUT), TLS handshake, Client hello (1):
- * (304) (IN), TLS handshake, Server hello (2):
- * (304) (IN), TLS handshake, Unknown (8):
- * (304) (IN), TLS handshake, Certificate (11):
- * (304) (IN), TLS handshake, CERT verify (15):
- * (304) (IN), TLS handshake, Finished (20):
- * (304) (OUT), TLS handshake, Finished (20):
- * SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256 / [blank] / UNDEF
- * ALPN: server accepted h2
- * Server certificate:
- * subject: CN=petstore.example.com; O=petstore organization
- * issuer: O=example Inc.; CN=example.com
- * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
- * using HTTP/2
- * [HTTP/2] [1] OPENED stream for https://petstore.example.com:443/api/pets
- * [HTTP/2] [1] [:method: GET]
- * [HTTP/2] [1] [:scheme: https]
- * [HTTP/2] [1] [:authority: petstore.example.com]
- * [HTTP/2] [1] [:path: /api/pets]
- * [HTTP/2] [1] [user-agent: curl/8.7.1]
- * [HTTP/2] [1] [accept: */*]
- > GET /api/pets HTTP/2
- > Host: petstore.example.com
- > User-Agent: curl/8.7.1
- > Accept: */*
- >
- * Request completely sent off
- < HTTP/2 200
- HTTP/2 200
- ...
-
- [{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}]
- ```
-
-## Cleanup
-
-{{< reuse "agw-docs/snippets/cleanup.md" >}}
-
-1. Remove the routing resources for the HTTPS route, including the Kubernetes secret that holds the TLS certificate and key.
-
- {{< tabs items="Gateway listeners,ListenerSet (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
-
- ```sh
- kubectl delete secret httpbin-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete secret petstore-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete gateway sni -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete httproute httpbin-https -n httpbin
- kubectl delete httproute petstore-https -n default
- kubectl delete deployment petstore
- kubectl delete service petstore
- ```
- {{% /tab %}}
- {{% tab tabName="ListenerSet (experimental)" %}}
- ```sh
- kubectl delete secret httpbin-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete secret petstore-credential -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete gateway sni -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete xlistenerset sni-listenerset -n {{< reuse "agw-docs/snippets/namespace.md" >}}
- kubectl delete httproute httpbin-https -n httpbin
- kubectl delete httproute petstore-https -n default
- kubectl delete deployment petstore
- kubectl delete service petstore
- ```
- {{% /tab %}}
- {{< /tabs >}}
-
-2. Remove the `example_certs` directory that stores your TLS credentials.
- ```sh
- rm -rf example_certs
- ```
-
-
-
-
-
diff --git a/assets/docs/pages/setup/listeners/tcp.md b/assets/docs/pages/setup/listeners/tcp.md
deleted file mode 100644
index 998cd2105..000000000
--- a/assets/docs/pages/setup/listeners/tcp.md
+++ /dev/null
@@ -1,364 +0,0 @@
-The following guide deploys a sample TCP echo app, sets up a TCP listener on the gateway, and creates a [TCPRoute](https://gateway-api.sigs.k8s.io/guides/tcp) to the sample app.
-
-{{< callout type="warning" >}}
-{{< reuse "agw-docs/versions/warn-experimental.md" >}}
-{{< /callout >}}
-
-## Before you begin
-
-1. Follow the [Get started guide]({{< link-hextra path="/quickstart" >}}) to install {{< reuse "agw-docs/snippets/kgateway.md" >}}.
-
-2. Install the experimental channel of the {{< reuse "agw-docs/snippets/k8s-gateway-api-name.md" >}} so that you can use TCPRoutes.
-
- ```shell
- kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.3.0/experimental-install.yaml
- ```
-
-3. {{< reuse "agw-docs/snippets/prereq-listenerset.md" >}}
-
- **ListenerSets**: {{< reuse "agw-docs/versions/warn-2-1-only.md" >}} Also, you must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later.
-
-4. Deploy the sample TCP echo app.
-
- ```yaml
- kubectl apply -f- <}}).
-* {{< reuse "agw-docs/versions/warn-2-1-only.md" >}}
-* You must install the experimental channel of the Kubernetes Gateway API at version 1.3 or later.
-
-1. Create a Gateway with a TCP listener. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}
- {{< tabs items="Gateway listeners,ListenerSets (experimental)" tabTotal="2" >}}
- {{% tab tabName="Gateway listeners" %}}
- ```yaml
- kubectl apply -f- <}}
- labels:
- app: tcp-echo
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- listeners:
- - protocol: TCP
- port: 8000
- name: tcp
- allowedRoutes:
- kinds:
- - kind: TCPRoute
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |--|--|
- |`spec.gatewayClassName`| The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}} |
- |`spec.listeners`|Configure the listeners for this Gateway. In this example, you configure a TCP Gateway that listens for incoming traffic on port 8000. The Gateway can serve TCPRoutes from any namespace. |
-
- {{% /tab %}}
- {{% tab tabName="ListenerSets (experimental)" %}}
-
- 1. Create a Gateway that enables the attachment of ListenerSets.
-
- ```yaml
- kubectl apply -f- <}}
- labels:
- app: tcp-echo
- spec:
- gatewayClassName: {{< reuse "agw-docs/snippets/gatewayclass.md" >}}
- allowedListeners:
- namespaces:
- from: All
- listeners:
- - protocol: TCP
- port: 80
- name: generic-tcp
- allowedRoutes:
- kinds:
- - kind: TCPRoute
- EOF
- ```
-
- {{< reuse "agw-docs/snippets/review-table.md" >}}
-
- |Setting|Description|
- |---|---|
- |`spec.gatewayClassName`|The name of the Kubernetes GatewayClass that you want to use to configure the Gateway. When you set up {{< reuse "agw-docs/snippets/kgateway.md" >}}, a default GatewayClass is set up for you. {{< reuse "agw-docs/snippets/agw-gatewayclass-choice.md" >}}|
- |`spec.allowedListeners`|Enable the attachment of ListenerSets to this Gateway. The example allows listeners from any namespace.|
- |`spec.listeners`|{{< reuse "agw-docs/snippets/generic-listener.md" >}} In this example, the generic listener is configured on port 80, which differs from port 8000 in the ListenerSet that you create later.|
-
- 2. Create a ListenerSet that configures a TCP listener for the Gateway.
-
- ```yaml
- kubectl apply -f- <