Repository: envoyproxy/gateway

Issue:
Create a design document for fuzz testing


Hints from issue comments:

Solution patch:
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index d3e8f96a0..653cc9bbf 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -27,6 +27,7 @@ updates:
   - package-ecosystem: gomod
     directories:
       - "/"
+      - "examples/*"
     schedule:
       interval: weekly
     ignore:
diff --git a/README.md b/README.md
index 6a50959a7..66026d003 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ Kubernetes-based application gateway.
 
 ## Contact
 
+* [envoy-gateway-announce](https://groups.google.com/g/envoy-gateway-announce): Join our mailing list to receive important announcements.
 * Slack: Join the [Envoy Slack workspace][] if you're not already a member. Otherwise, use the
   [Envoy Gateway channel][] to start collaborating with the community.
 
diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go
index b4ee4fcc9..26a4fb8fe 100644
--- a/api/v1alpha1/authorization_types.go
+++ b/api/v1alpha1/authorization_types.go
@@ -73,7 +73,7 @@ type Operation struct {
 // or any other identity that can be extracted from a custom header.
 // If there are multiple principal types, all principals must match for the rule to match.
 //
-// +kubebuilder:validation:XValidation:rule="(has(self.clientCIDRs) || has(self.jwt))",message="at least one of clientCIDRs or jwt must be specified"
+// +kubebuilder:validation:XValidation:rule="(has(self.clientCIDRs) || has(self.jwt) || has(self.headers))",message="at least one of clientCIDRs, jwt, or headers must be specified"
 type Principal struct {
 	// ClientCIDRs are the IP CIDR ranges of the client.
 	// Valid examples are "192.168.1.0/24" or "2001:db8::/64"
diff --git a/api/v1alpha1/ext_proc_types.go b/api/v1alpha1/ext_proc_types.go
index 234b7d0f4..88da0123c 100644
--- a/api/v1alpha1/ext_proc_types.go
+++ b/api/v1alpha1/ext_proc_types.go
@@ -17,6 +17,8 @@ const (
 	StreamedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Streamed"
 	// BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error.
 	BufferedExtProcBodyProcessingMode ExtProcBodyProcessingMode = "Buffered"
+	// FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode
+	FullDuplexStreamedExtBodyProcessingMode ExtProcBodyProcessingMode = "FullDuplexStreamed"
 	// BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent.
 	BufferedPartialExtBodyHeaderProcessingMode ExtProcBodyProcessingMode = "BufferedPartial"
 )
diff --git a/api/v1alpha1/httproutefilter_types.go b/api/v1alpha1/httproutefilter_types.go
index 3259fabc8..f156e7b94 100644
--- a/api/v1alpha1/httproutefilter_types.go
+++ b/api/v1alpha1/httproutefilter_types.go
@@ -7,6 +7,7 @@ package v1alpha1
 
 import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 )
 
 const (
@@ -35,6 +36,8 @@ type HTTPRouteFilterSpec struct {
 	URLRewrite *HTTPURLRewriteFilter `json:"urlRewrite,omitempty"`
 	// +optional
 	DirectResponse *HTTPDirectResponseFilter `json:"directResponse,omitempty"`
+	// +optional
+	CredentialInjection *HTTPCredentialInjectionFilter `json:"credentialInjection,omitempty"`
 }
 
 // HTTPURLRewriteFilter define rewrites of HTTP URL components such as path and host
@@ -140,6 +143,40 @@ type HTTPHostnameModifier struct {
 	Header *string `json:"header,omitempty"`
 }
 
+// HTTPCredentialInjectionFilter defines the configuration to inject credentials into the request.
+// This is useful when the backend service requires credentials in the request, and the original
+// request does not contain them. The filter can inject credentials into the request before forwarding
+// it to the backend service.
+// +notImplementedHide
+type HTTPCredentialInjectionFilter struct {
+	// Header is the name of the header where the credentials are injected.
+	// If not specified, the credentials are injected into the Authorization header.
+	// +optional
+	Header *string `json:"header,omitempty"`
+
+	// Whether to overwrite the value or not if the injected headers already exist.
+	// If not specified, the default value is false.
+	// +optional
+	Overwrite *bool `json:"overwrite"`
+
+	// Credential is the credential to be injected.
+	Credential InjectedCredential `json:"credential"`
+}
+
+// InjectedCredential defines the credential to be injected.
+// +notImplementedHide
+type InjectedCredential struct {
+	// ValueRef is a reference to the secret containing the credentials to be injected.
+	// This is an Opaque secret. The credential should be stored in the key
+	// "credential", and the value should be the credential to be injected.
+	// For example, for basic authentication, the value should be "Basic <base64 encoded username:password>".
+	// for bearer token, the value should be "Bearer <token>".
+	// Note: The secret must be in the same namespace as the HTTPRouteFilter.
+	ValueRef gwapiv1.SecretObjectReference `json:"valueRef"`
+
+	// EG may support more credential types in the future, for example, OAuth2 access token retrieved by Client Credentials Grant flow.
+}
+
 //+kubebuilder:object:root=true
 
 // HTTPRouteFilterList contains a list of HTTPRouteFilter resources.
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index bbb7c1145..8e87d5afd 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -2899,6 +2899,32 @@ func (in *HTTPClientTimeout) DeepCopy() *HTTPClientTimeout {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *HTTPCredentialInjectionFilter) DeepCopyInto(out *HTTPCredentialInjectionFilter) {
+	*out = *in
+	if in.Header != nil {
+		in, out := &in.Header, &out.Header
+		*out = new(string)
+		**out = **in
+	}
+	if in.Overwrite != nil {
+		in, out := &in.Overwrite, &out.Overwrite
+		*out = new(bool)
+		**out = **in
+	}
+	in.Credential.DeepCopyInto(&out.Credential)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPCredentialInjectionFilter.
+func (in *HTTPCredentialInjectionFilter) DeepCopy() *HTTPCredentialInjectionFilter {
+	if in == nil {
+		return nil
+	}
+	out := new(HTTPCredentialInjectionFilter)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *HTTPDirectResponseFilter) DeepCopyInto(out *HTTPDirectResponseFilter) {
 	*out = *in
@@ -3066,6 +3092,11 @@ func (in *HTTPRouteFilterSpec) DeepCopyInto(out *HTTPRouteFilterSpec) {
 		*out = new(HTTPDirectResponseFilter)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.CredentialInjection != nil {
+		in, out := &in.CredentialInjection, &out.CredentialInjection
+		*out = new(HTTPCredentialInjectionFilter)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilterSpec.
@@ -3333,6 +3364,22 @@ func (in *ImageWasmCodeSource) DeepCopy() *ImageWasmCodeSource {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *InjectedCredential) DeepCopyInto(out *InjectedCredential) {
+	*out = *in
+	in.ValueRef.DeepCopyInto(&out.ValueRef)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InjectedCredential.
+func (in *InjectedCredential) DeepCopy() *InjectedCredential {
+	if in == nil {
+		return nil
+	}
+	out := new(InjectedCredential)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *JSONPatchOperation) DeepCopyInto(out *JSONPatchOperation) {
 	*out = *in
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
index 491de3a72..319fa4df6 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_httproutefilters.yaml
@@ -49,6 +49,80 @@ spec:
           spec:
             description: Spec defines the desired state of HTTPRouteFilter.
             properties:
+              credentialInjection:
+                description: |-
+                  HTTPCredentialInjectionFilter defines the configuration to inject credentials into the request.
+                  This is useful when the backend service requires credentials in the request, and the original
+                  request does not contain them. The filter can inject credentials into the request before forwarding
+                  it to the backend service.
+                properties:
+                  credential:
+                    description: Credential is the credential to be injected.
+                    properties:
+                      valueRef:
+                        description: |-
+                          ValueRef is a reference to the secret containing the credentials to be injected.
+                          This is an Opaque secret. The credential should be stored in the key
+                          "credential", and the value should be the credential to be injected.
+                          For example, for basic authentication, the value should be "Basic <base64 encoded username:password>".
+                          for bearer token, the value should be "Bearer <token>".
+                          Note: The secret must be in the same namespace as the HTTPRouteFilter.
+                        properties:
+                          group:
+                            default: ""
+                            description: |-
+                              Group is the group of the referent. For example, "gateway.networking.k8s.io".
+                              When unspecified or empty string, core API group is inferred.
+                            maxLength: 253
+                            pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                            type: string
+                          kind:
+                            default: Secret
+                            description: Kind is kind of the referent. For example
+                              "Secret".
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
+                            type: string
+                          name:
+                            description: Name is the name of the referent.
+                            maxLength: 253
+                            minLength: 1
+                            type: string
+                          namespace:
+                            description: |-
+                              Namespace is the namespace of the referenced object. When unspecified, the local
+                              namespace is inferred.
+
+                              Note that when a namespace different than the local namespace is specified,
+                              a ReferenceGrant object is required in the referent namespace to allow that
+                              namespace's owner to accept the reference. See the ReferenceGrant
+                              documentation for details.
+
+                              Support: Core
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                            type: string
+                        required:
+                        - name
+                        type: object
+                    required:
+                    - valueRef
+                    type: object
+                  header:
+                    description: |-
+                      Header is the name of the header where the credentials are injected.
+                      If not specified, the credentials are injected into the Authorization header.
+                    type: string
+                  overwrite:
+                    description: |-
+                      Whether to overwrite the value or not if the injected headers already exist.
+                      If not specified, the default value is false.
+                    type: boolean
+                required:
+                - credential
+                type: object
               directResponse:
                 description: HTTPDirectResponseFilter defines the configuration to
                   return a fixed response.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index 6aa0d9dce..368d53dd1 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -372,8 +372,9 @@ spec:
                                 rule: (has(self.claims) || has(self.scopes))
                           type: object
                           x-kubernetes-validations:
-                          - message: at least one of clientCIDRs or jwt must be specified
-                            rule: (has(self.clientCIDRs) || has(self.jwt))
+                          - message: at least one of clientCIDRs, jwt, or headers
+                              must be specified
+                            rule: (has(self.clientCIDRs) || has(self.jwt) || has(self.headers))
                       required:
                       - action
                       - principal
diff --git a/examples/envoy-als/go.mod b/examples/envoy-als/go.mod
index f18b8a348..6cea3479c 100644
--- a/examples/envoy-als/go.mod
+++ b/examples/envoy-als/go.mod
@@ -3,25 +3,25 @@ module github.com/envoyproxy/gateway-envoy-als
 go 1.24.0
 
 require (
-	github.com/envoyproxy/go-control-plane v0.13.1
-	github.com/prometheus/client_golang v1.20.5
-	google.golang.org/grpc v1.67.1
+	github.com/envoyproxy/go-control-plane/envoy v1.32.4
+	github.com/prometheus/client_golang v1.21.1
+	google.golang.org/grpc v1.71.0
 )
 
 require (
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.3.0 // indirect
-	github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
-	github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
-	github.com/klauspost/compress v1.17.9 // indirect
+	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
+	github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
 	github.com/prometheus/client_model v0.6.1 // indirect
-	github.com/prometheus/common v0.55.0 // indirect
+	github.com/prometheus/common v0.62.0 // indirect
 	github.com/prometheus/procfs v0.15.1 // indirect
-	golang.org/x/net v0.34.0 // indirect
-	golang.org/x/sys v0.29.0 // indirect
-	golang.org/x/text v0.21.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
-	google.golang.org/protobuf v1.34.2 // indirect
+	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
+	google.golang.org/protobuf v1.36.5 // indirect
 )
diff --git a/examples/envoy-als/go.sum b/examples/envoy-als/go.sum
index 3be4ce0d5..c1238ad95 100644
--- a/examples/envoy-als/go.sum
+++ b/examples/envoy-als/go.sum
@@ -2,39 +2,67 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
-github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
-github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
-github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
+github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
+github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
+github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
 github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
-github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
-github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
+github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
 github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
 github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
-google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
+go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
+google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
+google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/examples/envoy-ext-auth/go.mod b/examples/envoy-ext-auth/go.mod
index b9400b077..5458c76cd 100644
--- a/examples/envoy-ext-auth/go.mod
+++ b/examples/envoy-ext-auth/go.mod
@@ -3,18 +3,18 @@ module github.com/envoyproxy/gateway-grcp-ext-auth
 go 1.24.0
 
 require (
-	github.com/envoyproxy/go-control-plane v0.13.1
+	github.com/envoyproxy/go-control-plane/envoy v1.32.4
 	github.com/golang/protobuf v1.5.4
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38
-	google.golang.org/grpc v1.67.1
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f
+	google.golang.org/grpc v1.71.0
 )
 
 require (
-	github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
-	github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
+	github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
-	golang.org/x/net v0.34.0 // indirect
-	golang.org/x/sys v0.29.0 // indirect
-	golang.org/x/text v0.21.0 // indirect
-	google.golang.org/protobuf v1.35.1 // indirect
+	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
+	google.golang.org/protobuf v1.36.5 // indirect
 )
diff --git a/examples/envoy-ext-auth/go.sum b/examples/envoy-ext-auth/go.sum
index 6e4c586b9..7fa0b367b 100644
--- a/examples/envoy-ext-auth/go.sum
+++ b/examples/envoy-ext-auth/go.sum
@@ -1,24 +1,42 @@
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
-github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
-github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
-github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
+github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
+github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 h1:zciRKQ4kBpFgpfC5QQCVtnnNAcLIqweL7plyZRQHVpI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI=
-google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
-google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
-google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
-google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
+go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
+google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
+google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index 52d92e8b6..0db3fe9ed 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -6,17 +6,17 @@ require (
 	github.com/envoyproxy/gateway v1.3.0
 	github.com/envoyproxy/go-control-plane v0.13.5-0.20250303232259-0c5cb90447bb
 	github.com/envoyproxy/go-control-plane/envoy v1.32.5-0.20250303232259-0c5cb90447bb
-	github.com/urfave/cli/v2 v2.27.5
-	google.golang.org/grpc v1.70.0
+	github.com/urfave/cli/v2 v2.27.6
+	google.golang.org/grpc v1.71.0
 	google.golang.org/protobuf v1.36.5
-	k8s.io/apimachinery v0.33.0-alpha.2
+	k8s.io/apimachinery v0.33.0-alpha.3
 	sigs.k8s.io/controller-runtime v0.20.2
 	sigs.k8s.io/gateway-api v1.2.1
 )
 
 require (
 	cel.dev/expr v0.19.1 // indirect
-	github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect
+	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
 	github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
 	github.com/fatih/color v1.18.0 // indirect
@@ -38,10 +38,10 @@ require (
 	github.com/x448/float16 v0.8.4 // indirect
 	github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
 	golang.org/x/mod v0.23.0 // indirect
-	golang.org/x/net v0.35.0 // indirect
-	golang.org/x/sync v0.11.0 // indirect
-	golang.org/x/sys v0.30.0 // indirect
-	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/sync v0.12.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/tools v0.30.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index 72842d102..c90c926ef 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -1,7 +1,7 @@
 cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4=
 cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
-github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
-github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -91,8 +91,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
-github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
+github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
+github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
@@ -122,23 +122,23 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
-golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
-golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
-golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
-golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
@@ -153,8 +153,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f h1:
 google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k=
 google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
-google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
-google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
 google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
 google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -173,8 +173,8 @@ k8s.io/api v0.32.2 h1:bZrMLEkgizC24G9eViHGOPbW+aRo9duEISRIJKfdJuw=
 k8s.io/api v0.32.2/go.mod h1:hKlhk4x1sJyYnHENsrdCWw31FEmCijNGPJO5WzHiJ6Y=
 k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4=
 k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
-k8s.io/apimachinery v0.33.0-alpha.2 h1:DygfxErwn1BHm5ACt87l3YhlX7rKyRg3QOgrkdNGa7o=
-k8s.io/apimachinery v0.33.0-alpha.2/go.mod h1:pvurfgWU15pkR11HFlMI9tdxY59XU+Wzo22Rx2iSD+g=
+k8s.io/apimachinery v0.33.0-alpha.3 h1:ugia3DzNbmhUP4mMUBhelThVifqQvB6YqrXz9Ncoans=
+k8s.io/apimachinery v0.33.0-alpha.3/go.mod h1:0rVRgdlgja0MQ+SYCognm5pRNteQOvhHAsDpKOs48GU=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
 k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
 k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
diff --git a/examples/grpc-ext-proc/go.mod b/examples/grpc-ext-proc/go.mod
index 9023d5d64..8f3adecc6 100644
--- a/examples/grpc-ext-proc/go.mod
+++ b/examples/grpc-ext-proc/go.mod
@@ -3,17 +3,17 @@ module github.com/envoyproxy/gateway-grpc-ext-proc
 go 1.24.0
 
 require (
-	github.com/envoyproxy/go-control-plane v0.13.1
-	google.golang.org/grpc v1.67.1
-	google.golang.org/protobuf v1.34.2
+	github.com/envoyproxy/go-control-plane/envoy v1.32.4
+	google.golang.org/grpc v1.71.0
+	google.golang.org/protobuf v1.36.5
 )
 
 require (
-	github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 // indirect
-	github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
+	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect
+	github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
-	golang.org/x/net v0.34.0 // indirect
-	golang.org/x/sys v0.29.0 // indirect
-	golang.org/x/text v0.21.0 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
+	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
 )
diff --git a/examples/grpc-ext-proc/go.sum b/examples/grpc-ext-proc/go.sum
index 0f73fe968..7fa0b367b 100644
--- a/examples/grpc-ext-proc/go.sum
+++ b/examples/grpc-ext-proc/go.sum
@@ -1,22 +1,42 @@
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20 h1:N+3sFI5GUjRKBi+i0TxYVST9h4Ie192jJWpHvthBBgg=
-github.com/cncf/xds/go v0.0.0-20240723142845-024c85f92f20/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE=
-github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw=
-github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM=
-github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A=
+github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw=
+github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
+github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
 github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
 github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo=
 github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
-google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
-google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
-google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
-google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
+go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
+go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
+go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
+go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
+go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
+go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
+go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
+go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
+google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
+google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
diff --git a/examples/preserve-case-backend/go.mod b/examples/preserve-case-backend/go.mod
index ce683792c..32bc13d30 100644
--- a/examples/preserve-case-backend/go.mod
+++ b/examples/preserve-case-backend/go.mod
@@ -2,10 +2,10 @@ module github.com/envoyproxy/gateway-preserve-case-backend
 
 go 1.24.0
 
-require github.com/valyala/fasthttp v1.51.0
+require github.com/valyala/fasthttp v1.59.0
 
 require (
-	github.com/andybalholm/brotli v1.0.5 // indirect
-	github.com/klauspost/compress v1.17.0 // indirect
+	github.com/andybalholm/brotli v1.1.1 // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/valyala/bytebufferpool v1.0.0 // indirect
 )
diff --git a/examples/preserve-case-backend/go.sum b/examples/preserve-case-backend/go.sum
index cfe8f6c10..2037bf9a4 100644
--- a/examples/preserve-case-backend/go.sum
+++ b/examples/preserve-case-backend/go.sum
@@ -1,8 +1,10 @@
-github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
-github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
+github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
-github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
+github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI=
+github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU=
+github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
+github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
diff --git a/go.mod b/go.mod
index 950428b84..71299e14c 100644
--- a/go.mod
+++ b/go.mod
@@ -7,8 +7,9 @@ require (
 	fortio.org/log v1.17.1
 	github.com/Masterminds/semver/v3 v3.3.1
 	github.com/andybalholm/brotli v1.1.1
+	github.com/avast/retry-go v3.0.0+incompatible
 	github.com/cenkalti/backoff/v4 v4.3.0
-	github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78
+	github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
 	github.com/docker/cli v28.0.1+incompatible
 	github.com/docker/docker v27.5.1+incompatible
@@ -36,10 +37,10 @@ require (
 	github.com/miekg/dns v1.1.63
 	github.com/ohler55/ojg v1.26.1
 	github.com/pkg/errors v0.9.1
-	github.com/prometheus/client_golang v1.20.5
+	github.com/prometheus/client_golang v1.21.1
 	github.com/prometheus/client_model v0.6.1
 	github.com/prometheus/common v0.62.0
-	github.com/replicatedhq/troubleshoot v0.107.5
+	github.com/replicatedhq/troubleshoot v0.117.0
 	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
@@ -58,15 +59,15 @@ require (
 	go.opentelemetry.io/proto/otlp v1.5.0
 	go.uber.org/zap v1.27.0
 	golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8
-	golang.org/x/net v0.35.0
+	golang.org/x/net v0.37.0
 	google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f
-	google.golang.org/grpc v1.70.0
+	google.golang.org/grpc v1.71.0
 	google.golang.org/protobuf v1.36.5
 	gopkg.in/yaml.v3 v3.0.1
 	helm.sh/helm/v3 v3.17.1
 	k8s.io/api v0.32.2
 	k8s.io/apiextensions-apiserver v0.32.2
-	k8s.io/apimachinery v0.33.0-alpha.2
+	k8s.io/apimachinery v0.33.0-alpha.3
 	k8s.io/cli-runtime v0.32.2
 	k8s.io/client-go v0.32.2
 	k8s.io/klog/v2 v2.130.1
@@ -157,7 +158,7 @@ require (
 	github.com/chai2010/gettext-go v1.0.2 // indirect
 	github.com/charithe/durationcheck v0.0.10 // indirect
 	github.com/chavacava/garif v0.1.0 // indirect
-	github.com/cilium/ebpf v0.16.0 // indirect
+	github.com/cilium/ebpf v0.17.3 // indirect
 	github.com/ckaznocha/intrange v0.3.0 // indirect
 	github.com/containerd/cgroups/v3 v3.0.5 // indirect
 	github.com/containerd/containerd v1.7.25 // indirect
@@ -169,10 +170,10 @@ require (
 	github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
 	github.com/containerd/ttrpc v1.2.7 // indirect
 	github.com/containerd/typeurl/v2 v2.2.3 // indirect
-	github.com/containers/image/v5 v5.32.2 // indirect
+	github.com/containers/image/v5 v5.34.0 // indirect
 	github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
-	github.com/containers/ocicrypt v1.2.0 // indirect
-	github.com/containers/storage v1.55.0 // indirect
+	github.com/containers/ocicrypt v1.2.1 // indirect
+	github.com/containers/storage v1.57.1 // indirect
 	github.com/coreos/go-semver v0.3.1 // indirect
 	github.com/coreos/go-systemd/v22 v22.5.0 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
@@ -180,13 +181,14 @@ require (
 	github.com/cyphar/filepath-securejoin v0.3.6 // indirect
 	github.com/daixiang0/gci v0.13.5 // indirect
 	github.com/denis-tingaikin/go-header v0.5.0 // indirect
-	github.com/distribution/distribution/v3 v3.0.0-beta.1 // indirect
+	github.com/distribution/distribution/v3 v3.0.0-rc.3 // indirect
 	github.com/distribution/reference v0.6.0 // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
 	github.com/docker/docker-credential-helpers v0.8.2 // indirect
 	github.com/docker/go-connections v0.5.0 // indirect
 	github.com/docker/go-metrics v0.0.1 // indirect
 	github.com/docker/go-units v0.5.0 // indirect
+	github.com/ebitengine/purego v0.8.2 // indirect
 	github.com/elastic/crd-ref-docs v0.1.0 // indirect
 	github.com/elliotchance/orderedmap/v2 v2.2.0 // indirect
 	github.com/emicklei/go-restful/v3 v3.12.0 // indirect
@@ -274,7 +276,7 @@ require (
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
 	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
-	github.com/jackc/pgx/v5 v5.7.1 // indirect
+	github.com/jackc/pgx/v5 v5.7.2 // indirect
 	github.com/jdx/go-netrc v1.0.0 // indirect
 	github.com/jgautheron/goconst v1.7.1 // indirect
 	github.com/jingyugao/rowserrcheck v1.1.1 // indirect
@@ -318,7 +320,7 @@ require (
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/mgechev/revive v1.6.1 // indirect
-	github.com/microsoft/go-mssqldb v1.7.2 // indirect
+	github.com/microsoft/go-mssqldb v1.8.0 // indirect
 	github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
 	github.com/mitchellh/copystructure v1.2.0 // indirect
 	github.com/mitchellh/go-homedir v1.1.0 // indirect
@@ -329,6 +331,7 @@ require (
 	github.com/moby/locker v1.0.1 // indirect
 	github.com/moby/patternmatcher v0.6.0 // indirect
 	github.com/moby/spdystream v0.5.0 // indirect
+	github.com/moby/sys/capability v0.4.0 // indirect
 	github.com/moby/sys/mount v0.3.4 // indirect
 	github.com/moby/sys/mountinfo v0.7.2 // indirect
 	github.com/moby/sys/reexec v0.1.0 // indirect
@@ -354,7 +357,7 @@ require (
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.0 // indirect
 	github.com/opencontainers/runtime-spec v1.2.0 // indirect
-	github.com/opencontainers/selinux v1.11.0 // indirect
+	github.com/opencontainers/selinux v1.11.1 // indirect
 	github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
@@ -392,6 +395,7 @@ require (
 	github.com/segmentio/encoding v0.4.1 // indirect
 	github.com/segmentio/ksuid v1.0.4 // indirect
 	github.com/shirou/gopsutil/v3 v3.24.5 // indirect
+	github.com/shirou/gopsutil/v4 v4.25.1 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
 	github.com/shopspring/decimal v1.4.0 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
@@ -408,9 +412,8 @@ require (
 	github.com/stoewer/go-strcase v1.3.0 // indirect
 	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
-	github.com/sylabs/sif/v2 v2.18.0 // indirect
-	github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
-	github.com/tchap/go-patricia/v2 v2.3.1 // indirect
+	github.com/sylabs/sif/v2 v2.20.2 // indirect
+	github.com/tchap/go-patricia/v2 v2.3.2 // indirect
 	github.com/tdakkota/asciicheck v0.4.0 // indirect
 	github.com/tetafro/godot v1.4.20 // indirect
 	github.com/tetratelabs/wazero v1.8.2 // indirect
@@ -424,17 +427,19 @@ require (
 	github.com/ulikunitz/xz v0.5.12 // indirect
 	github.com/ultraware/funlen v0.2.0 // indirect
 	github.com/ultraware/whitespace v0.2.0 // indirect
-	github.com/urfave/cli/v2 v2.8.1 // indirect
+	github.com/urfave/cli/v2 v2.27.6 // indirect
 	github.com/uudashr/gocognit v1.2.0 // indirect
 	github.com/uudashr/iface v1.3.1 // indirect
-	github.com/vbatts/tar-split v0.11.6 // indirect
+	github.com/vbatts/tar-split v0.11.7 // indirect
+	github.com/vishvananda/netlink v1.3.0 // indirect
+	github.com/vishvananda/netns v0.0.5 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
 	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 	github.com/xeipuuv/gojsonschema v1.2.0 // indirect
 	github.com/xen0n/gosmopolitan v1.2.2 // indirect
 	github.com/xlab/treeprint v1.2.0 // indirect
-	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
+	github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
 	github.com/yagipy/maintidx v1.0.0 // indirect
 	github.com/yeya24/promlinter v0.3.0 // indirect
 	github.com/ykadowak/zerologlint v0.1.5 // indirect
@@ -454,22 +459,22 @@ require (
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 // indirect
 	go.opentelemetry.io/otel/trace v1.34.0 // indirect
 	go.uber.org/automaxprocs v1.6.0 // indirect
 	go.uber.org/mock v0.5.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap/exp v0.3.0 // indirect
-	golang.org/x/crypto v0.35.0 // indirect
+	golang.org/x/crypto v0.36.0 // indirect
 	golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008 // indirect
 	golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect
 	golang.org/x/mod v0.23.0 // indirect
 	golang.org/x/oauth2 v0.27.0 // indirect
-	golang.org/x/sync v0.11.0 // indirect
-	golang.org/x/sys v0.30.0 // indirect
-	golang.org/x/term v0.29.0 // indirect
-	golang.org/x/text v0.22.0 // indirect
+	golang.org/x/sync v0.12.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/term v0.30.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/time v0.9.0 // indirect
 	golang.org/x/tools v0.30.0 // indirect
 	golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
@@ -488,7 +493,7 @@ require (
 	mvdan.cc/gofumpt v0.7.0 // indirect
 	mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect
 	oras.land/oras-go v1.2.6 // indirect
-	periph.io/x/host/v3 v3.8.2 // indirect
+	periph.io/x/host/v3 v3.8.3 // indirect
 	pluginrpc.com/pluginrpc v0.5.0 // indirect
 	sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.1 // indirect
 	sigs.k8s.io/controller-runtime/tools/setup-envtest v0.0.0-20250217160221-5e8256e05002 // indirect
diff --git a/go.sum b/go.sum
index 0d5d83f0c..9ebdfd47c 100644
--- a/go.sum
+++ b/go.sum
@@ -169,6 +169,8 @@ github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8ger
 github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU=
 github.com/ashanbrown/makezero v1.2.0 h1:/2Lp1bypdmK9wDIq7uWBlDF1iMUpIIS4A+pF6C9IEUU=
 github.com/ashanbrown/makezero v1.2.0/go.mod h1:dxlPhHbDMC6N6xICzFBSK+4njQDdK8euNO0qjQMtGY4=
+github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0=
+github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -228,14 +230,14 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
 github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
 github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
-github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok=
-github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE=
+github.com/cilium/ebpf v0.17.3 h1:FnP4r16PWYSE4ux6zN+//jMcW4nMVRvuTLVTvCjyyjg=
+github.com/cilium/ebpf v0.17.3/go.mod h1:G5EDHij8yiLzaqn0WjyfJHvRa+3aDlReIaLVRMvOyJk=
 github.com/ckaznocha/intrange v0.3.0 h1:VqnxtK32pxgkhJgYQEeOArVidIPg+ahLP7WBOXZd5ZY=
 github.com/ckaznocha/intrange v0.3.0/go.mod h1:+I/o2d2A1FBHgGELbGxzIcyd3/9l9DuwjM8FsbSS3Lo=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI=
-github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
+github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
 github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
@@ -257,14 +259,14 @@ github.com/containerd/ttrpc v1.2.7 h1:qIrroQvuOL9HQ1X6KHe2ohc7p+HP/0VE6XPU7elJRq
 github.com/containerd/ttrpc v1.2.7/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
 github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
 github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
-github.com/containers/image/v5 v5.32.2 h1:SzNE2Y6sf9b1GJoC8qjCuMBXwQrACFp4p0RK15+4gmQ=
-github.com/containers/image/v5 v5.32.2/go.mod h1:v1l73VeMugfj/QtKI+jhYbwnwFCFnNGckvbST3rQ5Hk=
+github.com/containers/image/v5 v5.34.0 h1:HPqQaDUsox/3mC1pbOyLAIQEp0JhQqiUZ+6JiFIZLDI=
+github.com/containers/image/v5 v5.34.0/go.mod h1:/WnvUSEfdqC/ahMRd4YJDBLrpYWkGl018rB77iB3FDo=
 github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
 github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
-github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
-github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
-github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg=
-github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ=
+github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
+github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
+github.com/containers/storage v1.57.1 h1:hKPoFsuBcB3qTzBxa4IFpZMRzUuL5Xhv/BE44W0XHx8=
+github.com/containers/storage v1.57.1/go.mod h1:i/Hb4lu7YgFr9G0K6BMjqW0BLJO1sFsnWQwj2UoWCUM=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@@ -305,8 +307,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
 github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfGUhc8I+MPfRis8dZ818Ic=
-github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs=
+github.com/distribution/distribution/v3 v3.0.0-rc.3 h1:JRJso9IVLoooKX76oWR+DWCCdZlK5m4nRtDWvzB1ITg=
+github.com/distribution/distribution/v3 v3.0.0-rc.3/go.mod h1:offoOgrnYs+CFwis8nE0hyzYZqRCZj5EFc5kgfszwiE=
 github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
 github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
 github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
@@ -340,6 +342,8 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
+github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I=
+github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
 github.com/elastic/crd-ref-docs v0.1.0 h1:Cr5kz89QB3Iuuj7dhAfLMApCrChEGAaIBTxGk/xuRKw=
 github.com/elastic/crd-ref-docs v0.1.0/go.mod h1:X83mMBdJt05heJUYiS3T0yJ/JkCuliuhSUNav5Gjo/U=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -730,8 +734,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
 github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
 github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
 github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs=
-github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA=
+github.com/jackc/pgx/v5 v5.7.2 h1:mLoDLV6sonKlvjIEsV56SkWNCnuNv531l94GaIzO+XI=
+github.com/jackc/pgx/v5 v5.7.2/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
 github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
 github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
 github.com/jdx/go-netrc v1.0.0 h1:QbLMLyCZGj0NA8glAhxUpf1zDg6cxnWgMBbjq40W0gQ=
@@ -870,8 +874,9 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
+github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
 github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw=
@@ -879,8 +884,8 @@ github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U
 github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
 github.com/mgechev/revive v1.6.1 h1:ncK0ZCMWtb8GXwVAmk+IeWF2ULIDsvRxSRfg5sTwQ2w=
 github.com/mgechev/revive v1.6.1/go.mod h1:/2tfHWVO8UQi/hqJsIYNEKELi+DJy/e+PQpLgTB1v88=
-github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA=
-github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA=
+github.com/microsoft/go-mssqldb v1.8.0 h1:7cyZ/AT7ycDsEoWPIXibd+aVKFtteUNhDGf3aobP+tw=
+github.com/microsoft/go-mssqldb v1.8.0/go.mod h1:6znkekS3T2vp0waiMhen4GPU1BiAsrP+iXHcE7a7rFo=
 github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
 github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
 github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
@@ -904,6 +909,8 @@ github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkV
 github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
 github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
 github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
+github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
+github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
 github.com/moby/sys/mount v0.3.4 h1:yn5jq4STPztkkzSKpZkLcmjue+bZJ0u2AuQY1iNI1Ww=
 github.com/moby/sys/mount v0.3.4/go.mod h1:KcQJMbQdJHPlq5lcYT+/CjatWM4PuxKe+XLSVS4J6Os=
 github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
@@ -982,8 +989,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ
 github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
 github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
 github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
-github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
+github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8=
+github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
 github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
 github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
 github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
@@ -1031,8 +1038,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
-github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
+github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
+github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -1075,8 +1082,8 @@ github.com/redis/go-redis/extra/redisotel/v9 v9.0.5 h1:EfpWLLCyXw8PSM2/XNJLjI3Pb
 github.com/redis/go-redis/extra/redisotel/v9 v9.0.5/go.mod h1:WZjPDy7VNzn77AAfnAfVjZNvfJTYfPetfZk5yoSTLaQ=
 github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
 github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
-github.com/replicatedhq/troubleshoot v0.107.5 h1:XrJEK8vN3HHEKmFnAe8rSmY+hPw8Fh5dsTMhhEBKQCM=
-github.com/replicatedhq/troubleshoot v0.107.5/go.mod h1:QTV4q6TXiCO825IS1GcLzgJu2KHWekXiKdcHCqBJTck=
+github.com/replicatedhq/troubleshoot v0.117.0 h1:FCw8VodGF/tetL7ZvdOhnjFDOvSDqMq/kce9/dsfHfc=
+github.com/replicatedhq/troubleshoot v0.117.0/go.mod h1:Xt6P84cvEyfyp9J/7EblCqINXHeTc+1zqfJY/KqjOss=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
 github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -1107,8 +1114,8 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM
 github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
 github.com/sashamelentyev/usestdlibvars v1.28.0 h1:jZnudE2zKCtYlGzLVreNp5pmCdOxXUzwsMDBkR21cyQ=
 github.com/sashamelentyev/usestdlibvars v1.28.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8=
-github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
-github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
+github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
+github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
 github.com/securego/gosec/v2 v2.22.1 h1:IcBt3TpI5Y9VN1YlwjSpM2cHu0i3Iw52QM+PQeg7jN8=
 github.com/securego/gosec/v2 v2.22.1/go.mod h1:4bb95X4Jz7VSEPdVjC0hD7C/yR6kdeUBvCPOy9gDQ0g=
 github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
@@ -1122,6 +1129,8 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
 github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
 github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI=
 github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk=
+github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs=
+github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI=
 github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
 github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
 github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
@@ -1200,12 +1209,10 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
 github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
-github.com/sylabs/sif/v2 v2.18.0 h1:eXugsS1qx7St2Wu/AJ21KnsQiVCpouPlTigABh+6KYI=
-github.com/sylabs/sif/v2 v2.18.0/go.mod h1:GOQj7LIBqp15fjqH5i8ZEbLp8SXJi9S+xbRO+QQAdRo=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
-github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
-github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
-github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
+github.com/sylabs/sif/v2 v2.20.2 h1:HGEPzauCHhIosw5o6xmT3jczuKEuaFzSfdjAsH33vYw=
+github.com/sylabs/sif/v2 v2.20.2/go.mod h1:WyYryGRaR4Wp21SAymm5pK0p45qzZCSRiZMFvUZiuhc=
+github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM=
+github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
 github.com/tdakkota/asciicheck v0.4.0 h1:VZ13Itw4k1i7d+dpDSNS8Op645XgGHpkCEh/WHicgWw=
 github.com/tdakkota/asciicheck v0.4.0/go.mod h1:0k7M3rCfRXb0Z6bwgvkEIMleKH3kXNz9UqJ9Xuqopr8=
 github.com/telepresenceio/telepresence/rpc/v2 v2.6.8 h1:q5V85LBT9bA/c4YPa/kMvJGyKZDgBPJTftlAMqJx7j4=
@@ -1252,15 +1259,20 @@ github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSx
 github.com/ultraware/whitespace v0.2.0 h1:TYowo2m9Nfj1baEQBjuHzvMRbp19i+RCcRYrSWoFa+g=
 github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-github.com/urfave/cli/v2 v2.8.1 h1:CGuYNZF9IKZY/rfBe3lJpccSoIY1ytfvmgQT90cNOl4=
-github.com/urfave/cli/v2 v2.8.1/go.mod h1:Z41J9TPoffeoqP0Iza0YbAhGvymRdZAd2uPmZ5JxRdY=
+github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
+github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
 github.com/uudashr/gocognit v1.2.0 h1:3BU9aMr1xbhPlvJLSydKwdLN3tEUUrzPSSM8S4hDYRA=
 github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
 github.com/uudashr/iface v1.3.1 h1:bA51vmVx1UIhiIsQFSNq6GZ6VPTk3WNMZgRiCe9R29U=
 github.com/uudashr/iface v1.3.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg=
-github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23envGs=
-github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI=
+github.com/vbatts/tar-split v0.11.7 h1:ixZ93pO/GmvaZw4Vq9OwmfZK/kc2zKdPfu0B+gYqs3U=
+github.com/vbatts/tar-split v0.11.7/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
 github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
+github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
+github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
+github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
+github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
 github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
 github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -1278,8 +1290,8 @@ github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q
 github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
 github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
 github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
 github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
 github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
@@ -1345,34 +1357,46 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/contrib/exporters/autoexport v0.46.1 h1:ysCfPZB9AjUlMa1UHYup3c9dAOCMQX/6sxSfPBUoxHw=
-go.opentelemetry.io/contrib/exporters/autoexport v0.46.1/go.mod h1:ha0aiYm+DOPsLHjh0zoQ8W8sLT+LJ58J3j47lGpSLrU=
+go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w=
+go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk=
+go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4=
+go.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
 go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
 go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0/go.mod h1:hKvJwTzJdp90Vh7p6q/9PAOd55dI6WA6sWj62a/JvSs=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0 h1:S+LdBGiQXtJdowoJoQPEtI52syEP/JYBUpjO49EQhV8=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.8.0/go.mod h1:5KXybFvPGds3QinJWQT7pmXf+TN5YIa7CNYObWRkj50=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0 h1:ajl4QczuJVA2TU9W9AGw++86Xga/RKt//16z/yxPgdk=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.34.0/go.mod h1:Vn3/rlOJ3ntf/Q3zAI0V5lDnTbHGaUsNUeF6nZmm7pA=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0 h1:IJFEoHiytixx8cMiVAO+GmHR6Frwu+u5Ur8njpFO6Ac=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.32.0/go.mod h1:3rHrKNtLIoS0oZwkY2vxi+oJcwFRWdtUyRII+so45p8=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0 h1:9kV11HXBHZAvuPUZxmMWrH8hZn/6UnHX4K0mu36vNsU=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.32.0/go.mod h1:JyA0FHXe22E1NeNiHmVp7kFHglnexDQ7uRWDiiJ1hKQ=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
 go.opentelemetry.io/otel/exporters/prometheus v0.56.0 h1:GnCIi0QyG0yy2MrJLzVrIM7laaJstj//flf1zEJCG+E=
 go.opentelemetry.io/otel/exporters/prometheus v0.56.0/go.mod h1:JQcVZtbIIPM+7SWBB+T6FK+xunlyidwLp++fN0sUaOk=
+go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0 h1:CHXNXwfKWfzS65yrlB2PVds1IBZcdsX8Vepy9of0iRU=
+go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.8.0/go.mod h1:zKU4zUgKiaRxrdovSS2amdM5gOc59slmo/zJwGX+YBg=
 go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.34.0 h1:czJDQwFrMbOr9Kk+BPo1y8WZIIFIK58SA1kykuVeiOU=
 go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.34.0/go.mod h1:lT7bmsxOe58Tq+JIOkTQMCGXdu47oA+VJKLZHbaBKbs=
-go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec=
-go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0 h1:cC2yDI3IQd0Udsux7Qmq8ToKAx1XCilTQECZ0KDZyTw=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.32.0/go.mod h1:2PD5Ex6z8CFzDbTdOlwyNIUywRr1DN0ospafJM1wJ+s=
+go.opentelemetry.io/otel/log v0.8.0 h1:egZ8vV5atrUWUbnSsHn6vB8R21G2wrKqNiDt3iWertk=
+go.opentelemetry.io/otel/log v0.8.0/go.mod h1:M9qvDdUTRCopJcGRKg57+JSQ9LgLBrwwfC32epk5NX8=
 go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
 go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
 go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
 go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
+go.opentelemetry.io/otel/sdk/log v0.8.0 h1:zg7GUYXqxk1jnGF/dTdLPrK06xJdrXgqgFLnI4Crxvs=
+go.opentelemetry.io/otel/sdk/log v0.8.0/go.mod h1:50iXr0UVwQrYS45KbruFrEt4LvAdCaWWgIrsN3ZQggo=
 go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
 go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
 go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
@@ -1408,8 +1432,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
-golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs=
-golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
 golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008 h1:vKHSxFhPLnBEYu9R8DcQ4gXq9EqU0VVhC9pq9wmtYsg=
 golang.org/x/crypto/x509roots/fallback v0.0.0-20240904212608-c9da6b9a4008/go.mod h1:kNa9WdvYnzFwC79zRpLRMJbdEFlhyM5RPFBBZp/wWH8=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1470,8 +1494,8 @@ golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
-golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
+golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
+golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1490,8 +1514,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
-golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
-golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1540,11 +1564,12 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
-golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@@ -1553,8 +1578,8 @@ golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
 golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
-golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
-golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1567,8 +1592,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
-golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1640,8 +1665,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ
 google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ=
-google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw=
+google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
+google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1712,8 +1737,8 @@ k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscgh
 k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
 k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
 k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
-k8s.io/apimachinery v0.33.0-alpha.2 h1:DygfxErwn1BHm5ACt87l3YhlX7rKyRg3QOgrkdNGa7o=
-k8s.io/apimachinery v0.33.0-alpha.2/go.mod h1:pvurfgWU15pkR11HFlMI9tdxY59XU+Wzo22Rx2iSD+g=
+k8s.io/apimachinery v0.33.0-alpha.3 h1:ugia3DzNbmhUP4mMUBhelThVifqQvB6YqrXz9Ncoans=
+k8s.io/apimachinery v0.33.0-alpha.3/go.mod h1:0rVRgdlgja0MQ+SYCognm5pRNteQOvhHAsDpKOs48GU=
 k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
 k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8=
 k8s.io/apiserver v0.32.2 h1:WzyxAu4mvLkQxwD9hGa4ZfExo3yZZaYzoYvvVDlM6vw=
@@ -1758,8 +1783,8 @@ mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8
 mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ=
 oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk=
 oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8=
-periph.io/x/host/v3 v3.8.2 h1:ayKUDzgUCN0g8+/xM9GTkWaOBhSLVcVHGTfjAOi8OsQ=
-periph.io/x/host/v3 v3.8.2/go.mod h1:yFL76AesNHR68PboofSWYaQTKmvPXsQH2Apvp/ls/K4=
+periph.io/x/host/v3 v3.8.3 h1:v90ozCFDWgEyfNElZ+JnOvq0jAdW0vmgjCUy8dYXDds=
+periph.io/x/host/v3 v3.8.3/go.mod h1:uKrIpfXjELwHkwGBNe6aos//XiQ/3uxDa1P2BmLV6Ok=
 pluginrpc.com/pluginrpc v0.5.0 h1:tOQj2D35hOmvHyPu8e7ohW2/QvAnEtKscy2IJYWQ2yo=
 pluginrpc.com/pluginrpc v0.5.0/go.mod h1:UNWZ941hcVAoOZUn8YZsMmOZBzbUjQa3XMns8RQLp9o=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
diff --git a/internal/gatewayapi/resource/load.go b/internal/gatewayapi/resource/load.go
index e3357b0b2..b3d1a523a 100644
--- a/internal/gatewayapi/resource/load.go
+++ b/internal/gatewayapi/resource/load.go
@@ -21,6 +21,7 @@ import (
 	utilyaml "k8s.io/apimachinery/pkg/util/yaml"
 	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 	gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	gwapiv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 	"sigs.k8s.io/yaml"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
@@ -341,6 +342,19 @@ func loadKubernetesYAMLToResources(input []byte, addMissingResources bool) (*Res
 				Data: typedData.(map[string]string),
 			}
 			resources.ConfigMaps = append(resources.ConfigMaps, configMap)
+		case KindBackendTLSPolicy:
+			typedSpec := spec.Interface()
+			backendTLSPolicy := &gwapiv1a3.BackendTLSPolicy{
+				TypeMeta: metav1.TypeMeta{
+					Kind: KindBackendTLSPolicy,
+				},
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      name,
+					Namespace: namespace,
+				},
+				Spec: typedSpec.(gwapiv1a3.BackendTLSPolicySpec),
+			}
+			resources.BackendTLSPolicies = append(resources.BackendTLSPolicies, backendTLSPolicy)
 		}
 
 		return nil
diff --git a/internal/gatewayapi/securitypolicy.go b/internal/gatewayapi/securitypolicy.go
index 7d5e18e49..9f1193319 100644
--- a/internal/gatewayapi/securitypolicy.go
+++ b/internal/gatewayapi/securitypolicy.go
@@ -1278,7 +1278,7 @@ func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Auth
 	irAuth.DefaultAction = defaultAction
 
 	for i, rule := range authorization.Rules {
-		principal := ir.Principal{}
+		irPrincipal := ir.Principal{}
 
 		for _, cidr := range rule.Principal.ClientCIDRs {
 			cidrMatch, err := parseCIDR(string(cidr))
@@ -1286,10 +1286,11 @@ func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Auth
 				return nil, fmt.Errorf("unable to translate authorization rule: %w", err)
 			}
 
-			principal.ClientCIDRs = append(principal.ClientCIDRs, cidrMatch)
+			irPrincipal.ClientCIDRs = append(irPrincipal.ClientCIDRs, cidrMatch)
 		}
 
-		principal.JWT = rule.Principal.JWT
+		irPrincipal.JWT = rule.Principal.JWT
+		irPrincipal.Headers = rule.Principal.Headers
 
 		var name string
 		if rule.Name != nil && *rule.Name != "" {
@@ -1300,7 +1301,8 @@ func (t *Translator) buildAuthorization(policy *egv1a1.SecurityPolicy) (*ir.Auth
 		irAuth.Rules = append(irAuth.Rules, &ir.AuthorizationRule{
 			Name:      name,
 			Action:    rule.Action,
-			Principal: principal,
+			Operation: rule.Operation,
+			Principal: irPrincipal,
 		})
 	}
 
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 368e7d5db..15a8e28c8 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -1241,6 +1241,9 @@ type AuthorizationRule struct {
 	// Action defines the action to be taken if the rule matches.
 	Action egv1a1.AuthorizationAction `json:"action"`
 
+	// Operation specifies the operation of a request, such as HTTP methods.
+	Operation *egv1a1.Operation `json:"operation,omitempty"`
+
 	// Principal defines the principal to be matched.
 	Principal Principal `json:"principal"`
 }
@@ -1253,6 +1256,8 @@ type Principal struct {
 	ClientCIDRs []*CIDRMatch `json:"clientCIDRs,omitempty"`
 	// JWT defines the JWT principal to be matched.
 	JWT *egv1a1.JWTPrincipal `json:"jwt,omitempty"`
+	// Headers defines the headers to be matched.
+	Headers []egv1a1.AuthorizationHeaderMatch `json:"headers,omitempty"`
 }
 
 // FaultInjection defines the schema for injecting faults into requests.
@@ -2794,6 +2799,8 @@ const (
 	ExtProcBodyBuffered = ExtProcBodyProcessingMode(egv1a1.BufferedExtProcBodyProcessingMode)
 	// ExtProcBodyBufferedPartial sets the partial buffered body processing mode
 	ExtProcBodyBufferedPartial = ExtProcBodyProcessingMode(egv1a1.BufferedPartialExtBodyHeaderProcessingMode)
+	// ExtProcBodyFullDuplexStreamed sets the full duplex streamed processing mode
+	ExtProcBodyFullDuplexStreamed = ExtProcBodyProcessingMode(egv1a1.FullDuplexStreamedExtBodyProcessingMode)
 )
 
 // ExtProc holds the information associated with the ExtProc extensions.
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index 4735b2e73..c2ae3f040 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -294,6 +294,11 @@ func (in *Authorization) DeepCopy() *Authorization {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *AuthorizationRule) DeepCopyInto(out *AuthorizationRule) {
 	*out = *in
+	if in.Operation != nil {
+		in, out := &in.Operation, &out.Operation
+		*out = new(v1alpha1.Operation)
+		(*in).DeepCopyInto(*out)
+	}
 	in.Principal.DeepCopyInto(&out.Principal)
 }
 
@@ -2464,6 +2469,13 @@ func (in *Principal) DeepCopyInto(out *Principal) {
 		*out = new(v1alpha1.JWTPrincipal)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.Headers != nil {
+		in, out := &in.Headers, &out.Headers
+		*out = make([]v1alpha1.AuthorizationHeaderMatch, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal.
diff --git a/internal/wasm/cache.go b/internal/wasm/cache.go
index 785d8d370..7a045038f 100644
--- a/internal/wasm/cache.go
+++ b/internal/wasm/cache.go
@@ -67,11 +67,16 @@ type localFileCache struct {
 	// option sets for configuring the cache.
 	CacheOptions
 
+	// permissionCheckCache is the cache for permission check for private OCI images.
+	// The permission check is run periodically by a background goroutine and the result is cached.
+	permissionCheckCache *permissionCache
+
 	// logger
 	logger logging.Logger
 }
 
 func (c *localFileCache) Start(ctx context.Context) {
+	c.permissionCheckCache.Start(ctx)
 	go c.purge(ctx)
 }
 
@@ -131,9 +136,12 @@ type cacheEntry struct {
 func newLocalFileCache(options CacheOptions, logger logging.Logger) *localFileCache {
 	options = options.sanitize()
 	cache := &localFileCache{
-		httpFetcher:  NewHTTPFetcher(options.HTTPRequestTimeout, options.HTTPRequestMaxRetries, logger),
-		modules:      make(map[moduleKey]*cacheEntry),
-		checksums:    make(map[string]*checksumEntry),
+		httpFetcher: NewHTTPFetcher(options.HTTPRequestTimeout, options.HTTPRequestMaxRetries, logger),
+		modules:     make(map[moduleKey]*cacheEntry),
+		checksums:   make(map[string]*checksumEntry),
+		permissionCheckCache: newPermissionCache(
+			permissionCacheOptions{},
+			logger),
 		CacheOptions: options,
 		logger:       logger,
 	}
@@ -220,7 +228,7 @@ func (c *localFileCache) getOrFetch(key cacheKey, opts GetOptions) (*cacheEntry,
 	if ce != nil {
 		// We still need to check if the pull secret is correct if it is a private OCI image.
 		if u.Scheme == "oci" && ce.isPrivate {
-			if err = c.checkPermission(ctx, u, insecure, opts); err != nil {
+			if _, err := c.permissionCheckCache.IsAllowed(ctx, u, opts.PullSecret, insecure); err != nil {
 				return nil, err
 			}
 		}
@@ -250,7 +258,24 @@ func (c *localFileCache) getOrFetch(key cacheKey, opts GetOptions) (*cacheEntry,
 		if len(opts.PullSecret) > 0 {
 			isPrivate = true
 		}
-		if imageBinaryFetcher, dChecksum, err = c.prepareFetch(ctx, u, insecure, opts); err != nil {
+
+		imageBinaryFetcher, dChecksum, err = c.prepareFetch(ctx, u, insecure, opts.PullSecret)
+
+		if isPrivate {
+			e := &permissionCacheEntry{
+				image: u,
+				fetcherOption: &ImageFetcherOption{
+					Insecure:   insecure,
+					PullSecret: opts.PullSecret,
+				},
+				lastCheck:  time.Now(),
+				lastAccess: time.Now(),
+				checkError: err,
+			}
+			c.permissionCheckCache.Put(e)
+		}
+
+		if err != nil {
 			wasmRemoteFetchTotal.WithFailure(reasonManifestError).Increment()
 			return nil, fmt.Errorf("could not fetch Wasm OCI image: %w", err)
 		}
@@ -287,24 +312,16 @@ func (c *localFileCache) getOrFetch(key cacheKey, opts GetOptions) (*cacheEntry,
 	return c.addEntry(key, b, isPrivate)
 }
 
-func (c *localFileCache) checkPermission(ctx context.Context, u *url.URL, insecure bool, opts GetOptions) error {
-	// Try to get the image metadata to check if the pull secret is correct.
-	if _, _, err := c.prepareFetch(ctx, u, insecure, opts); err != nil {
-		return fmt.Errorf("failed to login to private registry: %w", err)
-	}
-	return nil
-}
-
 // prepareFetch won't fetch the binary, but it will prepare the binaryFetcher and actualDigest.
 func (c *localFileCache) prepareFetch(
-	ctx context.Context, url *url.URL, insecure bool, opts GetOptions) (
+	ctx context.Context, url *url.URL, insecure bool, pullSecret []byte) (
 	binaryFetcher func() ([]byte, error), actualDigest string, err error,
 ) {
 	imgFetcherOps := ImageFetcherOption{
 		Insecure: insecure,
 	}
-	if len(opts.PullSecret) > 0 {
-		imgFetcherOps.PullSecret = opts.PullSecret
+	if len(pullSecret) > 0 {
+		imgFetcherOps.PullSecret = pullSecret
 	}
 	fetcher := NewImageFetcher(ctx, imgFetcherOps, c.logger)
 	if binaryFetcher, actualDigest, err = fetcher.PrepareFetch(url.Host + url.Path); err != nil {
diff --git a/internal/wasm/premissioncache.go b/internal/wasm/premissioncache.go
new file mode 100644
index 000000000..e680574ad
--- /dev/null
+++ b/internal/wasm/premissioncache.go
@@ -0,0 +1,266 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+// 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.
+
+package wasm
+
+import (
+	"context"
+	"encoding/hex"
+	"errors"
+	"fmt"
+	"net/http"
+	"net/url"
+	"sync"
+	"time"
+
+	"github.com/avast/retry-go"
+	"github.com/google/go-containerregistry/pkg/v1/remote/transport"
+
+	"github.com/envoyproxy/gateway/internal/logging"
+)
+
+type permissionCacheOptions struct {
+	// checkInterval is the interval to recheck the permission for the cached permission entries.
+	checkInterval time.Duration
+
+	// permissionExpiry is the expiry time for permission cache entry.
+	// The permission cache entry will be updated by rechecking the OCI image permission against the pull secret.
+	permissionExpiry time.Duration
+
+	// cacheExpiry is the expiry time for the permission cache.
+	// The permission cache will be removed if it is not accessed for the specified expiry time.
+	// This is used to purge the cache.
+	cacheExpiry time.Duration
+}
+
+// sanitize validates and sets the default values for the permission cache options.
+func (o *permissionCacheOptions) sanitize() {
+	if o.checkInterval == 0 {
+		o.checkInterval = 5 * time.Minute
+	}
+	if o.permissionExpiry == 0 {
+		o.permissionExpiry = 1 * time.Hour
+	}
+	if o.cacheExpiry == 0 {
+		o.cacheExpiry = 24 * time.Hour
+	}
+}
+
+// permissionCache is a cache for permission check for private OCI images.
+// After a new permission is put into the cache, it will be checked periodically by a background goroutine.
+// It is used to avoid blocking the translator due to the permission check.
+type permissionCache struct {
+	sync.Mutex
+	permissionCacheOptions
+
+	cache  map[string]*permissionCacheEntry
+	logger logging.Logger
+}
+
+// permissionCacheEntry is an entry in the permission cache.
+type permissionCacheEntry struct {
+	// The oci image URL.
+	image *url.URL
+	// fetcherOption contains the pull secret for the image.
+	fetcherOption *ImageFetcherOption
+	// The last time the pull secret is checked against the image.
+	lastCheck time.Time
+	// The error returned by the OCI registry when checking the permission.
+	// If error is not nil, the permission is not allowed.
+	// If it's a permission error, it's represented by a transport.Error with 401 or 403 HTTP status code.
+	// But it's not necessarily a permission error, it could be other errors like network error, non-exist image, etc.
+	// In this case, the permission is also not allowed.
+	checkError error
+	// The last time the cache entry is accessed.
+	lastAccess time.Time
+}
+
+func (e *permissionCacheEntry) key() string {
+	return permissionCacheKey(e.image, e.fetcherOption.PullSecret)
+}
+
+// isPermissionExpired returns true if the permission check is older
+// than the specified expiry duration. If this is true, the entry
+// should be rechecked.
+func (e *permissionCacheEntry) isPermissionExpired(expiry time.Duration) bool {
+	return time.Now().After(e.lastCheck.Add(expiry))
+}
+
+// isCacheExpired returns true if the cache entry has not been accessed
+// for the specified expiry duration. If this is true, the entry
+// should be removed.
+func (e *permissionCacheEntry) isCacheExpired(expiry time.Duration) bool {
+	return time.Now().After(e.lastAccess.Add(expiry))
+}
+
+// permissionCacheKey generates a key for a permission cache entry.
+// The key is the hex encoded of concatenation of the image URL and the pull secret.
+func permissionCacheKey(image *url.URL, pullSecret []byte) string {
+	b := make([]byte, len(image.String())+len(pullSecret))
+	copy(b, image.String())
+	copy(b[len(image.String()):], pullSecret)
+	return hex.EncodeToString(b)
+}
+
+// newPermissionCache creates a new permission cache with a given TTL.
+func newPermissionCache(options permissionCacheOptions, logger logging.Logger) *permissionCache {
+	options.sanitize()
+	return &permissionCache{
+		cache:                  make(map[string]*permissionCacheEntry),
+		permissionCacheOptions: options,
+		logger:                 logger,
+	}
+}
+
+// checkAndUpdatePermission checks the permission of the image against the pull secret and updates the cache entry.
+func (p *permissionCache) checkAndUpdatePermission(ctx context.Context, e *permissionCacheEntry) error {
+	fetcher := NewImageFetcher(ctx, *e.fetcherOption, p.logger)
+	_, _, err := fetcher.PrepareFetch(e.image.Host + e.image.Path)
+	e.checkError = err
+	e.lastCheck = time.Now()
+	return err
+}
+
+// start starts a background goroutine to periodically check the permission for the cached permission entries.
+func (p *permissionCache) Start(ctx context.Context) {
+	go func() {
+		ticker := time.NewTicker(p.checkInterval)
+		defer ticker.Stop()
+		for {
+			select {
+			case <-ticker.C:
+				func() {
+					p.Lock()
+					defer p.Unlock()
+					for _, e := range p.cache {
+						if e.isCacheExpired(p.cacheExpiry) {
+							p.logger.Info("removing permission cache entry", "image", e.image.String())
+							delete(p.cache, e.key())
+							continue
+						}
+						if e.isPermissionExpired(p.permissionExpiry) {
+							const retryAttempts = 3
+							const retryDelay = 1 * time.Second
+							p.logger.Info("rechecking permission for image", "image", e.image.String())
+							err := retry.Do(
+								func() error {
+									err := p.checkAndUpdatePermission(ctx, e)
+									if err != nil && isRetriableError(err) {
+										p.logger.Error(
+											err,
+											"failed to check permission for image, will retry again",
+											"image",
+											e.image.String())
+										return err
+									}
+									return nil
+								},
+								retry.Attempts(retryAttempts),
+								retry.DelayType(retry.BackOffDelay),
+								retry.Delay(retryDelay),
+								retry.Context(ctx),
+							)
+							if err != nil {
+								p.logger.Error(
+									err,
+									fmt.Sprintf("failed to recheck permission for image after %d attempts", retryAttempts),
+									"image",
+									e.image.String())
+							}
+						}
+					}
+				}()
+			case <-ctx.Done():
+				return
+			}
+		}
+	}()
+}
+
+// isRetriableError checks if the error is retriable.
+// If the error is a permission error, it's not retriable. For example, 401 and 403 HTTP status code.
+func isRetriableError(err error) bool {
+	var terr *transport.Error
+	if errors.As(err, &terr) {
+		if terr.StatusCode == http.StatusUnauthorized || terr.StatusCode == http.StatusForbidden {
+			return false
+		}
+	}
+	return true
+}
+
+// put puts a new permission cache entry into the cache.
+func (p *permissionCache) Put(e *permissionCacheEntry) {
+	p.Lock()
+	defer p.Unlock()
+	e.lastAccess = time.Now()
+	e.lastCheck = time.Now()
+	p.cache[e.key()] = e
+}
+
+// IsAllowed checks if the given image is allowed to be accessed with the provided pull secret.
+// If the permission is not found in the cache, this method will block until the permission is checked and cached.
+// This blocking won't be too long as it's only for the first time permission check and won't retry. Subsequent
+// permission checks will be done in a background goroutine by the permission cache.
+//
+// If any error occurs, the permission is considered not allowed.
+// The error can be a permission error or other errors like network error, non-exist image, etc.
+func (p *permissionCache) IsAllowed(ctx context.Context, image *url.URL, pullSecret []byte, insecure bool) (bool, error) {
+	p.Lock()
+	defer p.Unlock()
+	key := permissionCacheKey(image, pullSecret)
+	if e, ok := p.cache[key]; ok {
+		e.lastAccess = time.Now()
+		return e.checkError == nil, e.checkError
+	}
+
+	e := &permissionCacheEntry{
+		image: image,
+		fetcherOption: &ImageFetcherOption{
+			Insecure:   insecure,
+			PullSecret: pullSecret,
+		},
+	}
+	// Do not retry if the permission check fails because we don't want to block the translator for too long.
+	// The permission check will be retried in the background goroutine by the permission cache.
+	if err := p.checkAndUpdatePermission(ctx, e); err != nil {
+		p.logger.Error(err, "failed to check permission for image", "image", e.image.String())
+	}
+	e.lastAccess = time.Now()
+	p.cache[key] = e
+	return e.checkError == nil, e.checkError
+}
+
+// getForTest is a test helper to get a permission cache entry from the cache.
+func (p *permissionCache) getForTest(key string) (permissionCacheEntry, bool) {
+	p.Lock()
+	defer p.Unlock()
+	entry, ok := p.cache[key]
+	if !ok {
+		return permissionCacheEntry{}, false
+	}
+	return *entry, true
+}
+
+// deleteForTest is a test helper to delete a permission cache entry from the cache.
+func (p *permissionCache) deleteForTest(key string) {
+	p.Lock()
+	defer p.Unlock()
+	delete(p.cache, key)
+}
diff --git a/internal/xds/translator/authorization.go b/internal/xds/translator/authorization.go
index 4112d2aed..7d4b3af5c 100644
--- a/internal/xds/translator/authorization.go
+++ b/internal/xds/translator/authorization.go
@@ -23,6 +23,7 @@ import (
 	envoymatcherv3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3"
 	"google.golang.org/protobuf/types/known/anypb"
 	"google.golang.org/protobuf/types/known/wrapperspb"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/ir"
@@ -179,9 +180,20 @@ func buildRBACPerRoute(authorization *ir.Authorization) (*rbacv3.RBACPerRoute, e
 	// If no matcher matches, the default action will be used.
 	for _, rule := range authorization.Rules {
 		var (
-			ipPredicate  *matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_
+			// Predicates for HTTP methods.
+			methodPredicate *matcherv3.Matcher_MatcherList_Predicate
+
+			// Predicates for HTTP headers.
+			headerPredicate []*matcherv3.Matcher_MatcherList_Predicate
+
+			// Predicates for IP ranges.
+			ipPredicate *matcherv3.Matcher_MatcherList_Predicate
+
+			// Predicates for JWT claims and scopes.
 			jwtPredicate []*matcherv3.Matcher_MatcherList_Predicate
-			predicate    *matcherv3.Matcher_MatcherList_Predicate
+
+			// The final predicate that will be used for the current rule.
+			finalPredicate *matcherv3.Matcher_MatcherList_Predicate
 		)
 
 		// Determine the action for the current rule.
@@ -202,47 +214,64 @@ func buildRBACPerRoute(authorization *ir.Authorization) (*rbacv3.RBACPerRoute, e
 			}
 		}
 
-		// Build the predicate for the current rule.
+		var methodPredicates []*matcherv3.Matcher_MatcherList_Predicate
+		if rule.Operation != nil && len(rule.Operation.Methods) > 0 {
+			if methodPredicates, err = buildMethodsPredicate(rule.Operation.Methods); err != nil {
+				return nil, err
+			}
+		}
+
+		// If there are multiple methods, OR them together.
+		// Methods are matched if any of them match.
 		switch {
-		// If both IP and JWT predicates are present, AND them together.
-		case ipPredicate != nil && jwtPredicate != nil:
-			predicates := []*matcherv3.Matcher_MatcherList_Predicate{
-				{
-					MatchType: ipPredicate,
+		case len(methodPredicates) > 1:
+			methodPredicate = &matcherv3.Matcher_MatcherList_Predicate{
+				MatchType: &matcherv3.Matcher_MatcherList_Predicate_OrMatcher{
+					OrMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+						Predicate: methodPredicates,
+					},
 				},
 			}
-			predicates = append(predicates, jwtPredicate...)
+		case len(methodPredicates) == 1:
+			methodPredicate = &matcherv3.Matcher_MatcherList_Predicate{
+				MatchType: methodPredicates[0].MatchType.(*matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_),
+			}
+		}
+
+		if len(rule.Principal.Headers) > 0 {
+			if headerPredicate, err = buildHeadersPredicate(rule.Principal.Headers); err != nil {
+				return nil, err
+			}
+		}
 
-			predicate = &matcherv3.Matcher_MatcherList_Predicate{
+		// AND all the predicates together.
+		var allPredicates []*matcherv3.Matcher_MatcherList_Predicate
+		if methodPredicate != nil {
+			allPredicates = append(allPredicates, methodPredicate)
+		}
+		if ipPredicate != nil {
+			allPredicates = append(allPredicates, ipPredicate)
+		}
+		allPredicates = append(allPredicates, jwtPredicate...)
+		allPredicates = append(allPredicates, headerPredicate...)
+
+		switch {
+		case len(allPredicates) > 1:
+			finalPredicate = &matcherv3.Matcher_MatcherList_Predicate{
 				MatchType: &matcherv3.Matcher_MatcherList_Predicate_AndMatcher{
 					AndMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
-						Predicate: predicates,
+						Predicate: allPredicates,
 					},
 				},
 			}
-		case ipPredicate != nil:
-			predicate = &matcherv3.Matcher_MatcherList_Predicate{
-				MatchType: ipPredicate,
-			}
-		case jwtPredicate != nil:
-			// If there are multiple JWT predicates, AND them together.
-			if len(jwtPredicate) > 1 {
-				predicate = &matcherv3.Matcher_MatcherList_Predicate{
-					MatchType: &matcherv3.Matcher_MatcherList_Predicate_AndMatcher{
-						AndMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
-							Predicate: jwtPredicate,
-						},
-					},
-				}
-			} else if len(jwtPredicate) == 1 {
-				predicate = jwtPredicate[0]
-			}
+		case len(allPredicates) == 1:
+			finalPredicate = allPredicates[0]
 		}
 
 		// Add the matcher generated with the current rule to the matcher list.
 		// The first matcher that matches will be used to determine the action.
 		matcherList = append(matcherList, &matcherv3.Matcher_MatcherList_FieldMatcher{
-			Predicate: predicate,
+			Predicate: finalPredicate,
 			OnMatch: &matcherv3.Matcher_OnMatch{
 				OnMatch: &matcherv3.Matcher_OnMatch_Action{
 					Action: &cncfv3.TypedExtensionConfig{
@@ -291,7 +320,7 @@ func buildRBACPerRoute(authorization *ir.Authorization) (*rbacv3.RBACPerRoute, e
 	return rbac, nil
 }
 
-func buildIPPredicate(clientCIDRs []*ir.CIDRMatch) (*matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_, error) {
+func buildIPPredicate(clientCIDRs []*ir.CIDRMatch) (*matcherv3.Matcher_MatcherList_Predicate, error) {
 	var (
 		sourceIPInput *anypb.Any
 		ipMatcher     *anypb.Any
@@ -320,16 +349,18 @@ func buildIPPredicate(clientCIDRs []*ir.CIDRMatch) (*matcherv3.Matcher_MatcherLi
 		return nil, err
 	}
 
-	return &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
-		SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
-			Input: &cncfv3.TypedExtensionConfig{
-				Name:        "client_ip",
-				TypedConfig: sourceIPInput,
-			},
-			Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
-				CustomMatch: &cncfv3.TypedExtensionConfig{
-					Name:        "ip_matcher",
-					TypedConfig: ipMatcher,
+	return &matcherv3.Matcher_MatcherList_Predicate{
+		MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+			SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+				Input: &cncfv3.TypedExtensionConfig{
+					Name:        "client_ip",
+					TypedConfig: sourceIPInput,
+				},
+				Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_CustomMatch{
+					CustomMatch: &cncfv3.TypedExtensionConfig{
+						Name:        "ip_matcher",
+						TypedConfig: ipMatcher,
+					},
 				},
 			},
 		},
@@ -539,3 +570,81 @@ func buildJWTPredicate(jwt egv1a1.JWTPrincipal) ([]*matcherv3.Matcher_MatcherLis
 func (c *rbac) patchResources(*types.ResourceVersionTable, []*ir.HTTPRoute) error {
 	return nil
 }
+
+func buildMethodsPredicate(methods []gwapiv1.HTTPMethod) ([]*matcherv3.Matcher_MatcherList_Predicate, error) {
+	methodStrings := make([]string, len(methods))
+	for i, method := range methods {
+		methodStrings[i] = string(method)
+	}
+
+	// Match the HTTP method as a pesudo-header.
+	return buildHeaderPredicate(":method", methodStrings, true)
+}
+
+func buildHeadersPredicate(headers []egv1a1.AuthorizationHeaderMatch) ([]*matcherv3.Matcher_MatcherList_Predicate, error) {
+	var (
+		headersPredicates []*matcherv3.Matcher_MatcherList_Predicate // Predicates for all headers.
+		headerPredicates  []*matcherv3.Matcher_MatcherList_Predicate // Predicates for a single header.
+		err               error
+	)
+
+	for _, header := range headers {
+		if headerPredicates, err = buildHeaderPredicate(header.Name, header.Values, false); err != nil {
+			return nil, err
+		}
+
+		// For a header to match, one of the values must match.
+		// If there are multiple values for a header, OR them together.
+		if len(headerPredicates) > 1 {
+			headersPredicates = append(headersPredicates, &matcherv3.Matcher_MatcherList_Predicate{
+				MatchType: &matcherv3.Matcher_MatcherList_Predicate_OrMatcher{
+					OrMatcher: &matcherv3.Matcher_MatcherList_Predicate_PredicateList{
+						Predicate: headerPredicates,
+					},
+				},
+			})
+		} else if len(headerPredicates) == 1 {
+			headersPredicates = append(headersPredicates, &matcherv3.Matcher_MatcherList_Predicate{
+				MatchType: headerPredicates[0].MatchType.(*matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_),
+			})
+		}
+	}
+
+	return headersPredicates, nil
+}
+
+func buildHeaderPredicate(name string, values []string, ignoreCase bool) ([]*matcherv3.Matcher_MatcherList_Predicate, error) {
+	var (
+		headerMatchInput *anypb.Any
+		err              error
+	)
+
+	if headerMatchInput, err = proto.ToAnyWithValidation(&envoymatcherv3.HttpRequestHeaderMatchInput{
+		HeaderName: name,
+	}); err != nil {
+		return nil, err
+	}
+
+	var predicates []*matcherv3.Matcher_MatcherList_Predicate
+	for _, value := range values {
+		predicates = append(predicates, &matcherv3.Matcher_MatcherList_Predicate{
+			MatchType: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_{
+				SinglePredicate: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate{
+					Input: &cncfv3.TypedExtensionConfig{
+						Name:        "http_header",
+						TypedConfig: headerMatchInput,
+					},
+					Matcher: &matcherv3.Matcher_MatcherList_Predicate_SinglePredicate_ValueMatch{
+						ValueMatch: &matcherv3.StringMatcher{
+							MatchPattern: &matcherv3.StringMatcher_Exact{
+								Exact: value,
+							},
+							IgnoreCase: ignoreCase,
+						},
+					},
+				},
+			},
+		})
+	}
+	return predicates, nil
+}
diff --git a/internal/xds/translator/extproc.go b/internal/xds/translator/extproc.go
index d416e9074..b9452b673 100644
--- a/internal/xds/translator/extproc.go
+++ b/internal/xds/translator/extproc.go
@@ -234,9 +234,10 @@ func (*extProc) patchRoute(route *routev3.Route, irRoute *ir.HTTPRoute) error {
 
 func buildExtProcBodyProcessingMode(mode *ir.ExtProcBodyProcessingMode) extprocv3.ProcessingMode_BodySendMode {
 	lookup := map[ir.ExtProcBodyProcessingMode]extprocv3.ProcessingMode_BodySendMode{
-		ir.ExtProcBodyBuffered:        extprocv3.ProcessingMode_BUFFERED,
-		ir.ExtProcBodyBufferedPartial: extprocv3.ProcessingMode_BUFFERED_PARTIAL,
-		ir.ExtProcBodyStreamed:        extprocv3.ProcessingMode_STREAMED,
+		ir.ExtProcBodyBuffered:           extprocv3.ProcessingMode_BUFFERED,
+		ir.ExtProcBodyBufferedPartial:    extprocv3.ProcessingMode_BUFFERED_PARTIAL,
+		ir.ExtProcBodyStreamed:           extprocv3.ProcessingMode_STREAMED,
+		ir.ExtProcBodyFullDuplexStreamed: extprocv3.ProcessingMode_FULL_DUPLEX_STREAMED,
 	}
 	if r, found := lookup[*mode]; found {
 		return r
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index 3579855d9..b404cfffc 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -20,19 +20,21 @@ new features: |
   Added support for HorizontalPodAutoscaler to helm chart
   Added support for distinct header and distinct source CIDR based local rate limiting
   Added support for forwarding the authenticated username to the backend via a configurable header in BasicAuth
+  Added support for HTTP Methods and Headers based authorization in SecurityPolicy
   Added support for zone aware routing
 
-
 bug fixes: |
   Fix traffic splitting when filters are attached to the backendRef.
   Added support for Secret and ConfigMap parsing in Standalone mode.
   Bypass overload manager for stats and ready listeners
   Fix translating backendSettings for extAuth
   Fix an issue that stats compressor was not working.
+  Added support for BackendTLSPolicy parsing in Standalone mode.
 
 # Enhancements that improve performance.
 performance improvements: |
-
+  Added a cache for the Wasm OCI image permission checks and check the pullSecrets against the OCI image registry in
+  a background goroutine.
 # Deprecated features or APIs.
 deprecations: |
   Deprecated the PreserveXRequestID field.
diff --git a/site/content/en/contributions/design/fuzzing.md b/site/content/en/contributions/design/fuzzing.md
new file mode 100644
index 000000000..1ca805f5e
--- /dev/null
+++ b/site/content/en/contributions/design/fuzzing.md
@@ -0,0 +1,77 @@
+---
+title: "Fuzzing "
+---
+
+## Overview
+
+This design document introduces **Fuzz Testing** in Envoy Gateway.
+Its goal is to detect unexpected crashes, memory leaks, and undefined behaviors in the translation of Gateway 
+API resources and configuration parsing, areas that may not be fully covered by unit tests. 
+
+Additionally, [OSS-Fuzz](https://github.com/google/oss-fuzz) 
+provides a continuous fuzzing infrastructure for popular open-source projects. By writing fuzz tests, 
+we can leverage OSS-Fuzz to continuously fuzz Envoy Gateway against a wide range of inputs, 
+improving its resilience and reliability.
+
+**Note:** This work is sponsored by the 
+[Linux Foundation Mentorship](https://mentorship.lfx.linuxfoundation.org/project/44020e81-1218-49aa-95e0-ee3e03998eb3) 
+program.
+
+## Goals
+
+* Identify fuzz targets considering the tradeoff between realism, efficiency, and maintenance effort.
+* Develop a set of initial fuzzers.
+* Integrate with OSS-Fuzz for continuous, automated fuzz testing.
+* Iteratively refine, update, and enhance fuzzers based on findings and evolving requirements.
+
+
+## Non Goals
+
+* Introducing new features to Envoy Gateway.
+* Achieving 100% code coverage.
+
+## Implementation
+
+As the fuzzers will be integrated with OSS-Fuzz, the implementation will follow best practices 
+outlined in [OSS-Fuzz Ideal Integration](https://google.github.io/oss-fuzz/advanced-topics/ideal-integration/) page.
+Fuzzers will be developed native Go fuzzing library [go-fuzz](https://go.dev/blog/fuzz-beta).
+
+### Example
+Here is an example of a simple fuzzer that tests the translation of Gateway API resource to Intermediate 
+representation (IR).
+
+```go
+func FuzzGatewayAPIToIRWithGatewayClass(f *testing.F) {
+	f.Add("valid-name", "valid-namespace", "gateway.envoyproxy.io/gatewayclass-controller")
+	f.Fuzz(func(t *testing.T, name, namespace, controllerName string) {
+		resources := &resource.Resources{
+			GatewayClass: &gwapiv1.GatewayClass{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      name,
+					Namespace: namespace,
+				},
+				Spec: gwapiv1.GatewayClassSpec{
+					ControllerName: gwapiv1.GatewayController(controllerName),
+				},
+			},
+		}
+
+		result, err := translateGatewayAPIToIR(resources)
+		require.NoError(t, err, "Error should be nil")
+		require.NotNil(t, result, "Result should not be nil")
+		require.NotNil(t, result.Resources, "Resources should not be nil")
+		require.NotNil(t, result.XdsIR, "XdsIR should not be nil")
+		require.NotNil(t, result.InfraIR, "InfraIR should not be nil")
+	})
+}
+```
+
+## Design Decisions
+* Fuzzing library: [go-fuzz](https://go.dev/blog/fuzz-beta).
+* Fuzzers directory: Fuzzers will be stored in the `test/fuzz` directory.
+
+## Conclusion
+
+Fuzz testing is an ongoing process. Once the initial fuzzers are developed, 
+crashes reported by OSS-Fuzz will be continuously monitored, and the fuzzers will be iteratively refined.
+Additionally, future efforts will be directed toward exploring the integration of fuzz testing into the CI pipeline using GitHub Actions.
\ No newline at end of file
diff --git a/site/content/en/docs/troubleshooting/_index.md b/site/content/en/docs/troubleshooting/_index.md
new file mode 100644
index 000000000..775b2f935
--- /dev/null
+++ b/site/content/en/docs/troubleshooting/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Troubleshooting"
+weight: 2
+description: Learn how to debug Envoy Gateway
+---
diff --git a/site/content/en/docs/troubleshooting/configuration.md b/site/content/en/docs/troubleshooting/configuration.md
new file mode 100644
index 000000000..87b774fd8
--- /dev/null
+++ b/site/content/en/docs/troubleshooting/configuration.md
@@ -0,0 +1,228 @@
++++
+title = "Configuruation Issues"
++++
+
+## Overview
+After configuring and applying resources, you might find that Envoy Gateway does not behave as expected. This guide helps troubleshoot configuration issues.
+
+Many **syntax errors and simple semantic issues** are caught during resource validation by the **Kubernetes API Server**, which rejects invalid resources. However, more complex configuration issues require additional debugging.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+To demonstrate debugging techniques, let’s apply an *intentionally incorrect* HTTPRoute configuration with a *non-existent* backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+### Checking Resource Status
+The `status` field in your resource definitions is your primary troubleshooting tool. It provides insights into whether a resource has been **Accepted** or not, along with the reason for rejection.
+
+#### Using kubectl
+This example below shows why an HTTPRoute has been **Accepted** but the **ResolvedRefs** condition is `false` because the backend does not exist. 
+**Note**: Almost all resources have a `status` field, so be sure to check them all.
+
+```shell
+kubectl get httproute/backend -o yaml
+```
+
+```console
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+status:
+  parents:
+  - conditions:
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Route is accepted
+      observedGeneration: 3
+      reason: Accepted
+      status: "True"
+      type: Accepted
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Service default/backend-does-not-exist not found
+      observedGeneration: 3
+      reason: BackendNotFound
+      status: "False"
+      type: ResolvedRefs
+    controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    parentRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: eg
+```
+
+#### Using egctl
+The egctl CLI tool can quickly fetch the status of multiple resources at once:
+
+```shell
+egctl x status all -A
+```
+
+```console
+NAME              TYPE       STATUS    REASON
+gatewayclass/eg   Accepted   True      Accepted
+
+NAMESPACE   NAME         TYPE         STATUS    REASON
+default     gateway/eg   Programmed   True      Programmed
+                         Accepted     True      Accepted
+
+NAMESPACE   NAME                TYPE           STATUS    REASON
+default     httproute/backend   ResolvedRefs   False     BackendNotFound
+                                Accepted       True      Accepted
+```
+
+Follow the instructions [here](./../install/install-egctl.md) to install `egctl`.
+
+#### Using kube-state-metrics
+For large-scale deployments, kube-state-metrics can help monitor the status of Envoy Gateway resources. For more details, refer to the [Observability Guide](./../tasks/observability/gateway-api-metrics.md).
+
+### Traffic
+If a configuration is not accepted, Envoy Gateway assigns a `direct_response` to the affected route, causing clients to receive an **HTTP 500 error**.
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+```console
+*   Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.7.1
+> Accept: */*
+> 
+* Request completely sent off
+< HTTP/1.1 500 Internal Server Error
+< date: Sat, 08 Mar 2025 02:25:32 GMT
+< content-length: 0
+< 
+* Connection #0 to host 127.0.0.1 left intact
+```
+
+If you inspect the access logs in the pod logs:
+
+```shell
+kubectl logs -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -c envoy | grep start_time | jq
+```
+
+```console
+{
+  ":authority": "www.example.com",
+  "bytes_received": 0,
+  "bytes_sent": 0,
+  "connection_termination_details": null,
+  "downstream_local_address": "10.1.21.65:10080",
+  "downstream_remote_address": "192.168.65.4:45050",
+  "duration": 0,
+  "method": "GET",
+  "protocol": "HTTP/1.1",
+  "requested_server_name": null,
+  "response_code": 500,
+  "response_code_details": "direct_response",
+  "response_flags": "-",
+  "route_name": "httproute/default/backend/rule/0/match/0/www_example_com",
+  "start_time": "2025-03-08T02:25:32.588Z",
+  "upstream_cluster": null,
+  "upstream_host": null,
+  "upstream_local_address": null,
+  "upstream_transport_failure_reason": null,
+  "user-agent": "curl/8.7.1",
+  "x-envoy-origin-path": "/get",
+  "x-envoy-upstream-service-time": null,
+  "x-forwarded-for": "192.168.65.4",
+  "x-request-id": "54c4c2f9-d209-4aa0-8870-342bc6622d1a"
+}
+```
+
+and find the following entries
+
+```console
+"response_code": "500",
+"response_code_details": "direct_response"
+```
+
+this likely indicates a configuration issue. Review the relevant [resource status](#checking-resource-status) for resolution steps.
diff --git a/site/content/en/v1.2/troubleshooting/_index.md b/site/content/en/v1.2/troubleshooting/_index.md
new file mode 100644
index 000000000..775b2f935
--- /dev/null
+++ b/site/content/en/v1.2/troubleshooting/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Troubleshooting"
+weight: 2
+description: Learn how to debug Envoy Gateway
+---
diff --git a/site/content/en/v1.2/troubleshooting/configuration.md b/site/content/en/v1.2/troubleshooting/configuration.md
new file mode 100644
index 000000000..87b774fd8
--- /dev/null
+++ b/site/content/en/v1.2/troubleshooting/configuration.md
@@ -0,0 +1,228 @@
++++
+title = "Configuruation Issues"
++++
+
+## Overview
+After configuring and applying resources, you might find that Envoy Gateway does not behave as expected. This guide helps troubleshoot configuration issues.
+
+Many **syntax errors and simple semantic issues** are caught during resource validation by the **Kubernetes API Server**, which rejects invalid resources. However, more complex configuration issues require additional debugging.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+To demonstrate debugging techniques, let’s apply an *intentionally incorrect* HTTPRoute configuration with a *non-existent* backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+### Checking Resource Status
+The `status` field in your resource definitions is your primary troubleshooting tool. It provides insights into whether a resource has been **Accepted** or not, along with the reason for rejection.
+
+#### Using kubectl
+This example below shows why an HTTPRoute has been **Accepted** but the **ResolvedRefs** condition is `false` because the backend does not exist. 
+**Note**: Almost all resources have a `status` field, so be sure to check them all.
+
+```shell
+kubectl get httproute/backend -o yaml
+```
+
+```console
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+status:
+  parents:
+  - conditions:
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Route is accepted
+      observedGeneration: 3
+      reason: Accepted
+      status: "True"
+      type: Accepted
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Service default/backend-does-not-exist not found
+      observedGeneration: 3
+      reason: BackendNotFound
+      status: "False"
+      type: ResolvedRefs
+    controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    parentRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: eg
+```
+
+#### Using egctl
+The egctl CLI tool can quickly fetch the status of multiple resources at once:
+
+```shell
+egctl x status all -A
+```
+
+```console
+NAME              TYPE       STATUS    REASON
+gatewayclass/eg   Accepted   True      Accepted
+
+NAMESPACE   NAME         TYPE         STATUS    REASON
+default     gateway/eg   Programmed   True      Programmed
+                         Accepted     True      Accepted
+
+NAMESPACE   NAME                TYPE           STATUS    REASON
+default     httproute/backend   ResolvedRefs   False     BackendNotFound
+                                Accepted       True      Accepted
+```
+
+Follow the instructions [here](./../install/install-egctl.md) to install `egctl`.
+
+#### Using kube-state-metrics
+For large-scale deployments, kube-state-metrics can help monitor the status of Envoy Gateway resources. For more details, refer to the [Observability Guide](./../tasks/observability/gateway-api-metrics.md).
+
+### Traffic
+If a configuration is not accepted, Envoy Gateway assigns a `direct_response` to the affected route, causing clients to receive an **HTTP 500 error**.
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+```console
+*   Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.7.1
+> Accept: */*
+> 
+* Request completely sent off
+< HTTP/1.1 500 Internal Server Error
+< date: Sat, 08 Mar 2025 02:25:32 GMT
+< content-length: 0
+< 
+* Connection #0 to host 127.0.0.1 left intact
+```
+
+If you inspect the access logs in the pod logs:
+
+```shell
+kubectl logs -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -c envoy | grep start_time | jq
+```
+
+```console
+{
+  ":authority": "www.example.com",
+  "bytes_received": 0,
+  "bytes_sent": 0,
+  "connection_termination_details": null,
+  "downstream_local_address": "10.1.21.65:10080",
+  "downstream_remote_address": "192.168.65.4:45050",
+  "duration": 0,
+  "method": "GET",
+  "protocol": "HTTP/1.1",
+  "requested_server_name": null,
+  "response_code": 500,
+  "response_code_details": "direct_response",
+  "response_flags": "-",
+  "route_name": "httproute/default/backend/rule/0/match/0/www_example_com",
+  "start_time": "2025-03-08T02:25:32.588Z",
+  "upstream_cluster": null,
+  "upstream_host": null,
+  "upstream_local_address": null,
+  "upstream_transport_failure_reason": null,
+  "user-agent": "curl/8.7.1",
+  "x-envoy-origin-path": "/get",
+  "x-envoy-upstream-service-time": null,
+  "x-forwarded-for": "192.168.65.4",
+  "x-request-id": "54c4c2f9-d209-4aa0-8870-342bc6622d1a"
+}
+```
+
+and find the following entries
+
+```console
+"response_code": "500",
+"response_code_details": "direct_response"
+```
+
+this likely indicates a configuration issue. Review the relevant [resource status](#checking-resource-status) for resolution steps.
diff --git a/site/content/en/v1.3/troubleshooting/_index.md b/site/content/en/v1.3/troubleshooting/_index.md
new file mode 100644
index 000000000..775b2f935
--- /dev/null
+++ b/site/content/en/v1.3/troubleshooting/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Troubleshooting"
+weight: 2
+description: Learn how to debug Envoy Gateway
+---
diff --git a/site/content/en/v1.3/troubleshooting/configuration.md b/site/content/en/v1.3/troubleshooting/configuration.md
new file mode 100644
index 000000000..87b774fd8
--- /dev/null
+++ b/site/content/en/v1.3/troubleshooting/configuration.md
@@ -0,0 +1,228 @@
++++
+title = "Configuruation Issues"
++++
+
+## Overview
+After configuring and applying resources, you might find that Envoy Gateway does not behave as expected. This guide helps troubleshoot configuration issues.
+
+Many **syntax errors and simple semantic issues** are caught during resource validation by the **Kubernetes API Server**, which rejects invalid resources. However, more complex configuration issues require additional debugging.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+To demonstrate debugging techniques, let’s apply an *intentionally incorrect* HTTPRoute configuration with a *non-existent* backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+### Checking Resource Status
+The `status` field in your resource definitions is your primary troubleshooting tool. It provides insights into whether a resource has been **Accepted** or not, along with the reason for rejection.
+
+#### Using kubectl
+This example below shows why an HTTPRoute has been **Accepted** but the **ResolvedRefs** condition is `false` because the backend does not exist. 
+**Note**: Almost all resources have a `status` field, so be sure to check them all.
+
+```shell
+kubectl get httproute/backend -o yaml
+```
+
+```console
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+status:
+  parents:
+  - conditions:
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Route is accepted
+      observedGeneration: 3
+      reason: Accepted
+      status: "True"
+      type: Accepted
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Service default/backend-does-not-exist not found
+      observedGeneration: 3
+      reason: BackendNotFound
+      status: "False"
+      type: ResolvedRefs
+    controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    parentRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: eg
+```
+
+#### Using egctl
+The egctl CLI tool can quickly fetch the status of multiple resources at once:
+
+```shell
+egctl x status all -A
+```
+
+```console
+NAME              TYPE       STATUS    REASON
+gatewayclass/eg   Accepted   True      Accepted
+
+NAMESPACE   NAME         TYPE         STATUS    REASON
+default     gateway/eg   Programmed   True      Programmed
+                         Accepted     True      Accepted
+
+NAMESPACE   NAME                TYPE           STATUS    REASON
+default     httproute/backend   ResolvedRefs   False     BackendNotFound
+                                Accepted       True      Accepted
+```
+
+Follow the instructions [here](./../install/install-egctl.md) to install `egctl`.
+
+#### Using kube-state-metrics
+For large-scale deployments, kube-state-metrics can help monitor the status of Envoy Gateway resources. For more details, refer to the [Observability Guide](./../tasks/observability/gateway-api-metrics.md).
+
+### Traffic
+If a configuration is not accepted, Envoy Gateway assigns a `direct_response` to the affected route, causing clients to receive an **HTTP 500 error**.
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+```console
+*   Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.7.1
+> Accept: */*
+> 
+* Request completely sent off
+< HTTP/1.1 500 Internal Server Error
+< date: Sat, 08 Mar 2025 02:25:32 GMT
+< content-length: 0
+< 
+* Connection #0 to host 127.0.0.1 left intact
+```
+
+If you inspect the access logs in the pod logs:
+
+```shell
+kubectl logs -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -c envoy | grep start_time | jq
+```
+
+```console
+{
+  ":authority": "www.example.com",
+  "bytes_received": 0,
+  "bytes_sent": 0,
+  "connection_termination_details": null,
+  "downstream_local_address": "10.1.21.65:10080",
+  "downstream_remote_address": "192.168.65.4:45050",
+  "duration": 0,
+  "method": "GET",
+  "protocol": "HTTP/1.1",
+  "requested_server_name": null,
+  "response_code": 500,
+  "response_code_details": "direct_response",
+  "response_flags": "-",
+  "route_name": "httproute/default/backend/rule/0/match/0/www_example_com",
+  "start_time": "2025-03-08T02:25:32.588Z",
+  "upstream_cluster": null,
+  "upstream_host": null,
+  "upstream_local_address": null,
+  "upstream_transport_failure_reason": null,
+  "user-agent": "curl/8.7.1",
+  "x-envoy-origin-path": "/get",
+  "x-envoy-upstream-service-time": null,
+  "x-forwarded-for": "192.168.65.4",
+  "x-request-id": "54c4c2f9-d209-4aa0-8870-342bc6622d1a"
+}
+```
+
+and find the following entries
+
+```console
+"response_code": "500",
+"response_code_details": "direct_response"
+```
+
+this likely indicates a configuration issue. Review the relevant [resource status](#checking-resource-status) for resolution steps.



Test patch:
diff --git a/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml b/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml
index d2aa0f78f..0f1f3ab69 100644
--- a/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml
+++ b/internal/cmd/egctl/testdata/translate/in/backend-endpoint.yaml
@@ -44,3 +44,16 @@ spec:
     - ip:
         address: 0.0.0.0
         port: 3000
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: example-com-tls-policy
+spec:
+  targetRefs:
+    - group: 'gateway.envoyproxy.io'
+      kind: Backend
+      name: backend
+  validation:
+    wellKnownCACertificates: "System"
+    hostname: www.example.com
diff --git a/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml b/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml
index 0841f8487..41a84b3d8 100644
--- a/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml
+++ b/internal/cmd/egctl/testdata/translate/out/backend-endpoint.all.yaml
@@ -1,3 +1,30 @@
+backendTLSPolicies:
+- kind: BackendTLSPolicy
+  metadata:
+    creationTimestamp: null
+    name: example-com-tls-policy
+    namespace: envoy-gateway-system
+  spec:
+    targetRefs:
+    - group: gateway.envoyproxy.io
+      kind: Backend
+      name: backend
+    validation:
+      hostname: www.example.com
+      wellKnownCACertificates: System
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: eg
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
 backends:
 - kind: Backend
   metadata:
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.in.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.in.yaml
new file mode 100644
index 000000000..faa891739
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.in.yaml
@@ -0,0 +1,61 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-1
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+      allowedRoutes:
+        namespaces:
+          from: All
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    namespace: default
+    name: httproute-1
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - namespace: envoy-gateway
+      name: gateway-1
+      sectionName: http
+    rules:
+    - matches:
+      - path:
+          value: "/foo"
+      backendRefs:
+      - name: service-1
+        port: 8080
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: policy-for-gateway  # This policy should attach httproute-2
+  spec:
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+    authorization:
+      defaultAction: Deny
+      rules:
+      - name: "allow-specific-headers"
+        action: Allow
+        operation:
+          methods:
+          - GET
+          - POST
+        principal:
+          headers:
+          - name: x-user-id
+            values:
+            - john
+            - alice
diff --git a/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.out.yaml b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.out.yaml
new file mode 100644
index 000000000..ccc99507f
--- /dev/null
+++ b/internal/gatewayapi/testdata/securitypolicy-with-authoriztion-headers-and-methods.out.yaml
@@ -0,0 +1,200 @@
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-1
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: All
+      name: http
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+httpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: HTTPRoute
+  metadata:
+    creationTimestamp: null
+    name: httproute-1
+    namespace: default
+  spec:
+    hostnames:
+    - www.example.com
+    parentRefs:
+    - name: gateway-1
+      namespace: envoy-gateway
+      sectionName: http
+    rules:
+    - backendRefs:
+      - name: service-1
+        port: 8080
+      matches:
+      - path:
+          value: /foo
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Resolved all the Object references for the Route
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+infraIR:
+  envoy-gateway/gateway-1:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-1/http
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-1
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+      name: envoy-gateway/gateway-1
+securityPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: SecurityPolicy
+  metadata:
+    creationTimestamp: null
+    name: policy-for-gateway
+    namespace: envoy-gateway
+  spec:
+    authorization:
+      defaultAction: Deny
+      rules:
+      - action: Allow
+        name: allow-specific-headers
+        operation:
+          methods:
+          - GET
+          - POST
+        principal:
+          headers:
+          - name: x-user-id
+            values:
+            - john
+            - alice
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-1
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+xdsIR:
+  envoy-gateway/gateway-1:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-1
+        namespace: envoy-gateway
+        sectionName: http
+      name: envoy-gateway/gateway-1/http
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      routes:
+      - destination:
+          name: httproute/default/httproute-1/rule/0
+          settings:
+          - addressType: IP
+            endpoints:
+            - host: 7.7.7.7
+              port: 8080
+            name: httproute/default/httproute-1/rule/0/backend/0
+            protocol: HTTP
+            weight: 1
+        hostname: www.example.com
+        isHTTP2: false
+        metadata:
+          kind: HTTPRoute
+          name: httproute-1
+          namespace: default
+        name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+        pathMatch:
+          distinct: false
+          name: ""
+          prefix: /foo
+        security:
+          authorization:
+            defaultAction: Deny
+            rules:
+            - action: Allow
+              name: allow-specific-headers
+              operation:
+                methods:
+                - GET
+                - POST
+              principal:
+                headers:
+                - name: x-user-id
+                  values:
+                  - john
+                  - alice
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
diff --git a/internal/wasm/premissioncache_test.go b/internal/wasm/premissioncache_test.go
new file mode 100644
index 000000000..2fdb95ff1
--- /dev/null
+++ b/internal/wasm/premissioncache_test.go
@@ -0,0 +1,282 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+// 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.
+
+package wasm
+
+import (
+	"context"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/google/go-containerregistry/pkg/registry"
+	"github.com/stretchr/testify/require"
+
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+	"github.com/envoyproxy/gateway/internal/logging"
+)
+
+func TestPermissionCache(t *testing.T) {
+	lock := sync.Mutex{}
+	// Flag to control whether the permission check should fail.
+	failPermissionCheck := false
+
+	// Set up a fake registry for OCI images.
+	reg := registry.New()
+	tos := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		lock.Lock()
+		defer lock.Unlock()
+		if failPermissionCheck {
+			http.Error(w, "permission denied", http.StatusUnauthorized)
+			return
+		}
+		reg.ServeHTTP(w, r)
+	}))
+	defer tos.Close()
+	ou, err := url.Parse(tos.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, _ = setupOCIRegistry(t, ou.Host)
+	ociURLWithTag := fmt.Sprintf("oci://%s/test/valid/docker:v0.1.0", ou.Host)
+	ociURLWithLatestTag := fmt.Sprintf("oci://%s/test/valid/docker:latest", ou.Host)
+	image, _ := url.Parse(ociURLWithTag)
+	latestImage, _ := url.Parse(ociURLWithLatestTag)
+	secret := []byte("")
+
+	t.Run("Cached permission should be updated", func(t *testing.T) {
+		lock.Lock()
+		failPermissionCheck = false
+		lock.Unlock()
+
+		ctx := context.Background()
+		defer ctx.Done()
+		cache, entry := setupTestPermissionCache(
+			permissionCacheOptions{
+				checkInterval:    10 * time.Nanosecond,
+				permissionExpiry: 10 * time.Nanosecond,
+			},
+			image,
+			latestImage,
+			secret)
+		cache.Start(ctx)
+
+		lastAccessTime := entry.lastAccess
+		lastCheckTime := entry.lastCheck
+
+		time.Sleep(1 * time.Millisecond)
+		allowed, err := cache.IsAllowed(context.Background(), image, secret, true)
+		require.True(
+			t,
+			allowed,
+			"permission should be rechecked and allowed after permission expired")
+		require.NoError(
+			t,
+			err,
+			"permission should be rechecked and allowed after permission expired")
+
+		entry, ok := cache.getForTest(entry.key())
+		require.True(t, ok, "cache entry should exist")
+		require.True(t, entry.lastAccess.After(lastAccessTime), "last access time should be updated")
+		require.True(t, entry.lastCheck.After(lastCheckTime), "last check time should be updated")
+	})
+
+	t.Run("Cached permission failed after recheck", func(t *testing.T) {
+		lock.Lock()
+		failPermissionCheck = true
+		lock.Unlock()
+
+		ctx := context.Background()
+		defer ctx.Done()
+		cache, entry := setupTestPermissionCache(
+			permissionCacheOptions{
+				checkInterval:    10 * time.Nanosecond,
+				permissionExpiry: 10 * time.Nanosecond,
+			},
+			image,
+			latestImage,
+			secret)
+		cache.Start(ctx)
+
+		lastAccessTime := entry.lastAccess
+		lastCheckTime := entry.lastCheck
+
+		time.Sleep(1 * time.Millisecond)
+		allowed, err := cache.IsAllowed(context.Background(), image, secret, true)
+		require.False(t, isRetriableError(err), "permission check error should not be retriable")
+		require.False(
+			t,
+			allowed,
+			"permission should be rechecked and denied after permission expired and secret is invalid")
+		require.Error(
+			t,
+			err,
+			"permission should be rechecked and denied after permission expired and secret is invalid")
+
+		entry, ok := cache.getForTest(entry.key())
+		require.True(t, ok, "cache entry should exist")
+		require.True(t, entry.lastAccess.After(lastAccessTime), "last access time should be updated")
+		require.True(t, entry.lastCheck.After(lastCheckTime), "last check time should be updated")
+	})
+
+	t.Run("Cached permission should be removed after expiry", func(t *testing.T) {
+		lock.Lock()
+		failPermissionCheck = false
+		lock.Unlock()
+
+		ctx := context.Background()
+		defer ctx.Done()
+		cache, entry := setupTestPermissionCache(
+			permissionCacheOptions{
+				checkInterval: 10 * time.Nanosecond,
+				cacheExpiry:   10 * time.Nanosecond,
+			},
+			image,
+			latestImage,
+			secret)
+		cache.Start(ctx)
+
+		lastAccessTime := entry.lastAccess
+		lastCheckTime := entry.lastCheck
+
+		time.Sleep(1 * time.Millisecond)
+		key := entry.key()
+		entry, ok := cache.getForTest(key)
+		require.False(t, ok, "cache entry should be removed after expiry")
+		allowed, err := cache.IsAllowed(context.Background(), image, secret, true)
+		require.True(t,
+			allowed,
+			"permission should be rechecked and allowed after cache removed")
+		require.NoError(t,
+			err,
+			"permission should be rechecked and allowed after cache removed")
+		entry, ok = cache.getForTest(key)
+		require.True(t, ok, "expired entry should be added after recheck")
+		require.True(t, entry.lastAccess.After(lastAccessTime), "last access time should be updated")
+		require.True(t, entry.lastCheck.After(lastCheckTime), "last check time should be updated")
+	})
+
+	t.Run("Non-exist permission should be checked and cached after first access for allowed permission", func(t *testing.T) {
+		lock.Lock()
+		failPermissionCheck = false
+		lock.Unlock()
+
+		ctx := context.Background()
+		defer ctx.Done()
+		cache, entry := setupTestPermissionCache(
+			permissionCacheOptions{
+				checkInterval: 10 * time.Nanosecond,
+			},
+			image,
+			latestImage,
+			secret)
+		key := entry.key()
+		// remove the cache entry
+		cache.deleteForTest(key)
+		cache.Start(ctx)
+
+		_, ok := cache.getForTest(key)
+		require.False(t, ok, "cache entry should not exist before access")
+
+		now := time.Now()
+		allowed, err := cache.IsAllowed(context.Background(), image, secret, true)
+		require.True(t,
+			allowed,
+			"non-exist permission should be checked and allowed at first access")
+		require.NoError(t,
+			err,
+			"non-exist permission should be checked and allowed at first access")
+
+		entry, ok = cache.getForTest(key)
+		require.True(t, ok, "non-exist permission should be added to the cache after first access ")
+		require.True(t, entry.lastAccess.After(now), "last access time should be updated after first access")
+		require.True(t, entry.lastCheck.After(now), "last check time should be updated after first access")
+	})
+
+	t.Run("Non-exist permission should be checked and cached after first access for denied permission", func(t *testing.T) {
+		lock.Lock()
+		failPermissionCheck = true
+		lock.Unlock()
+
+		ctx := context.Background()
+		defer ctx.Done()
+		cache, entry := setupTestPermissionCache(
+			permissionCacheOptions{
+				checkInterval: 10 * time.Nanosecond,
+			},
+			image,
+			latestImage,
+			secret)
+		key := entry.key()
+		// remove the cache entry
+		cache.deleteForTest(key)
+		cache.Start(ctx)
+
+		_, ok := cache.getForTest(key)
+		require.False(t, ok, "cache entry should not exist before access")
+
+		now := time.Now()
+		allowed, err := cache.IsAllowed(context.Background(), image, secret, true)
+		require.False(t,
+			allowed,
+			"non-exist permission should be checked and denied at first access if secret is invalid")
+		require.Error(t,
+			err,
+			"non-exist permission should be checked and denied at first access if secret is invalid")
+
+		entry, ok = cache.getForTest(key)
+		require.True(t, ok, "non-exist permission should be added to the cache after first access ")
+		require.True(t, entry.lastAccess.After(now), "last access time should be updated after first access")
+		require.True(t, entry.lastCheck.After(now), "last check time should be updated after first access")
+	})
+}
+
+// setupTestPermissionCache sets up a permission cache for testing.
+func setupTestPermissionCache(options permissionCacheOptions, image, latestImage *url.URL, secret []byte) (*permissionCache, permissionCacheEntry) {
+	// Setup the permission cache.
+	cache := newPermissionCache(
+		options,
+		logging.DefaultLogger(egv1a1.LogLevelInfo))
+
+	entry := &permissionCacheEntry{
+		image: image,
+		fetcherOption: &ImageFetcherOption{
+			PullSecret: secret,
+			Insecure:   true,
+		},
+		lastCheck: time.Now(),
+	}
+	cache.Put(entry)
+
+	// Add one more entry for the latest image to test the cache can handle multiple entries correctly.
+	cache.Put(&permissionCacheEntry{
+		image: latestImage,
+		fetcherOption: &ImageFetcherOption{
+			PullSecret: secret,
+			Insecure:   true,
+		},
+		lastCheck: time.Now(),
+	})
+
+	return cache, *entry
+}
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization-http-header.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-http-header.yaml
new file mode 100644
index 000000000..ff997db5a
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization-http-header.yaml
@@ -0,0 +1,51 @@
+http:
+- address: 0.0.0.0
+  hostnames:
+  - '*'
+  isHTTP2: false
+  name: envoy-gateway/gateway-1/http
+  path:
+    escapedSlashesAction: UnescapeAndRedirect
+    mergeSlashes: true
+  port: 10080
+  routes:
+  - destination:
+      name: httproute/default/httproute-1/rule/0
+      settings:
+      - addressType: IP
+        endpoints:
+        - host: 7.7.7.7
+          port: 8080
+        protocol: HTTP
+        weight: 1
+        name: httproute/default/httproute-1/rule/0/backend/0
+    hostname: www.example.com
+    isHTTP2: false
+    name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+    pathMatch:
+      distinct: false
+      name: ""
+      prefix: /foo
+    security:
+      authorization:
+        defaultAction: Deny
+        rules:
+        - action: Allow
+          name: allow-specific-headers
+          principal:
+            headers:
+            - name: x-user-id
+              values:
+              - john
+              - alice
+        - action: Allow
+          name: allow-multiple-headers
+          principal:
+            headers:
+            - name: x-location-id
+              values:
+              - chengdu
+            - name: x-org-id
+              values:
+              - 123
+              - 456
diff --git a/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml b/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml
index 61835bccf..8a8edbc2b 100644
--- a/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/authorization-multiple-principals.yaml
@@ -32,6 +32,15 @@ http:
         rules:
         - action: Allow
           name: allow-rule-1
+          operation:
+            methods:
+            - GET
+        - action: Allow
+          name: allow-rule-2
+          operation:
+            methods:
+            - DELETE
+            - POST
           principal:
             clientCIDRs:
             - cidr: 192.168.1.0/24
@@ -55,7 +64,7 @@ http:
               - name: department
                 values: ["engineering"]
         - action: Allow
-          name: allow-rule-2
+          name: allow-rule-3
           principal:
             clientCIDRs:
             - cidr: 10.0.1.0/24
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.clusters.yaml
new file mode 100644
index 000000000..c24d059ee
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.clusters.yaml
@@ -0,0 +1,17 @@
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig:
+    localityWeightedLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_PREFERRED
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: httproute/default/httproute-1/rule/0
+  ignoreHealthOnHostRemoval: true
+  lbPolicy: LEAST_REQUEST
+  name: httproute/default/httproute-1/rule/0
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.endpoints.yaml
new file mode 100644
index 000000000..29bb6b4e4
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.endpoints.yaml
@@ -0,0 +1,12 @@
+- clusterName: httproute/default/httproute-1/rule/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 7.7.7.7
+            portValue: 8080
+      loadBalancingWeight: 1
+    loadBalancingWeight: 1
+    locality:
+      region: httproute/default/httproute-1/rule/0/backend/0
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.listeners.yaml
new file mode 100644
index 000000000..907d28f78
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.listeners.yaml
@@ -0,0 +1,37 @@
+- address:
+    socketAddress:
+      address: 0.0.0.0
+      portValue: 10080
+  defaultFilterChain:
+    filters:
+    - name: envoy.filters.network.http_connection_manager
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+        commonHttpProtocolOptions:
+          headersWithUnderscoresAction: REJECT_REQUEST
+        http2ProtocolOptions:
+          initialConnectionWindowSize: 1048576
+          initialStreamWindowSize: 65536
+          maxConcurrentStreams: 100
+        httpFilters:
+        - name: envoy.filters.http.rbac
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
+        - name: envoy.filters.http.router
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+            suppressEnvoyHeaders: true
+        mergeSlashes: true
+        normalizePath: true
+        pathWithEscapedSlashesAction: UNESCAPE_AND_REDIRECT
+        rds:
+          configSource:
+            ads: {}
+            resourceApiVersion: V3
+          routeConfigName: envoy-gateway/gateway-1/http
+        serverHeaderTransformation: PASS_THROUGH
+        statPrefix: http-10080
+        useRemoteAddress: true
+    name: envoy-gateway/gateway-1/http
+  name: envoy-gateway/gateway-1/http
+  perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.routes.yaml
new file mode 100644
index 000000000..7f2a8ca27
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-http-header.routes.yaml
@@ -0,0 +1,88 @@
+- ignorePortInHostMatching: true
+  name: envoy-gateway/gateway-1/http
+  virtualHosts:
+  - domains:
+    - www.example.com
+    name: envoy-gateway/gateway-1/http/www_example_com
+    routes:
+    - match:
+        pathSeparatedPrefix: /foo
+      name: httproute/default/httproute-1/rule/0/match/0/www_example_com
+      route:
+        cluster: httproute/default/httproute-1/rule/0
+        upgradeConfigs:
+        - upgradeType: websocket
+      typedPerFilterConfig:
+        envoy.filters.http.rbac:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
+          rbac:
+            matcher:
+              matcherList:
+                matchers:
+                - onMatch:
+                    action:
+                      name: allow-specific-headers
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        name: ALLOW
+                  predicate:
+                    orMatcher:
+                      predicate:
+                      - singlePredicate:
+                          input:
+                            name: http_header
+                            typedConfig:
+                              '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                              headerName: x-user-id
+                          valueMatch:
+                            exact: john
+                      - singlePredicate:
+                          input:
+                            name: http_header
+                            typedConfig:
+                              '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                              headerName: x-user-id
+                          valueMatch:
+                            exact: alice
+                - onMatch:
+                    action:
+                      name: allow-multiple-headers
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        name: ALLOW
+                  predicate:
+                    andMatcher:
+                      predicate:
+                      - singlePredicate:
+                          input:
+                            name: http_header
+                            typedConfig:
+                              '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                              headerName: x-location-id
+                          valueMatch:
+                            exact: chengdu
+                      - orMatcher:
+                          predicate:
+                          - singlePredicate:
+                              input:
+                                name: http_header
+                                typedConfig:
+                                  '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                                  headerName: x-org-id
+                              valueMatch:
+                                exact: "123"
+                          - singlePredicate:
+                              input:
+                                name: http_header
+                                typedConfig:
+                                  '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                                  headerName: x-org-id
+                              valueMatch:
+                                exact: "456"
+              onNoMatch:
+                action:
+                  name: default
+                  typedConfig:
+                    '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                    action: DENY
+                    name: DENY
diff --git a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml
index 2b9a49063..2d1b96cfc 100644
--- a/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/authorization-multiple-principals.routes.yaml
@@ -25,9 +25,45 @@
                       typedConfig:
                         '@type': type.googleapis.com/envoy.config.rbac.v3.Action
                         name: ALLOW
+                  predicate:
+                    singlePredicate:
+                      input:
+                        name: http_header
+                        typedConfig:
+                          '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                          headerName: :method
+                      valueMatch:
+                        exact: GET
+                        ignoreCase: true
+                - onMatch:
+                    action:
+                      name: allow-rule-2
+                      typedConfig:
+                        '@type': type.googleapis.com/envoy.config.rbac.v3.Action
+                        name: ALLOW
                   predicate:
                     andMatcher:
                       predicate:
+                      - orMatcher:
+                          predicate:
+                          - singlePredicate:
+                              input:
+                                name: http_header
+                                typedConfig:
+                                  '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                                  headerName: :method
+                              valueMatch:
+                                exact: DELETE
+                                ignoreCase: true
+                          - singlePredicate:
+                              input:
+                                name: http_header
+                                typedConfig:
+                                  '@type': type.googleapis.com/envoy.type.matcher.v3.HttpRequestHeaderMatchInput
+                                  headerName: :method
+                              valueMatch:
+                                exact: POST
+                                ignoreCase: true
                       - singlePredicate:
                           customMatch:
                             name: ip_matcher
@@ -117,7 +153,7 @@
                               - key: department
                 - onMatch:
                     action:
-                      name: allow-rule-2
+                      name: allow-rule-3
                       typedConfig:
                         '@type': type.googleapis.com/envoy.config.rbac.v3.Action
                         name: ALLOW
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index 1134cf454..e9f9b2e0b 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -1608,6 +1608,7 @@ _Appears in:_
 | ----- | ----------- |
 | `Streamed` | StreamedExtProcBodyProcessingMode will stream the body to the server in pieces as they arrive at the proxy.<br /> | 
 | `Buffered` | BufferedExtProcBodyProcessingMode will buffer the message body in memory and send the entire body at once. If the body exceeds the configured buffer limit, then the downstream system will receive an error.<br /> | 
+| `FullDuplexStreamed` | FullDuplexStreamedExtBodyProcessingMode will send the body in pieces, to be read in a stream. Full details here: https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/http/ext_proc/v3/processing_mode.proto.html#enum-extensions-filters-http-ext-proc-v3-processingmode-bodysendmode<br /> | 
 | `BufferedPartial` | BufferedPartialExtBodyHeaderProcessingMode will buffer the message body in memory and send the entire body in one chunk. If the body exceeds the configured buffer limit, then the body contents up to the buffer limit will be sent.<br /> | 
 
 
@@ -2022,6 +2023,25 @@ _Appears in:_
 | `idleTimeout` | _[Duration](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.Duration)_ |  false  |  | IdleTimeout for an HTTP connection. Idle time is defined as a period in which there are no active requests in the connection.<br />Default: 1 hour. |
 
 
+#### HTTPCredentialInjectionFilter
+
+
+
+HTTPCredentialInjectionFilter defines the configuration to inject credentials into the request.
+This is useful when the backend service requires credentials in the request, and the original
+request does not contain them. The filter can inject credentials into the request before forwarding
+it to the backend service.
+
+_Appears in:_
+- [HTTPRouteFilterSpec](#httproutefilterspec)
+
+| Field | Type | Required | Default | Description |
+| ---   | ---  | ---      | ---     | ---         |
+| `header` | _string_ |  false  |  | Header is the name of the header where the credentials are injected.<br />If not specified, the credentials are injected into the Authorization header. |
+| `overwrite` | _boolean_ |  false  |  | Whether to overwrite the value or not if the injected headers already exist.<br />If not specified, the default value is false. |
+| `credential` | _[InjectedCredential](#injectedcredential)_ |  true  |  | Credential is the credential to be injected. |
+
+
 #### HTTPDirectResponseFilter
 
 
@@ -2145,6 +2165,7 @@ _Appears in:_
 | ---   | ---  | ---      | ---     | ---         |
 | `urlRewrite` | _[HTTPURLRewriteFilter](#httpurlrewritefilter)_ |  false  |  |  |
 | `directResponse` | _[HTTPDirectResponseFilter](#httpdirectresponsefilter)_ |  false  |  |  |
+| `credentialInjection` | _[HTTPCredentialInjectionFilter](#httpcredentialinjectionfilter)_ |  false  |  |  |
 
 
 #### HTTPStatus
@@ -2384,6 +2405,20 @@ _Appears in:_
 | `Host` | InfrastructureProviderTypeHost defines the "Host" provider.<br /> | 
 
 
+#### InjectedCredential
+
+
+
+InjectedCredential defines the credential to be injected.
+
+_Appears in:_
+- [HTTPCredentialInjectionFilter](#httpcredentialinjectionfilter)
+
+| Field | Type | Required | Default | Description |
+| ---   | ---  | ---      | ---     | ---         |
+| `valueRef` | _[SecretObjectReference](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1.SecretObjectReference)_ |  true  |  | ValueRef is a reference to the secret containing the credentials to be injected.<br />This is an Opaque secret. The credential should be stored in the key<br />"credential", and the value should be the credential to be injected.<br />For example, for basic authentication, the value should be "Basic <base64 encoded username:password>".<br />for bearer token, the value should be "Bearer <token>".<br />Note: The secret must be in the same namespace as the HTTPRouteFilter. |
+
+
 #### InvalidMessageAction
 
 _Underlying type:_ _string_
diff --git a/site/content/en/latest/troubleshooting/_index.md b/site/content/en/latest/troubleshooting/_index.md
new file mode 100644
index 000000000..775b2f935
--- /dev/null
+++ b/site/content/en/latest/troubleshooting/_index.md
@@ -0,0 +1,5 @@
+---
+title: "Troubleshooting"
+weight: 2
+description: Learn how to debug Envoy Gateway
+---
diff --git a/site/content/en/latest/troubleshooting/configuration.md b/site/content/en/latest/troubleshooting/configuration.md
new file mode 100644
index 000000000..87b774fd8
--- /dev/null
+++ b/site/content/en/latest/troubleshooting/configuration.md
@@ -0,0 +1,228 @@
++++
+title = "Configuruation Issues"
++++
+
+## Overview
+After configuring and applying resources, you might find that Envoy Gateway does not behave as expected. This guide helps troubleshoot configuration issues.
+
+Many **syntax errors and simple semantic issues** are caught during resource validation by the **Kubernetes API Server**, which rejects invalid resources. However, more complex configuration issues require additional debugging.
+
+## Prerequisites
+
+{{< boilerplate prerequisites >}}
+
+To demonstrate debugging techniques, let’s apply an *intentionally incorrect* HTTPRoute configuration with a *non-existent* backend.
+
+{{< tabpane text=true >}}
+{{% tab header="Apply from stdin" %}}
+
+```shell
+cat <<EOF | kubectl apply -f -
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+EOF
+```
+
+{{% /tab %}}
+{{% tab header="Apply from file" %}}
+Save and apply the following resource to your cluster:
+
+```yaml
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+```
+
+{{% /tab %}}
+{{< /tabpane >}}
+
+### Checking Resource Status
+The `status` field in your resource definitions is your primary troubleshooting tool. It provides insights into whether a resource has been **Accepted** or not, along with the reason for rejection.
+
+#### Using kubectl
+This example below shows why an HTTPRoute has been **Accepted** but the **ResolvedRefs** condition is `false` because the backend does not exist. 
+**Note**: Almost all resources have a `status` field, so be sure to check them all.
+
+```shell
+kubectl get httproute/backend -o yaml
+```
+
+```console
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backend
+  namespace: default
+spec:
+  hostnames:
+  - www.example.com
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backend-does-not-exist
+      port: 3000
+      weight: 1
+    matches:
+    - path:
+        type: PathPrefix
+        value: /
+status:
+  parents:
+  - conditions:
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Route is accepted
+      observedGeneration: 3
+      reason: Accepted
+      status: "True"
+      type: Accepted
+    - lastTransitionTime: "2025-03-08T02:07:53Z"
+      message: Service default/backend-does-not-exist not found
+      observedGeneration: 3
+      reason: BackendNotFound
+      status: "False"
+      type: ResolvedRefs
+    controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    parentRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: eg
+```
+
+#### Using egctl
+The egctl CLI tool can quickly fetch the status of multiple resources at once:
+
+```shell
+egctl x status all -A
+```
+
+```console
+NAME              TYPE       STATUS    REASON
+gatewayclass/eg   Accepted   True      Accepted
+
+NAMESPACE   NAME         TYPE         STATUS    REASON
+default     gateway/eg   Programmed   True      Programmed
+                         Accepted     True      Accepted
+
+NAMESPACE   NAME                TYPE           STATUS    REASON
+default     httproute/backend   ResolvedRefs   False     BackendNotFound
+                                Accepted       True      Accepted
+```
+
+Follow the instructions [here](./../install/install-egctl.md) to install `egctl`.
+
+#### Using kube-state-metrics
+For large-scale deployments, kube-state-metrics can help monitor the status of Envoy Gateway resources. For more details, refer to the [Observability Guide](./../tasks/observability/gateway-api-metrics.md).
+
+### Traffic
+If a configuration is not accepted, Envoy Gateway assigns a `direct_response` to the affected route, causing clients to receive an **HTTP 500 error**.
+
+```shell
+curl --verbose --header "Host: www.example.com" http://$GATEWAY_HOST/get
+```
+
+```console
+*   Trying 127.0.0.1:80...
+* Connected to 127.0.0.1 (127.0.0.1) port 80
+> GET /get HTTP/1.1
+> Host: www.example.com
+> User-Agent: curl/8.7.1
+> Accept: */*
+> 
+* Request completely sent off
+< HTTP/1.1 500 Internal Server Error
+< date: Sat, 08 Mar 2025 02:25:32 GMT
+< content-length: 0
+< 
+* Connection #0 to host 127.0.0.1 left intact
+```
+
+If you inspect the access logs in the pod logs:
+
+```shell
+kubectl logs -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -c envoy | grep start_time | jq
+```
+
+```console
+{
+  ":authority": "www.example.com",
+  "bytes_received": 0,
+  "bytes_sent": 0,
+  "connection_termination_details": null,
+  "downstream_local_address": "10.1.21.65:10080",
+  "downstream_remote_address": "192.168.65.4:45050",
+  "duration": 0,
+  "method": "GET",
+  "protocol": "HTTP/1.1",
+  "requested_server_name": null,
+  "response_code": 500,
+  "response_code_details": "direct_response",
+  "response_flags": "-",
+  "route_name": "httproute/default/backend/rule/0/match/0/www_example_com",
+  "start_time": "2025-03-08T02:25:32.588Z",
+  "upstream_cluster": null,
+  "upstream_host": null,
+  "upstream_local_address": null,
+  "upstream_transport_failure_reason": null,
+  "user-agent": "curl/8.7.1",
+  "x-envoy-origin-path": "/get",
+  "x-envoy-upstream-service-time": null,
+  "x-forwarded-for": "192.168.65.4",
+  "x-request-id": "54c4c2f9-d209-4aa0-8870-342bc6622d1a"
+}
+```
+
+and find the following entries
+
+```console
+"response_code": "500",
+"response_code_details": "direct_response"
+```
+
+this likely indicates a configuration issue. Review the relevant [resource status](#checking-resource-status) for resolution steps.
diff --git a/test/cel-validation/securitypolicy_test.go b/test/cel-validation/securitypolicy_test.go
index 033726f2b..ad53bb478 100644
--- a/test/cel-validation/securitypolicy_test.go
+++ b/test/cel-validation/securitypolicy_test.go
@@ -1015,7 +1015,7 @@ func TestSecurityPolicyTarget(t *testing.T) {
 					},
 				}
 			},
-			wantErrors: []string{"at least one of clientCIDRs or jwt must be specified"},
+			wantErrors: []string{"at least one of clientCIDRs, jwt, or headers must be specified"},
 		},
 		{
 			desc: "authorization-jwt-claims-without-jwt-authn",
diff --git a/test/e2e/testdata/authorization-http-header-and-method.yaml b/test/e2e/testdata/authorization-http-header-and-method.yaml
new file mode 100644
index 000000000..daa6ed430
--- /dev/null
+++ b/test/e2e/testdata/authorization-http-header-and-method.yaml
@@ -0,0 +1,83 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-only-user-id-header
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /protected-only-user-id-header
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: http-with-authorization-multiple-headers-and-methods
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: Exact
+        value: /protected-multiple-headers-and-methods
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-only-user-id-header
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-only-user-id-header
+  authorization:
+    defaultAction: Deny
+    rules:
+    - name: "allow-user-headers"
+      action: Allow
+      principal:
+        headers:
+        - name: x-user-id
+          values:
+          - john
+          - alice
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: authorization-multiple-headers-and-methods
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: http-with-authorization-multiple-headers-and-methods
+  authorization:
+    defaultAction: Deny
+    rules:
+    - name: "allow-user-headers"
+      action: Allow
+      operation:
+        methods:
+        - GET
+      principal:
+        headers:
+        - name: x-user-id
+          values:
+          - john
+        - name: x-location-id
+          values:
+          - chengdu
+          - milpitas
diff --git a/test/e2e/tests/authorization_http_method_and_header.go b/test/e2e/tests/authorization_http_method_and_header.go
new file mode 100644
index 000000000..c474e417c
--- /dev/null
+++ b/test/e2e/tests/authorization_http_method_and_header.go
@@ -0,0 +1,183 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+//go:build e2e
+
+package tests
+
+import (
+	"testing"
+
+	"k8s.io/apimachinery/pkg/types"
+	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+
+	"github.com/envoyproxy/gateway/internal/gatewayapi"
+	"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, AuthorizationHTTPMethodAndHeaderTest)
+}
+
+var AuthorizationHTTPMethodAndHeaderTest = suite.ConformanceTest{
+	ShortName:   "AuthzWithHTTPMethodAndHeader",
+	Description: "Authorization with HTTP method and header",
+	Manifests:   []string{"testdata/authorization-http-header-and-method.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		route1NN := types.NamespacedName{Name: "http-with-authorization-only-user-id-header", Namespace: ns}
+		route2NN := types.NamespacedName{Name: "http-with-authorization-multiple-headers-and-methods", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+		gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), route1NN, route2NN)
+
+		ancestorRef := gwapiv1a2.ParentReference{
+			Group:     gatewayapi.GroupPtr(gwapiv1.GroupName),
+			Kind:      gatewayapi.KindPtr(resource.KindGateway),
+			Namespace: gatewayapi.NamespacePtr(gwNN.Namespace),
+			Name:      gwapiv1.ObjectName(gwNN.Name),
+		}
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-only-user-id-header", Namespace: ns}, suite.ControllerName, ancestorRef)
+		SecurityPolicyMustBeAccepted(t, suite.Client, types.NamespacedName{Name: "authorization-multiple-headers-and-methods", Namespace: ns}, suite.ControllerName, ancestorRef)
+
+		// Test authorization only with headers
+		t.Run("user-id header not present should be denied", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-only-user-id-header",
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+
+		t.Run("user-id header with wrong value should be denied", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-only-user-id-header",
+					Headers: map[string]string{
+						"x-user-id": "wrong-user-id",
+					},
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+
+		t.Run("user-id header with correct value should be allowed", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-only-user-id-header",
+					Headers: map[string]string{
+						"x-user-id": "john",
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+
+		t.Run("user-id header with correct value should be allowed", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-only-user-id-header",
+					Headers: map[string]string{
+						"x-user-id": "alice",
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+
+		// Test authorization with multiple headers and methods
+		t.Run("user-id header not present should be denied", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-multiple-headers-and-methods",
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+
+		t.Run("with correct user-id header and wrong method should be denied", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-multiple-headers-and-methods",
+					Headers: map[string]string{
+						"x-user-id": "john",
+					},
+					Method: "POST",
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+		t.Run("with correct user-id header, correct method and wrong x-location-id header should be denied", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-multiple-headers-and-methods",
+					Headers: map[string]string{
+						"x-user-id":     "john",
+						"x-location-id": "gotham",
+					},
+					Method: "GET",
+				},
+				Response: http.Response{
+					StatusCode: 403,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+		t.Run("with all correct headers and method should be allowed", func(t *testing.T) {
+			expectedResponse := http.ExpectedResponse{
+				Request: http.Request{
+					Path: "/protected-multiple-headers-and-methods",
+					Headers: map[string]string{
+						"x-user-id":     "john",
+						"x-location-id": "chengdu",
+					},
+					Method: "GET",
+				},
+				Response: http.Response{
+					StatusCode: 200,
+				},
+				Namespace: ns,
+			}
+
+			http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+		})
+	},
+}
diff --git a/test/e2e/tests/wasm_oci.go b/test/e2e/tests/wasm_oci.go
index 514ab9373..f9f74cec2 100644
--- a/test/e2e/tests/wasm_oci.go
+++ b/test/e2e/tests/wasm_oci.go
@@ -197,7 +197,7 @@ var OCIWasmTest = suite.ConformanceTest{
 				t, suite.Client,
 				types.NamespacedName{Name: testEEP, Namespace: testNS},
 				suite.ControllerName,
-				ancestorRef, "failed to login to private registry")
+				ancestorRef, "UNAUTHORIZED: authentication required")
 		})
 
 		// Verify that the wasm module can't be loaded if the password is incorrect
@@ -232,7 +232,7 @@ var OCIWasmTest = suite.ConformanceTest{
 				t, suite.Client,
 				types.NamespacedName{Name: testEEP, Namespace: testNS},
 				suite.ControllerName,
-				ancestorRef, "failed to login to private registry")
+				ancestorRef, "UNAUTHORIZED: authentication required")
 		})
 	},
 }