Repository: kubernetes-sigs/gateway-api

Issue:
`Gateway.BackendTLS` is Support:Core without conformance tests
**What happened**:

https://github.com/kubernetes-sigs/gateway-api/pull/3304 incorporated `Support: Core` API changes without any conformance testing.

- Gateway.BackendTLS is Core and experimental without a conformance test.
- BackendTLSPolicyValidation.SubjectAltNames is Core, but there is no conformance test.

It was somewhat discussed in https://github.com/kubernetes-sigs/gateway-api/pull/3304/files#r1739635258

**Update: SubjectAltNames was changed to Extended in https://github.com/kubernetes-sigs/gateway-api/pull/3591**

**What you expected to happen**:

We need to keep them ~both~ Gateway.BackendTLS as ~experimental~ Extended until there are conformance tests

**Anything else we need to know?**

BackendTLSPolicy is on track to go GA in v1.4.0 and this will block that.

Hints from issue comments:
@kl52752: I'm working for test coverage for SAN field. If we could find someone to cover gateway.backendTLS field that would be great :)@snorwin: @candita @shaneutt @kl52752 Is SAN validation really `Core`? According to the API spec, the `SubjectAltNames` list is marked as `Extended`, whereas the fields within it are marked as `Core`. I think we should get a clear understanding of whether it is `Core` or `Extended` and update the spec accordingly.

```
	// SubjectAltNames contains one or more Subject Alternative Names.
	// When specified the certificate served from the backend MUST
	// have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
	//
	// Support: Extended
	//
	// +optional
	// +listType=atomic
	// +kubebuilder:validation:MaxItems=5
	SubjectAltNames []SubjectAltName `json:"subjectAltNames,omitempty"`
```
https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha3/backendtlspolicy_types.go#L173


/cc @mlavacca @robscott: > According to the API spec, the SubjectAltNames list is marked as Extended, whereas the fields within it are marked as Core

My interpretation of this is that supporting `SubjectAltNames` is extended/optional, but if you claim support for the feature, you have to support all fields marked `Core` within that field. If others agree with that interpretation, we should make a corresponding update to our docs to make the pattern more clear.@dprotaso: Should we at least have a feature constant so that SubjectAltNames can be listed as supported features?@snorwin: @robscott Is that pattern used anywhere else? I did a quick check of HTTPRoute and didn’t find any cases where a higher-level field is marked as `Extended` while containing `Core` fields. The opposite does exist and IMO makes sense.

@dprotaso Yes, if it is `Extended`, we’ll need a feature, and therefore split the conformance tests into dedicated methods.

\cc @kl52752 @kl52752: My interpretation aligns with @robscott. I think this is a good pattern where a high level `Extended` field has low level `Core` fields. I think this distinguishes `Extended` from `ImplementationSpecific`.   @youngnick: We've definitely used this "higher-level Extended can have Core fields" pattern before - we use it for the overall support of the various Route objects. Each Route object is actually Extended support, technically, since you can have an implementation that, for example, only supports TLSRoute. But _within_ each Route object, there are Core features that are not optional.
@candita: Update: For the SANs field I was looking at the [original PR in which it was marked Core](https://github.com/kubernetes-sigs/gateway-api/pull/3304).  It had [afterwards been updated to Extended](https://github.com/kubernetes-sigs/gateway-api/pull/3591).

However, Gateway.BackendTLS is still Core and experimental without a conformance test.
@candita: @shaneutt I've updated this.  Do we need to worry about the remaining Core/experimental Gateway.BackendTLS field for v1.4.0 ?  With no conformance test?
@LiorLieberman: Gateway.BackendTLS **does not** need conformance. it will stay experimental and wont graduate. @youngnick: * The SAN list field in BackendTLSPolicy is Extended support.
* We do _not_ need complete conformance tests coverage for all Extended features for an object to move to Standard. We need to have _most_ functionality checked with conformance tests, but we don't need _complete_ functionality.
* The SAN List field's conformance tests can be added after graduation.

Gateway.backendTLS will stay as experimental, and will not graduate, as @LiorLieberman said. @kl52752 is working on adding backend config to the new top-level TLS config struct that also holds the frontend validation. If that merges, we should mark gateway.backendTLS as Deprecated at the same time.@snorwin: @shaneutt @youngnick The conformance tests for SAN validation are  ready  #3981 (kudos to @kl52752). We were looking to verify them against a second implementation, but at the moment there aren’t many spec-compliant implementation available.@kl52752: Thread from chat discussion:  
I'm working on moving Gateway.BackendTLS field into GatewayTLSConfig struct created for clientCertValidation (frontend). This struct is experimental and BackendTLS will stay experimental after this change.  

Solution patch:
diff --git a/apis/v1/gateway_types.go b/apis/v1/gateway_types.go
index e85e81ba..652101ff 100644
--- a/apis/v1/gateway_types.go
+++ b/apis/v1/gateway_types.go
@@ -279,15 +279,6 @@ type GatewaySpec struct {
 	// +optional
 	Infrastructure *GatewayInfrastructure `json:"infrastructure,omitempty"`
 
-	// BackendTLS configures TLS settings for when this Gateway is connecting to
-	// backends with TLS.
-	//
-	// Support: Core
-	//
-	// +optional
-	// <gateway:experimental>
-	BackendTLS *GatewayBackendTLS `json:"backendTLS,omitempty"`
-
 	// AllowedListeners defines which ListenerSets can be attached to this Gateway.
 	// While this feature is experimental, the default value is to allow no ListenerSets.
 	//
@@ -296,7 +287,7 @@ type GatewaySpec struct {
 	// +optional
 	AllowedListeners *AllowedListeners `json:"allowedListeners,omitempty"`
 	//
-	// GatewayTLSConfig specifies frontend tls configuration for gateway.
+	// TLS specifies frontend and backend tls configuration for entire gateway.
 	//
 	// Support: Extended
 	//
@@ -525,8 +516,6 @@ type GatewayBackendTLS struct {
 	// ClientCertificateRef can reference to standard Kubernetes resources, i.e.
 	// Secret, or implementation-specific custom resources.
 	//
-	// This setting can be overridden on the service level by use of BackendTLSPolicy.
-	//
 	// Support: Core
 	//
 	// +optional
@@ -602,8 +591,31 @@ type ListenerTLSConfig struct {
 	Options map[AnnotationKey]AnnotationValue `json:"options,omitempty"`
 }
 
-// GatewayTLSConfig specifies frontend tls configuration for gateway.
+// GatewayTLSConfig specifies frontend and backend tls configuration for gateway.
 type GatewayTLSConfig struct {
+	// Backend describes TLS configuration for gateway when connecting
+	// to backends.
+	//
+	// Note that this contains only details for the Gateway as a TLS client,
+	// and does _not_ imply behavior about how to choose which backend should
+	// get a TLS connection. That is determined by the presence of a BackendTLSPolicy.
+	//
+	// Support: Core
+	//
+	// +optional
+	// <gateway:experimental>
+	Backend *GatewayBackendTLS `json:"backend,omitempty"`
+
+	// Frontend describes TLS config when client connects to Gateway.
+	// Support: Core
+	//
+	// +optional
+	// <gateway:experimental>
+	Frontend *FrontendTLSConfig `json:"frontend,omitempty"`
+}
+
+// FrontendTLSConfig specifies frontend tls configuration for gateway.
+type FrontendTLSConfig struct {
 	// Default specifies the default client certificate validation configuration
 	// for all Listeners handling HTTPS traffic, unless a per-port configuration
 	// is defined.
@@ -653,7 +665,7 @@ const (
 // within this Gateway. Currently, it stores only the client certificate validation
 // configuration, but this may be extended in the future.
 type TLSConfig struct {
-	// FrontendValidation holds configuration information for validating the frontend (client).
+	// Validation holds configuration information for validating the frontend (client).
 	// Setting this field will result in mutual authentication when connecting to the gateway.
 	// In browsers this may result in a dialog appearing
 	// that requests a user to specify the client certificate.
@@ -661,9 +673,9 @@ type TLSConfig struct {
 	//
 	// Support: Core
 	//
-	// +required
+	// +optional
 	// <gateway:experimental>
-	FrontendValidation FrontendTLSValidation `json:"frontendValidation"`
+	Validation *FrontendTLSValidation `json:"validation,omitempty"`
 }
 
 type TLSPortConfig struct {
diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go
index 6bbf75ba..bcbf4890 100644
--- a/apis/v1/zz_generated.deepcopy.go
+++ b/apis/v1/zz_generated.deepcopy.go
@@ -205,6 +205,29 @@ func (in *Fraction) DeepCopy() *Fraction {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *FrontendTLSConfig) DeepCopyInto(out *FrontendTLSConfig) {
+	*out = *in
+	in.Default.DeepCopyInto(&out.Default)
+	if in.PerPort != nil {
+		in, out := &in.PerPort, &out.PerPort
+		*out = make([]TLSPortConfig, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FrontendTLSConfig.
+func (in *FrontendTLSConfig) DeepCopy() *FrontendTLSConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(FrontendTLSConfig)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *FrontendTLSValidation) DeepCopyInto(out *FrontendTLSValidation) {
 	*out = *in
@@ -777,11 +800,6 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) {
 		*out = new(GatewayInfrastructure)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.BackendTLS != nil {
-		in, out := &in.BackendTLS, &out.BackendTLS
-		*out = new(GatewayBackendTLS)
-		(*in).DeepCopyInto(*out)
-	}
 	if in.AllowedListeners != nil {
 		in, out := &in.AllowedListeners, &out.AllowedListeners
 		*out = new(AllowedListeners)
@@ -883,13 +901,15 @@ func (in *GatewayStatusAddress) DeepCopy() *GatewayStatusAddress {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GatewayTLSConfig) DeepCopyInto(out *GatewayTLSConfig) {
 	*out = *in
-	in.Default.DeepCopyInto(&out.Default)
-	if in.PerPort != nil {
-		in, out := &in.PerPort, &out.PerPort
-		*out = make([]TLSPortConfig, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
+	if in.Backend != nil {
+		in, out := &in.Backend, &out.Backend
+		*out = new(GatewayBackendTLS)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.Frontend != nil {
+		in, out := &in.Frontend, &out.Frontend
+		*out = new(FrontendTLSConfig)
+		(*in).DeepCopyInto(*out)
 	}
 }
 
@@ -1962,7 +1982,11 @@ func (in *SupportedFeature) DeepCopy() *SupportedFeature {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *TLSConfig) DeepCopyInto(out *TLSConfig) {
 	*out = *in
-	in.FrontendValidation.DeepCopyInto(&out.FrontendValidation)
+	if in.Validation != nil {
+		in, out := &in.Validation, &out.Validation
+		*out = new(FrontendTLSValidation)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig.
diff --git a/applyconfiguration/apis/v1/frontendtlsconfig.go b/applyconfiguration/apis/v1/frontendtlsconfig.go
new file mode 100644
index 00000000..4cf84649
--- /dev/null
+++ b/applyconfiguration/apis/v1/frontendtlsconfig.go
@@ -0,0 +1,53 @@
+/*
+Copyright The Kubernetes 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.
+*/
+
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1
+
+// FrontendTLSConfigApplyConfiguration represents a declarative configuration of the FrontendTLSConfig type for use
+// with apply.
+type FrontendTLSConfigApplyConfiguration struct {
+	Default *TLSConfigApplyConfiguration      `json:"default,omitempty"`
+	PerPort []TLSPortConfigApplyConfiguration `json:"perPort,omitempty"`
+}
+
+// FrontendTLSConfigApplyConfiguration constructs a declarative configuration of the FrontendTLSConfig type for use with
+// apply.
+func FrontendTLSConfig() *FrontendTLSConfigApplyConfiguration {
+	return &FrontendTLSConfigApplyConfiguration{}
+}
+
+// WithDefault sets the Default field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Default field is set to the value of the last call.
+func (b *FrontendTLSConfigApplyConfiguration) WithDefault(value *TLSConfigApplyConfiguration) *FrontendTLSConfigApplyConfiguration {
+	b.Default = value
+	return b
+}
+
+// WithPerPort adds the given value to the PerPort field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, values provided by each call will be appended to the PerPort field.
+func (b *FrontendTLSConfigApplyConfiguration) WithPerPort(values ...*TLSPortConfigApplyConfiguration) *FrontendTLSConfigApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithPerPort")
+		}
+		b.PerPort = append(b.PerPort, *values[i])
+	}
+	return b
+}
diff --git a/applyconfiguration/apis/v1/gatewayspec.go b/applyconfiguration/apis/v1/gatewayspec.go
index b123a40f..e976dc48 100644
--- a/applyconfiguration/apis/v1/gatewayspec.go
+++ b/applyconfiguration/apis/v1/gatewayspec.go
@@ -29,7 +29,6 @@ type GatewaySpecApplyConfiguration struct {
 	Listeners        []ListenerApplyConfiguration             `json:"listeners,omitempty"`
 	Addresses        []GatewaySpecAddressApplyConfiguration   `json:"addresses,omitempty"`
 	Infrastructure   *GatewayInfrastructureApplyConfiguration `json:"infrastructure,omitempty"`
-	BackendTLS       *GatewayBackendTLSApplyConfiguration     `json:"backendTLS,omitempty"`
 	AllowedListeners *AllowedListenersApplyConfiguration      `json:"allowedListeners,omitempty"`
 	TLS              *GatewayTLSConfigApplyConfiguration      `json:"tls,omitempty"`
 }
@@ -82,14 +81,6 @@ func (b *GatewaySpecApplyConfiguration) WithInfrastructure(value *GatewayInfrast
 	return b
 }
 
-// WithBackendTLS sets the BackendTLS field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the BackendTLS field is set to the value of the last call.
-func (b *GatewaySpecApplyConfiguration) WithBackendTLS(value *GatewayBackendTLSApplyConfiguration) *GatewaySpecApplyConfiguration {
-	b.BackendTLS = value
-	return b
-}
-
 // WithAllowedListeners sets the AllowedListeners field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the AllowedListeners field is set to the value of the last call.
diff --git a/applyconfiguration/apis/v1/gatewaytlsconfig.go b/applyconfiguration/apis/v1/gatewaytlsconfig.go
index dbd3f443..4ec825db 100644
--- a/applyconfiguration/apis/v1/gatewaytlsconfig.go
+++ b/applyconfiguration/apis/v1/gatewaytlsconfig.go
@@ -21,8 +21,8 @@ package v1
 // GatewayTLSConfigApplyConfiguration represents a declarative configuration of the GatewayTLSConfig type for use
 // with apply.
 type GatewayTLSConfigApplyConfiguration struct {
-	Default *TLSConfigApplyConfiguration      `json:"default,omitempty"`
-	PerPort []TLSPortConfigApplyConfiguration `json:"perPort,omitempty"`
+	Backend  *GatewayBackendTLSApplyConfiguration `json:"backend,omitempty"`
+	Frontend *FrontendTLSConfigApplyConfiguration `json:"frontend,omitempty"`
 }
 
 // GatewayTLSConfigApplyConfiguration constructs a declarative configuration of the GatewayTLSConfig type for use with
@@ -31,23 +31,18 @@ func GatewayTLSConfig() *GatewayTLSConfigApplyConfiguration {
 	return &GatewayTLSConfigApplyConfiguration{}
 }
 
-// WithDefault sets the Default field in the declarative configuration to the given value
+// WithBackend sets the Backend field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the Default field is set to the value of the last call.
-func (b *GatewayTLSConfigApplyConfiguration) WithDefault(value *TLSConfigApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
-	b.Default = value
+// If called multiple times, the Backend field is set to the value of the last call.
+func (b *GatewayTLSConfigApplyConfiguration) WithBackend(value *GatewayBackendTLSApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
+	b.Backend = value
 	return b
 }
 
-// WithPerPort adds the given value to the PerPort field in the declarative configuration
-// and returns the receiver, so that objects can be build by chaining "With" function invocations.
-// If called multiple times, values provided by each call will be appended to the PerPort field.
-func (b *GatewayTLSConfigApplyConfiguration) WithPerPort(values ...*TLSPortConfigApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
-	for i := range values {
-		if values[i] == nil {
-			panic("nil value passed to WithPerPort")
-		}
-		b.PerPort = append(b.PerPort, *values[i])
-	}
+// WithFrontend sets the Frontend field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Frontend field is set to the value of the last call.
+func (b *GatewayTLSConfigApplyConfiguration) WithFrontend(value *FrontendTLSConfigApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
+	b.Frontend = value
 	return b
 }
diff --git a/applyconfiguration/apis/v1/tlsconfig.go b/applyconfiguration/apis/v1/tlsconfig.go
index 1dfa5e02..99a42ca4 100644
--- a/applyconfiguration/apis/v1/tlsconfig.go
+++ b/applyconfiguration/apis/v1/tlsconfig.go
@@ -21,7 +21,7 @@ package v1
 // TLSConfigApplyConfiguration represents a declarative configuration of the TLSConfig type for use
 // with apply.
 type TLSConfigApplyConfiguration struct {
-	FrontendValidation *FrontendTLSValidationApplyConfiguration `json:"frontendValidation,omitempty"`
+	Validation *FrontendTLSValidationApplyConfiguration `json:"validation,omitempty"`
 }
 
 // TLSConfigApplyConfiguration constructs a declarative configuration of the TLSConfig type for use with
@@ -30,10 +30,10 @@ func TLSConfig() *TLSConfigApplyConfiguration {
 	return &TLSConfigApplyConfiguration{}
 }
 
-// WithFrontendValidation sets the FrontendValidation field in the declarative configuration to the given value
+// WithValidation sets the Validation field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the FrontendValidation field is set to the value of the last call.
-func (b *TLSConfigApplyConfiguration) WithFrontendValidation(value *FrontendTLSValidationApplyConfiguration) *TLSConfigApplyConfiguration {
-	b.FrontendValidation = value
+// If called multiple times, the Validation field is set to the value of the last call.
+func (b *TLSConfigApplyConfiguration) WithValidation(value *FrontendTLSValidationApplyConfiguration) *TLSConfigApplyConfiguration {
+	b.Validation = value
 	return b
 }
diff --git a/applyconfiguration/internal/internal.go b/applyconfiguration/internal/internal.go
index 953f2863..974c4bd2 100644
--- a/applyconfiguration/internal/internal.go
+++ b/applyconfiguration/internal/internal.go
@@ -304,6 +304,21 @@ var schemaYAML = typed.YAMLObject(`types:
       type:
         scalar: numeric
       default: 0
+- name: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSConfig
+  map:
+    fields:
+    - name: default
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
+      default: {}
+    - name: perPort
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.TLSPortConfig
+          elementRelationship: associative
+          keys:
+          - port
 - name: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSValidation
   map:
     fields:
@@ -598,9 +613,6 @@ var schemaYAML = typed.YAMLObject(`types:
     - name: allowedListeners
       type:
         namedType: io.k8s.sigs.gateway-api.apis.v1.AllowedListeners
-    - name: backendTLS
-      type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayBackendTLS
     - name: gatewayClassName
       type:
         scalar: string
@@ -666,18 +678,12 @@ var schemaYAML = typed.YAMLObject(`types:
 - name: io.k8s.sigs.gateway-api.apis.v1.GatewayTLSConfig
   map:
     fields:
-    - name: default
+    - name: backend
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
-      default: {}
-    - name: perPort
+        namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayBackendTLS
+    - name: frontend
       type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1.TLSPortConfig
-          elementRelationship: associative
-          keys:
-          - port
+        namedType: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSConfig
 - name: io.k8s.sigs.gateway-api.apis.v1.HTTPAuthConfig
   map:
     fields:
@@ -1311,10 +1317,9 @@ var schemaYAML = typed.YAMLObject(`types:
 - name: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
   map:
     fields:
-    - name: frontendValidation
+    - name: validation
       type:
         namedType: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSValidation
-      default: {}
 - name: io.k8s.sigs.gateway-api.apis.v1.TLSPortConfig
   map:
     fields:
diff --git a/applyconfiguration/utils.go b/applyconfiguration/utils.go
index 5acafbc2..274736cd 100644
--- a/applyconfiguration/utils.go
+++ b/applyconfiguration/utils.go
@@ -56,6 +56,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.ForwardBodyConfigApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("Fraction"):
 		return &apisv1.FractionApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("FrontendTLSConfig"):
+		return &apisv1.FrontendTLSConfigApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("FrontendTLSValidation"):
 		return &apisv1.FrontendTLSValidationApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("Gateway"):
diff --git a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
index f04f7b97..6e154e95 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
@@ -215,70 +215,6 @@ spec:
                         x-kubernetes-map-type: atomic
                     type: object
                 type: object
-              backendTLS:
-                description: |-
-                  BackendTLS configures TLS settings for when this Gateway is connecting to
-                  backends with TLS.
-
-                  Support: Core
-                properties:
-                  clientCertificateRef:
-                    description: |-
-                      ClientCertificateRef is a reference to an object that contains a Client
-                      Certificate and the associated private key.
-
-                      References to a resource in different namespace are invalid UNLESS there
-                      is a ReferenceGrant in the target namespace that allows the certificate
-                      to be attached. If a ReferenceGrant does not allow this reference, the
-                      "ResolvedRefs" condition MUST be set to False for this listener with the
-                      "RefNotPermitted" reason.
-
-                      ClientCertificateRef can reference to standard Kubernetes resources, i.e.
-                      Secret, or implementation-specific custom resources.
-
-                      This setting can be overridden on the service level by use of BackendTLSPolicy.
-
-                      Support: Core
-                    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
-                type: object
               gatewayClassName:
                 description: |-
                   GatewayClassName used for this Gateway. This is the name of a
@@ -970,294 +906,363 @@ spec:
                     == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
               tls:
                 description: |-
-                  GatewayTLSConfig specifies frontend tls configuration for gateway.
+                  TLS specifies frontend and backend tls configuration for entire gateway.
 
                   Support: Extended
                 properties:
-                  default:
+                  backend:
                     description: |-
-                      Default specifies the default client certificate validation configuration
-                      for all Listeners handling HTTPS traffic, unless a per-port configuration
-                      is defined.
+                      Backend describes TLS configuration for gateway when connecting
+                      to backends.
 
-                      support: Core
+                      Note that this contains only details for the Gateway as a TLS client,
+                      and does _not_ imply behavior about how to choose which backend should
+                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.
+
+                      Support: Core
                     properties:
-                      frontendValidation:
+                      clientCertificateRef:
                         description: |-
-                          FrontendValidation holds configuration information for validating the frontend (client).
-                          Setting this field will result in mutual authentication when connecting to the gateway.
-                          In browsers this may result in a dialog appearing
-                          that requests a user to specify the client certificate.
-                          The maximum depth of a certificate chain accepted in verification is Implementation specific.
+                          ClientCertificateRef is a reference to an object that contains a Client
+                          Certificate and the associated private key.
+
+                          References to a resource in different namespace are invalid UNLESS there
+                          is a ReferenceGrant in the target namespace that allows the certificate
+                          to be attached. If a ReferenceGrant does not allow this reference, the
+                          "ResolvedRefs" condition MUST be set to False for this listener with the
+                          "RefNotPermitted" reason.
+
+                          ClientCertificateRef can reference to standard Kubernetes resources, i.e.
+                          Secret, or implementation-specific custom resources.
 
                           Support: Core
                         properties:
-                          caCertificateRefs:
+                          group:
+                            default: ""
                             description: |-
-                              CACertificateRefs contains one or more references to
-                              Kubernetes objects that contain TLS certificates of
-                              the Certificate Authorities that can be used
-                              as a trust anchor to validate the certificates presented by the client.
-
-                              A single CA certificate reference to a Kubernetes ConfigMap
-                              has "Core" support.
-                              Implementations MAY choose to support attaching multiple CA certificates to
-                              a Listener, but this behavior is implementation-specific.
-
-                              Support: Core - A single reference to a Kubernetes ConfigMap
-                              with the CA certificate in a key named `ca.crt`.
-
-                              Support: Implementation-specific (More than one certificate in a ConfigMap
-                              with different keys or more than one reference, or other kinds of resources).
-
-                              References to a resource in a different namespace are invalid UNLESS there
-                              is a ReferenceGrant in the target namespace that allows the certificate
-                              to be attached. If a ReferenceGrant does not allow this reference, the
-                              "ResolvedRefs" condition MUST be set to False for this listener with the
-                              "RefNotPermitted" reason.
-                            items:
-                              description: |-
-                                ObjectReference identifies an API object including its namespace.
-
-                                The API object must be valid in the cluster; the Group and Kind must
-                                be registered in the cluster for this reference to be valid.
-
-                                References to objects with invalid Group and Kind are not valid, and must
-                                be rejected by the implementation, with appropriate Conditions set
-                                on the containing object.
-                              properties:
-                                group:
-                                  description: |-
-                                    Group is the group of the referent. For example, "gateway.networking.k8s.io".
-                                    When set to the 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:
-                                  description: Kind is kind of the referent. For example
-                                    "ConfigMap" or "Service".
-                                  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:
-                              - group
-                              - kind
-                              - name
-                              type: object
-                            maxItems: 8
-                            minItems: 1
-                            type: array
-                            x-kubernetes-list-type: atomic
-                          mode:
-                            default: AllowValidOnly
+                              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: |-
-                              FrontendValidationMode defines the mode for validating the client certificate.
-                              There are two possible modes:
-
-                              - AllowValidOnly: In this mode, the gateway will accept connections only if
-                                the client presents a valid certificate. This certificate must successfully
-                                pass validation against the CA certificates specified in `CACertificateRefs`.
-                              - AllowInsecureFallback: In this mode, the gateway will accept connections
-                                even if the client certificate is not presented or fails verification.
+                              Namespace is the namespace of the referenced object. When unspecified, the local
+                              namespace is inferred.
 
-                                This approach delegates client authorization to the backend and introduce
-                                a significant security risk. It should be used in testing environments or
-                                on a temporary basis in non-testing environments.
-
-                              Defaults to AllowValidOnly.
+                              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
-                            enum:
-                            - AllowValidOnly
-                            - AllowInsecureFallback
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
                             type: string
                         required:
-                        - caCertificateRefs
+                        - name
                         type: object
-                    required:
-                    - frontendValidation
                     type: object
-                  perPort:
+                  frontend:
                     description: |-
-                      PerPort specifies tls configuration assigned per port.
-                      Per port configuration is optional. Once set this configuration overrides
-                      the default configuration for all Listeners handling HTTPS traffic
-                      that match this port.
-                      Each override port requires a unique TLS configuration.
-
-                      support: Core
-                    items:
-                      properties:
-                        port:
-                          description: |-
-                            The Port indicates the Port Number to which the TLS configuration will be
-                            applied. This configuration will be applied to all Listeners handling HTTPS
-                            traffic that match this port.
-
-                            Support: Core
-                          format: int32
-                          maximum: 65535
-                          minimum: 1
-                          type: integer
-                        tls:
-                          description: |-
-                            TLS store the configuration that will be applied to all Listeners handling
-                            HTTPS traffic and matching given port.
+                      Frontend describes TLS config when client connects to Gateway.
+                      Support: Core
+                    properties:
+                      default:
+                        description: |-
+                          Default specifies the default client certificate validation configuration
+                          for all Listeners handling HTTPS traffic, unless a per-port configuration
+                          is defined.
 
-                            Support: Core
-                          properties:
-                            frontendValidation:
-                              description: |-
-                                FrontendValidation holds configuration information for validating the frontend (client).
-                                Setting this field will result in mutual authentication when connecting to the gateway.
-                                In browsers this may result in a dialog appearing
-                                that requests a user to specify the client certificate.
-                                The maximum depth of a certificate chain accepted in verification is Implementation specific.
+                          support: Core
+                        properties:
+                          validation:
+                            description: |-
+                              Validation holds configuration information for validating the frontend (client).
+                              Setting this field will result in mutual authentication when connecting to the gateway.
+                              In browsers this may result in a dialog appearing
+                              that requests a user to specify the client certificate.
+                              The maximum depth of a certificate chain accepted in verification is Implementation specific.
 
-                                Support: Core
-                              properties:
-                                caCertificateRefs:
+                              Support: Core
+                            properties:
+                              caCertificateRefs:
+                                description: |-
+                                  CACertificateRefs contains one or more references to
+                                  Kubernetes objects that contain TLS certificates of
+                                  the Certificate Authorities that can be used
+                                  as a trust anchor to validate the certificates presented by the client.
+
+                                  A single CA certificate reference to a Kubernetes ConfigMap
+                                  has "Core" support.
+                                  Implementations MAY choose to support attaching multiple CA certificates to
+                                  a Listener, but this behavior is implementation-specific.
+
+                                  Support: Core - A single reference to a Kubernetes ConfigMap
+                                  with the CA certificate in a key named `ca.crt`.
+
+                                  Support: Implementation-specific (More than one certificate in a ConfigMap
+                                  with different keys or more than one reference, or other kinds of resources).
+
+                                  References to a resource in a different namespace are invalid UNLESS there
+                                  is a ReferenceGrant in the target namespace that allows the certificate
+                                  to be attached. If a ReferenceGrant does not allow this reference, the
+                                  "ResolvedRefs" condition MUST be set to False for this listener with the
+                                  "RefNotPermitted" reason.
+                                items:
                                   description: |-
-                                    CACertificateRefs contains one or more references to
-                                    Kubernetes objects that contain TLS certificates of
-                                    the Certificate Authorities that can be used
-                                    as a trust anchor to validate the certificates presented by the client.
-
-                                    A single CA certificate reference to a Kubernetes ConfigMap
-                                    has "Core" support.
-                                    Implementations MAY choose to support attaching multiple CA certificates to
-                                    a Listener, but this behavior is implementation-specific.
-
-                                    Support: Core - A single reference to a Kubernetes ConfigMap
-                                    with the CA certificate in a key named `ca.crt`.
-
-                                    Support: Implementation-specific (More than one certificate in a ConfigMap
-                                    with different keys or more than one reference, or other kinds of resources).
-
-                                    References to a resource in a different namespace are invalid UNLESS there
-                                    is a ReferenceGrant in the target namespace that allows the certificate
-                                    to be attached. If a ReferenceGrant does not allow this reference, the
-                                    "ResolvedRefs" condition MUST be set to False for this listener with the
-                                    "RefNotPermitted" reason.
-                                  items:
-                                    description: |-
-                                      ObjectReference identifies an API object including its namespace.
+                                    ObjectReference identifies an API object including its namespace.
+
+                                    The API object must be valid in the cluster; the Group and Kind must
+                                    be registered in the cluster for this reference to be valid.
+
+                                    References to objects with invalid Group and Kind are not valid, and must
+                                    be rejected by the implementation, with appropriate Conditions set
+                                    on the containing object.
+                                  properties:
+                                    group:
+                                      description: |-
+                                        Group is the group of the referent. For example, "gateway.networking.k8s.io".
+                                        When set to the 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:
+                                      description: Kind is kind of the referent. For
+                                        example "ConfigMap" or "Service".
+                                      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:
+                                  - group
+                                  - kind
+                                  - name
+                                  type: object
+                                maxItems: 8
+                                minItems: 1
+                                type: array
+                                x-kubernetes-list-type: atomic
+                              mode:
+                                default: AllowValidOnly
+                                description: |-
+                                  FrontendValidationMode defines the mode for validating the client certificate.
+                                  There are two possible modes:
 
-                                      The API object must be valid in the cluster; the Group and Kind must
-                                      be registered in the cluster for this reference to be valid.
+                                  - AllowValidOnly: In this mode, the gateway will accept connections only if
+                                    the client presents a valid certificate. This certificate must successfully
+                                    pass validation against the CA certificates specified in `CACertificateRefs`.
+                                  - AllowInsecureFallback: In this mode, the gateway will accept connections
+                                    even if the client certificate is not presented or fails verification.
 
-                                      References to objects with invalid Group and Kind are not valid, and must
-                                      be rejected by the implementation, with appropriate Conditions set
-                                      on the containing object.
-                                    properties:
-                                      group:
-                                        description: |-
-                                          Group is the group of the referent. For example, "gateway.networking.k8s.io".
-                                          When set to the 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:
-                                        description: Kind is kind of the referent.
-                                          For example "ConfigMap" or "Service".
-                                        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:
-                                    - group
-                                    - kind
-                                    - name
-                                    type: object
-                                  maxItems: 8
-                                  minItems: 1
-                                  type: array
-                                  x-kubernetes-list-type: atomic
-                                mode:
-                                  default: AllowValidOnly
-                                  description: |-
-                                    FrontendValidationMode defines the mode for validating the client certificate.
-                                    There are two possible modes:
+                                    This approach delegates client authorization to the backend and introduce
+                                    a significant security risk. It should be used in testing environments or
+                                    on a temporary basis in non-testing environments.
 
-                                    - AllowValidOnly: In this mode, the gateway will accept connections only if
-                                      the client presents a valid certificate. This certificate must successfully
-                                      pass validation against the CA certificates specified in `CACertificateRefs`.
-                                    - AllowInsecureFallback: In this mode, the gateway will accept connections
-                                      even if the client certificate is not presented or fails verification.
+                                  Defaults to AllowValidOnly.
 
-                                      This approach delegates client authorization to the backend and introduce
-                                      a significant security risk. It should be used in testing environments or
-                                      on a temporary basis in non-testing environments.
+                                  Support: Core
+                                enum:
+                                - AllowValidOnly
+                                - AllowInsecureFallback
+                                type: string
+                            required:
+                            - caCertificateRefs
+                            type: object
+                        type: object
+                      perPort:
+                        description: |-
+                          PerPort specifies tls configuration assigned per port.
+                          Per port configuration is optional. Once set this configuration overrides
+                          the default configuration for all Listeners handling HTTPS traffic
+                          that match this port.
+                          Each override port requires a unique TLS configuration.
+
+                          support: Core
+                        items:
+                          properties:
+                            port:
+                              description: |-
+                                The Port indicates the Port Number to which the TLS configuration will be
+                                applied. This configuration will be applied to all Listeners handling HTTPS
+                                traffic that match this port.
+
+                                Support: Core
+                              format: int32
+                              maximum: 65535
+                              minimum: 1
+                              type: integer
+                            tls:
+                              description: |-
+                                TLS store the configuration that will be applied to all Listeners handling
+                                HTTPS traffic and matching given port.
 
-                                    Defaults to AllowValidOnly.
+                                Support: Core
+                              properties:
+                                validation:
+                                  description: |-
+                                    Validation holds configuration information for validating the frontend (client).
+                                    Setting this field will result in mutual authentication when connecting to the gateway.
+                                    In browsers this may result in a dialog appearing
+                                    that requests a user to specify the client certificate.
+                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.
 
                                     Support: Core
-                                  enum:
-                                  - AllowValidOnly
-                                  - AllowInsecureFallback
-                                  type: string
-                              required:
-                              - caCertificateRefs
+                                  properties:
+                                    caCertificateRefs:
+                                      description: |-
+                                        CACertificateRefs contains one or more references to
+                                        Kubernetes objects that contain TLS certificates of
+                                        the Certificate Authorities that can be used
+                                        as a trust anchor to validate the certificates presented by the client.
+
+                                        A single CA certificate reference to a Kubernetes ConfigMap
+                                        has "Core" support.
+                                        Implementations MAY choose to support attaching multiple CA certificates to
+                                        a Listener, but this behavior is implementation-specific.
+
+                                        Support: Core - A single reference to a Kubernetes ConfigMap
+                                        with the CA certificate in a key named `ca.crt`.
+
+                                        Support: Implementation-specific (More than one certificate in a ConfigMap
+                                        with different keys or more than one reference, or other kinds of resources).
+
+                                        References to a resource in a different namespace are invalid UNLESS there
+                                        is a ReferenceGrant in the target namespace that allows the certificate
+                                        to be attached. If a ReferenceGrant does not allow this reference, the
+                                        "ResolvedRefs" condition MUST be set to False for this listener with the
+                                        "RefNotPermitted" reason.
+                                      items:
+                                        description: |-
+                                          ObjectReference identifies an API object including its namespace.
+
+                                          The API object must be valid in the cluster; the Group and Kind must
+                                          be registered in the cluster for this reference to be valid.
+
+                                          References to objects with invalid Group and Kind are not valid, and must
+                                          be rejected by the implementation, with appropriate Conditions set
+                                          on the containing object.
+                                        properties:
+                                          group:
+                                            description: |-
+                                              Group is the group of the referent. For example, "gateway.networking.k8s.io".
+                                              When set to the 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:
+                                            description: Kind is kind of the referent.
+                                              For example "ConfigMap" or "Service".
+                                            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:
+                                        - group
+                                        - kind
+                                        - name
+                                        type: object
+                                      maxItems: 8
+                                      minItems: 1
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mode:
+                                      default: AllowValidOnly
+                                      description: |-
+                                        FrontendValidationMode defines the mode for validating the client certificate.
+                                        There are two possible modes:
+
+                                        - AllowValidOnly: In this mode, the gateway will accept connections only if
+                                          the client presents a valid certificate. This certificate must successfully
+                                          pass validation against the CA certificates specified in `CACertificateRefs`.
+                                        - AllowInsecureFallback: In this mode, the gateway will accept connections
+                                          even if the client certificate is not presented or fails verification.
+
+                                          This approach delegates client authorization to the backend and introduce
+                                          a significant security risk. It should be used in testing environments or
+                                          on a temporary basis in non-testing environments.
+
+                                        Defaults to AllowValidOnly.
+
+                                        Support: Core
+                                      enum:
+                                      - AllowValidOnly
+                                      - AllowInsecureFallback
+                                      type: string
+                                  required:
+                                  - caCertificateRefs
+                                  type: object
                               type: object
                           required:
-                          - frontendValidation
+                          - port
+                          - tls
                           type: object
-                      required:
-                      - port
-                      - tls
-                      type: object
-                    maxItems: 64
-                    type: array
-                    x-kubernetes-list-map-keys:
-                    - port
-                    x-kubernetes-list-type: map
-                    x-kubernetes-validations:
-                    - message: Port for TLS configuration must be unique within the
-                        Gateway
-                      rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))
-                required:
-                - default
+                        maxItems: 64
+                        type: array
+                        x-kubernetes-list-map-keys:
+                        - port
+                        x-kubernetes-list-type: map
+                        x-kubernetes-validations:
+                        - message: Port for TLS configuration must be unique within
+                            the Gateway
+                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))
+                    required:
+                    - default
+                    type: object
                 type: object
             required:
             - gatewayClassName
@@ -1762,70 +1767,6 @@ spec:
                         x-kubernetes-map-type: atomic
                     type: object
                 type: object
-              backendTLS:
-                description: |-
-                  BackendTLS configures TLS settings for when this Gateway is connecting to
-                  backends with TLS.
-
-                  Support: Core
-                properties:
-                  clientCertificateRef:
-                    description: |-
-                      ClientCertificateRef is a reference to an object that contains a Client
-                      Certificate and the associated private key.
-
-                      References to a resource in different namespace are invalid UNLESS there
-                      is a ReferenceGrant in the target namespace that allows the certificate
-                      to be attached. If a ReferenceGrant does not allow this reference, the
-                      "ResolvedRefs" condition MUST be set to False for this listener with the
-                      "RefNotPermitted" reason.
-
-                      ClientCertificateRef can reference to standard Kubernetes resources, i.e.
-                      Secret, or implementation-specific custom resources.
-
-                      This setting can be overridden on the service level by use of BackendTLSPolicy.
-
-                      Support: Core
-                    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
-                type: object
               gatewayClassName:
                 description: |-
                   GatewayClassName used for this Gateway. This is the name of a
@@ -2517,294 +2458,363 @@ spec:
                     == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
               tls:
                 description: |-
-                  GatewayTLSConfig specifies frontend tls configuration for gateway.
+                  TLS specifies frontend and backend tls configuration for entire gateway.
 
                   Support: Extended
                 properties:
-                  default:
+                  backend:
                     description: |-
-                      Default specifies the default client certificate validation configuration
-                      for all Listeners handling HTTPS traffic, unless a per-port configuration
-                      is defined.
+                      Backend describes TLS configuration for gateway when connecting
+                      to backends.
 
-                      support: Core
+                      Note that this contains only details for the Gateway as a TLS client,
+                      and does _not_ imply behavior about how to choose which backend should
+                      get a TLS connection. That is determined by the presence of a BackendTLSPolicy.
+
+                      Support: Core
                     properties:
-                      frontendValidation:
+                      clientCertificateRef:
                         description: |-
-                          FrontendValidation holds configuration information for validating the frontend (client).
-                          Setting this field will result in mutual authentication when connecting to the gateway.
-                          In browsers this may result in a dialog appearing
-                          that requests a user to specify the client certificate.
-                          The maximum depth of a certificate chain accepted in verification is Implementation specific.
+                          ClientCertificateRef is a reference to an object that contains a Client
+                          Certificate and the associated private key.
+
+                          References to a resource in different namespace are invalid UNLESS there
+                          is a ReferenceGrant in the target namespace that allows the certificate
+                          to be attached. If a ReferenceGrant does not allow this reference, the
+                          "ResolvedRefs" condition MUST be set to False for this listener with the
+                          "RefNotPermitted" reason.
+
+                          ClientCertificateRef can reference to standard Kubernetes resources, i.e.
+                          Secret, or implementation-specific custom resources.
 
                           Support: Core
                         properties:
-                          caCertificateRefs:
+                          group:
+                            default: ""
                             description: |-
-                              CACertificateRefs contains one or more references to
-                              Kubernetes objects that contain TLS certificates of
-                              the Certificate Authorities that can be used
-                              as a trust anchor to validate the certificates presented by the client.
-
-                              A single CA certificate reference to a Kubernetes ConfigMap
-                              has "Core" support.
-                              Implementations MAY choose to support attaching multiple CA certificates to
-                              a Listener, but this behavior is implementation-specific.
-
-                              Support: Core - A single reference to a Kubernetes ConfigMap
-                              with the CA certificate in a key named `ca.crt`.
-
-                              Support: Implementation-specific (More than one certificate in a ConfigMap
-                              with different keys or more than one reference, or other kinds of resources).
-
-                              References to a resource in a different namespace are invalid UNLESS there
-                              is a ReferenceGrant in the target namespace that allows the certificate
-                              to be attached. If a ReferenceGrant does not allow this reference, the
-                              "ResolvedRefs" condition MUST be set to False for this listener with the
-                              "RefNotPermitted" reason.
-                            items:
-                              description: |-
-                                ObjectReference identifies an API object including its namespace.
-
-                                The API object must be valid in the cluster; the Group and Kind must
-                                be registered in the cluster for this reference to be valid.
-
-                                References to objects with invalid Group and Kind are not valid, and must
-                                be rejected by the implementation, with appropriate Conditions set
-                                on the containing object.
-                              properties:
-                                group:
-                                  description: |-
-                                    Group is the group of the referent. For example, "gateway.networking.k8s.io".
-                                    When set to the 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:
-                                  description: Kind is kind of the referent. For example
-                                    "ConfigMap" or "Service".
-                                  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:
-                              - group
-                              - kind
-                              - name
-                              type: object
-                            maxItems: 8
-                            minItems: 1
-                            type: array
-                            x-kubernetes-list-type: atomic
-                          mode:
-                            default: AllowValidOnly
+                              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: |-
-                              FrontendValidationMode defines the mode for validating the client certificate.
-                              There are two possible modes:
-
-                              - AllowValidOnly: In this mode, the gateway will accept connections only if
-                                the client presents a valid certificate. This certificate must successfully
-                                pass validation against the CA certificates specified in `CACertificateRefs`.
-                              - AllowInsecureFallback: In this mode, the gateway will accept connections
-                                even if the client certificate is not presented or fails verification.
+                              Namespace is the namespace of the referenced object. When unspecified, the local
+                              namespace is inferred.
 
-                                This approach delegates client authorization to the backend and introduce
-                                a significant security risk. It should be used in testing environments or
-                                on a temporary basis in non-testing environments.
-
-                              Defaults to AllowValidOnly.
+                              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
-                            enum:
-                            - AllowValidOnly
-                            - AllowInsecureFallback
+                            maxLength: 63
+                            minLength: 1
+                            pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
                             type: string
                         required:
-                        - caCertificateRefs
+                        - name
                         type: object
-                    required:
-                    - frontendValidation
                     type: object
-                  perPort:
+                  frontend:
                     description: |-
-                      PerPort specifies tls configuration assigned per port.
-                      Per port configuration is optional. Once set this configuration overrides
-                      the default configuration for all Listeners handling HTTPS traffic
-                      that match this port.
-                      Each override port requires a unique TLS configuration.
-
-                      support: Core
-                    items:
-                      properties:
-                        port:
-                          description: |-
-                            The Port indicates the Port Number to which the TLS configuration will be
-                            applied. This configuration will be applied to all Listeners handling HTTPS
-                            traffic that match this port.
-
-                            Support: Core
-                          format: int32
-                          maximum: 65535
-                          minimum: 1
-                          type: integer
-                        tls:
-                          description: |-
-                            TLS store the configuration that will be applied to all Listeners handling
-                            HTTPS traffic and matching given port.
+                      Frontend describes TLS config when client connects to Gateway.
+                      Support: Core
+                    properties:
+                      default:
+                        description: |-
+                          Default specifies the default client certificate validation configuration
+                          for all Listeners handling HTTPS traffic, unless a per-port configuration
+                          is defined.
 
-                            Support: Core
-                          properties:
-                            frontendValidation:
-                              description: |-
-                                FrontendValidation holds configuration information for validating the frontend (client).
-                                Setting this field will result in mutual authentication when connecting to the gateway.
-                                In browsers this may result in a dialog appearing
-                                that requests a user to specify the client certificate.
-                                The maximum depth of a certificate chain accepted in verification is Implementation specific.
+                          support: Core
+                        properties:
+                          validation:
+                            description: |-
+                              Validation holds configuration information for validating the frontend (client).
+                              Setting this field will result in mutual authentication when connecting to the gateway.
+                              In browsers this may result in a dialog appearing
+                              that requests a user to specify the client certificate.
+                              The maximum depth of a certificate chain accepted in verification is Implementation specific.
 
-                                Support: Core
-                              properties:
-                                caCertificateRefs:
+                              Support: Core
+                            properties:
+                              caCertificateRefs:
+                                description: |-
+                                  CACertificateRefs contains one or more references to
+                                  Kubernetes objects that contain TLS certificates of
+                                  the Certificate Authorities that can be used
+                                  as a trust anchor to validate the certificates presented by the client.
+
+                                  A single CA certificate reference to a Kubernetes ConfigMap
+                                  has "Core" support.
+                                  Implementations MAY choose to support attaching multiple CA certificates to
+                                  a Listener, but this behavior is implementation-specific.
+
+                                  Support: Core - A single reference to a Kubernetes ConfigMap
+                                  with the CA certificate in a key named `ca.crt`.
+
+                                  Support: Implementation-specific (More than one certificate in a ConfigMap
+                                  with different keys or more than one reference, or other kinds of resources).
+
+                                  References to a resource in a different namespace are invalid UNLESS there
+                                  is a ReferenceGrant in the target namespace that allows the certificate
+                                  to be attached. If a ReferenceGrant does not allow this reference, the
+                                  "ResolvedRefs" condition MUST be set to False for this listener with the
+                                  "RefNotPermitted" reason.
+                                items:
                                   description: |-
-                                    CACertificateRefs contains one or more references to
-                                    Kubernetes objects that contain TLS certificates of
-                                    the Certificate Authorities that can be used
-                                    as a trust anchor to validate the certificates presented by the client.
-
-                                    A single CA certificate reference to a Kubernetes ConfigMap
-                                    has "Core" support.
-                                    Implementations MAY choose to support attaching multiple CA certificates to
-                                    a Listener, but this behavior is implementation-specific.
-
-                                    Support: Core - A single reference to a Kubernetes ConfigMap
-                                    with the CA certificate in a key named `ca.crt`.
-
-                                    Support: Implementation-specific (More than one certificate in a ConfigMap
-                                    with different keys or more than one reference, or other kinds of resources).
-
-                                    References to a resource in a different namespace are invalid UNLESS there
-                                    is a ReferenceGrant in the target namespace that allows the certificate
-                                    to be attached. If a ReferenceGrant does not allow this reference, the
-                                    "ResolvedRefs" condition MUST be set to False for this listener with the
-                                    "RefNotPermitted" reason.
-                                  items:
-                                    description: |-
-                                      ObjectReference identifies an API object including its namespace.
+                                    ObjectReference identifies an API object including its namespace.
+
+                                    The API object must be valid in the cluster; the Group and Kind must
+                                    be registered in the cluster for this reference to be valid.
+
+                                    References to objects with invalid Group and Kind are not valid, and must
+                                    be rejected by the implementation, with appropriate Conditions set
+                                    on the containing object.
+                                  properties:
+                                    group:
+                                      description: |-
+                                        Group is the group of the referent. For example, "gateway.networking.k8s.io".
+                                        When set to the 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:
+                                      description: Kind is kind of the referent. For
+                                        example "ConfigMap" or "Service".
+                                      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:
+                                  - group
+                                  - kind
+                                  - name
+                                  type: object
+                                maxItems: 8
+                                minItems: 1
+                                type: array
+                                x-kubernetes-list-type: atomic
+                              mode:
+                                default: AllowValidOnly
+                                description: |-
+                                  FrontendValidationMode defines the mode for validating the client certificate.
+                                  There are two possible modes:
 
-                                      The API object must be valid in the cluster; the Group and Kind must
-                                      be registered in the cluster for this reference to be valid.
+                                  - AllowValidOnly: In this mode, the gateway will accept connections only if
+                                    the client presents a valid certificate. This certificate must successfully
+                                    pass validation against the CA certificates specified in `CACertificateRefs`.
+                                  - AllowInsecureFallback: In this mode, the gateway will accept connections
+                                    even if the client certificate is not presented or fails verification.
 
-                                      References to objects with invalid Group and Kind are not valid, and must
-                                      be rejected by the implementation, with appropriate Conditions set
-                                      on the containing object.
-                                    properties:
-                                      group:
-                                        description: |-
-                                          Group is the group of the referent. For example, "gateway.networking.k8s.io".
-                                          When set to the 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:
-                                        description: Kind is kind of the referent.
-                                          For example "ConfigMap" or "Service".
-                                        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:
-                                    - group
-                                    - kind
-                                    - name
-                                    type: object
-                                  maxItems: 8
-                                  minItems: 1
-                                  type: array
-                                  x-kubernetes-list-type: atomic
-                                mode:
-                                  default: AllowValidOnly
-                                  description: |-
-                                    FrontendValidationMode defines the mode for validating the client certificate.
-                                    There are two possible modes:
+                                    This approach delegates client authorization to the backend and introduce
+                                    a significant security risk. It should be used in testing environments or
+                                    on a temporary basis in non-testing environments.
 
-                                    - AllowValidOnly: In this mode, the gateway will accept connections only if
-                                      the client presents a valid certificate. This certificate must successfully
-                                      pass validation against the CA certificates specified in `CACertificateRefs`.
-                                    - AllowInsecureFallback: In this mode, the gateway will accept connections
-                                      even if the client certificate is not presented or fails verification.
+                                  Defaults to AllowValidOnly.
 
-                                      This approach delegates client authorization to the backend and introduce
-                                      a significant security risk. It should be used in testing environments or
-                                      on a temporary basis in non-testing environments.
+                                  Support: Core
+                                enum:
+                                - AllowValidOnly
+                                - AllowInsecureFallback
+                                type: string
+                            required:
+                            - caCertificateRefs
+                            type: object
+                        type: object
+                      perPort:
+                        description: |-
+                          PerPort specifies tls configuration assigned per port.
+                          Per port configuration is optional. Once set this configuration overrides
+                          the default configuration for all Listeners handling HTTPS traffic
+                          that match this port.
+                          Each override port requires a unique TLS configuration.
+
+                          support: Core
+                        items:
+                          properties:
+                            port:
+                              description: |-
+                                The Port indicates the Port Number to which the TLS configuration will be
+                                applied. This configuration will be applied to all Listeners handling HTTPS
+                                traffic that match this port.
+
+                                Support: Core
+                              format: int32
+                              maximum: 65535
+                              minimum: 1
+                              type: integer
+                            tls:
+                              description: |-
+                                TLS store the configuration that will be applied to all Listeners handling
+                                HTTPS traffic and matching given port.
 
-                                    Defaults to AllowValidOnly.
+                                Support: Core
+                              properties:
+                                validation:
+                                  description: |-
+                                    Validation holds configuration information for validating the frontend (client).
+                                    Setting this field will result in mutual authentication when connecting to the gateway.
+                                    In browsers this may result in a dialog appearing
+                                    that requests a user to specify the client certificate.
+                                    The maximum depth of a certificate chain accepted in verification is Implementation specific.
 
                                     Support: Core
-                                  enum:
-                                  - AllowValidOnly
-                                  - AllowInsecureFallback
-                                  type: string
-                              required:
-                              - caCertificateRefs
+                                  properties:
+                                    caCertificateRefs:
+                                      description: |-
+                                        CACertificateRefs contains one or more references to
+                                        Kubernetes objects that contain TLS certificates of
+                                        the Certificate Authorities that can be used
+                                        as a trust anchor to validate the certificates presented by the client.
+
+                                        A single CA certificate reference to a Kubernetes ConfigMap
+                                        has "Core" support.
+                                        Implementations MAY choose to support attaching multiple CA certificates to
+                                        a Listener, but this behavior is implementation-specific.
+
+                                        Support: Core - A single reference to a Kubernetes ConfigMap
+                                        with the CA certificate in a key named `ca.crt`.
+
+                                        Support: Implementation-specific (More than one certificate in a ConfigMap
+                                        with different keys or more than one reference, or other kinds of resources).
+
+                                        References to a resource in a different namespace are invalid UNLESS there
+                                        is a ReferenceGrant in the target namespace that allows the certificate
+                                        to be attached. If a ReferenceGrant does not allow this reference, the
+                                        "ResolvedRefs" condition MUST be set to False for this listener with the
+                                        "RefNotPermitted" reason.
+                                      items:
+                                        description: |-
+                                          ObjectReference identifies an API object including its namespace.
+
+                                          The API object must be valid in the cluster; the Group and Kind must
+                                          be registered in the cluster for this reference to be valid.
+
+                                          References to objects with invalid Group and Kind are not valid, and must
+                                          be rejected by the implementation, with appropriate Conditions set
+                                          on the containing object.
+                                        properties:
+                                          group:
+                                            description: |-
+                                              Group is the group of the referent. For example, "gateway.networking.k8s.io".
+                                              When set to the 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:
+                                            description: Kind is kind of the referent.
+                                              For example "ConfigMap" or "Service".
+                                            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:
+                                        - group
+                                        - kind
+                                        - name
+                                        type: object
+                                      maxItems: 8
+                                      minItems: 1
+                                      type: array
+                                      x-kubernetes-list-type: atomic
+                                    mode:
+                                      default: AllowValidOnly
+                                      description: |-
+                                        FrontendValidationMode defines the mode for validating the client certificate.
+                                        There are two possible modes:
+
+                                        - AllowValidOnly: In this mode, the gateway will accept connections only if
+                                          the client presents a valid certificate. This certificate must successfully
+                                          pass validation against the CA certificates specified in `CACertificateRefs`.
+                                        - AllowInsecureFallback: In this mode, the gateway will accept connections
+                                          even if the client certificate is not presented or fails verification.
+
+                                          This approach delegates client authorization to the backend and introduce
+                                          a significant security risk. It should be used in testing environments or
+                                          on a temporary basis in non-testing environments.
+
+                                        Defaults to AllowValidOnly.
+
+                                        Support: Core
+                                      enum:
+                                      - AllowValidOnly
+                                      - AllowInsecureFallback
+                                      type: string
+                                  required:
+                                  - caCertificateRefs
+                                  type: object
                               type: object
                           required:
-                          - frontendValidation
+                          - port
+                          - tls
                           type: object
-                      required:
-                      - port
-                      - tls
-                      type: object
-                    maxItems: 64
-                    type: array
-                    x-kubernetes-list-map-keys:
-                    - port
-                    x-kubernetes-list-type: map
-                    x-kubernetes-validations:
-                    - message: Port for TLS configuration must be unique within the
-                        Gateway
-                      rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))
-                required:
-                - default
+                        maxItems: 64
+                        type: array
+                        x-kubernetes-list-map-keys:
+                        - port
+                        x-kubernetes-list-type: map
+                        x-kubernetes-validations:
+                        - message: Port for TLS configuration must be unique within
+                            the Gateway
+                          rule: self.all(t1, self.exists_one(t2, t1.port == t2.port))
+                    required:
+                    - default
+                    type: object
                 type: object
             required:
             - gatewayClassName
diff --git a/conformance/base/manifests.yaml b/conformance/base/manifests.yaml
index 9380223e..d8f8c45a 100644
--- a/conformance/base/manifests.yaml
+++ b/conformance/base/manifests.yaml
@@ -95,6 +95,39 @@ spec:
           matchLabels:
             gateway-conformance: backend
 ---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: gateway-backendtlspolicy
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+  - name: http
+    port: 80
+    protocol: HTTP
+    hostname: "abc.example.com"
+    allowedRoutes:
+      namespaces:
+        from: Same
+      kinds:
+      - kind: HTTPRoute
+  - name: https
+    port: 443
+    protocol: HTTPS
+    tls:
+      mode: Terminate
+      certificateRefs:
+      - group: ""
+        kind: Secret
+        name: tls-checks-certificate
+    hostname: "abc.example.com"
+    allowedRoutes:
+      namespaces:
+        from: Same
+      kinds:
+      - kind: HTTPRoute
+---
 apiVersion: v1
 kind: Service
 metadata:
diff --git a/conformance/utils/echo/pod.go b/conformance/utils/echo/pod.go
index 0222ff12..dff03ed5 100644
--- a/conformance/utils/echo/pod.go
+++ b/conformance/utils/echo/pod.go
@@ -20,6 +20,8 @@ import (
 	"bytes"
 	"context"
 	"fmt"
+	"slices"
+	"strconv"
 	"strings"
 	"testing"
 	"time"
@@ -84,8 +86,14 @@ func makeRequest(t *testing.T, exp *http.ExpectedResponse) []string {
 		exp.Request.Method = "GET"
 	}
 
-	if exp.Response.StatusCode == 0 {
-		exp.Response.StatusCode = 200
+	// if the deprecated field StatusCode is set, append it to StatusCodes for backwards compatibility
+	//nolint:staticcheck
+	if exp.Response.StatusCode != 0 {
+		exp.Response.StatusCodes = append(exp.Response.StatusCodes, exp.Response.StatusCode)
+	}
+
+	if len(exp.Response.StatusCodes) == 0 {
+		exp.Response.StatusCodes = []int{200}
 	}
 
 	r := exp.Request
@@ -110,8 +118,12 @@ func compareRequest(exp http.ExpectedResponse, resp Response) error {
 	}
 	wantReq := exp.ExpectedRequest
 	wantResp := exp.Response
-	if fmt.Sprint(wantResp.StatusCode) != resp.Code {
-		return fmt.Errorf("wanted status code %v, got %v", wantResp.StatusCode, resp.Code)
+	statusCode, err := strconv.Atoi(resp.Code)
+	if err != nil {
+		return fmt.Errorf("invalid status code '%v': %v", resp.Code, err)
+	}
+	if !slices.Contains(wantResp.StatusCodes, statusCode) {
+		return fmt.Errorf("wanted status code to be one of %v, got %d", wantResp.StatusCodes, statusCode)
 	}
 	if wantReq.Headers != nil {
 		if resp.RequestHeaders == nil {
diff --git a/conformance/utils/http/http.go b/conformance/utils/http/http.go
index 50f8d1ef..6cd68dd0 100644
--- a/conformance/utils/http/http.go
+++ b/conformance/utils/http/http.go
@@ -22,6 +22,7 @@ import (
 	"math/big"
 	"net"
 	"net/url"
+	"slices"
 	"strings"
 	"testing"
 	"time"
@@ -91,7 +92,9 @@ type ExpectedRequest struct {
 
 // Response defines expected properties of a response from a backend.
 type Response struct {
+	// Deprecated: Use StatusCodes instead, which supports matching against multiple status codes.
 	StatusCode    int
+	StatusCodes   []int
 	Headers       map[string]string
 	AbsentHeaders []string
 	Protocol      string
@@ -138,8 +141,13 @@ func MakeRequest(t *testing.T, expected *ExpectedResponse, gwAddr, protocol, sch
 		expected.Request.Method = "GET"
 	}
 
-	if expected.Response.StatusCode == 0 {
-		expected.Response.StatusCode = 200
+	// if the deprecated field StatusCode is set, append it to StatusCodes for backwards compatibility
+	if expected.Response.StatusCode != 0 {
+		expected.Response.StatusCodes = append(expected.Response.StatusCodes, expected.Response.StatusCode)
+	}
+
+	if len(expected.Response.StatusCodes) == 0 {
+		expected.Response.StatusCodes = []int{200}
 	}
 
 	if expected.Request.Protocol == "" {
@@ -300,12 +308,14 @@ func WaitForConsistentFailureResponse(t *testing.T, r roundtripper.RoundTripper,
 
 func CompareRoundTrip(t *testing.T, req *roundtripper.Request, cReq *roundtripper.CapturedRequest, cRes *roundtripper.CapturedResponse, expected ExpectedResponse) error {
 	if roundtripper.IsTimeoutError(cRes.StatusCode) {
-		if roundtripper.IsTimeoutError(expected.Response.StatusCode) {
-			return nil
+		for _, statusCode := range expected.Response.StatusCodes {
+			if roundtripper.IsTimeoutError(statusCode) {
+				return nil
+			}
 		}
 	}
-	if expected.Response.StatusCode != cRes.StatusCode {
-		return fmt.Errorf("expected status code to be %d, got %d. CRes: %v", expected.Response.StatusCode, cRes.StatusCode, cRes)
+	if !slices.Contains(expected.Response.StatusCodes, cRes.StatusCode) {
+		return fmt.Errorf("expected status code to be one of %v, got %d. CRes: %v", expected.Response.StatusCodes, cRes.StatusCode, cRes)
 	}
 	if expected.Response.Protocol != "" && expected.Response.Protocol != cRes.Protocol {
 		return fmt.Errorf("expected protocol to be %s, got %s", expected.Response.Protocol, cRes.Protocol)
@@ -467,7 +477,8 @@ func (er *ExpectedResponse) GetTestCaseName(i int) string {
 	if er.Backend != "" {
 		return fmt.Sprintf("%s should go to %s", reqStr, er.Backend)
 	}
-	return fmt.Sprintf("%s should receive a %d", reqStr, er.Response.StatusCode)
+
+	return fmt.Sprintf("%s should receive one of %v", reqStr, er.Response.StatusCodes)
 }
 
 func setRedirectRequestDefaults(req *roundtripper.Request, cRes *roundtripper.CapturedResponse, expected *ExpectedResponse) {
diff --git a/conformance/utils/kubernetes/certificate.go b/conformance/utils/kubernetes/certificate.go
index 07c3c807..1b2ee3af 100644
--- a/conformance/utils/kubernetes/certificate.go
+++ b/conformance/utils/kubernetes/certificate.go
@@ -27,6 +27,7 @@ import (
 	"io"
 	"math/big"
 	"net"
+	"net/url"
 	"strings"
 	"testing"
 	"time"
@@ -119,6 +120,8 @@ func generateRSACert(hosts []string, keyOut, certOut io.Writer, ca *x509.Certifi
 			template.IPAddresses = append(template.IPAddresses, ip)
 		} else if err = validateHost(h); err == nil {
 			template.DNSNames = append(template.DNSNames, h)
+		} else if u, parseErr := url.Parse(h); parseErr == nil {
+			template.URIs = append(template.URIs, u)
 		}
 	}
 
@@ -215,6 +218,8 @@ func generateCACert(hosts []string) (*x509.Certificate, []byte, *rsa.PrivateKey,
 			ca.IPAddresses = append(ca.IPAddresses, ip)
 		} else if err := validateHost(h); err == nil {
 			ca.DNSNames = append(ca.DNSNames, h)
+		} else if u, err := url.Parse(h); err == nil {
+			ca.URIs = append(ca.URIs, u)
 		}
 	}
 
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index ea9b8af6..3309c8f2 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -1003,7 +1003,7 @@ func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeo
 		policy := &v1alpha3.BackendTLSPolicy{}
 		err := client.Get(ctx, policyNN, policy)
 		if err != nil {
-			return false, fmt.Errorf("error fetching BackendTLSPolicy: %w", err)
+			return false, fmt.Errorf("error fetching BackendTLSPolicy %v err: %w", policyNN, err)
 		}
 
 		for _, parent := range policy.Status.Ancestors {
@@ -1024,7 +1024,7 @@ func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeo
 		return false, nil
 	})
 
-	require.NoErrorf(t, waitErr, "error waiting for BackendTLSPolicy status to have a Condition %v", condition)
+	require.NoErrorf(t, waitErr, "error waiting for BackendTLSPolicy %v status to have a Condition %v", policyNN, condition)
 }
 
 // BackendTLSPolicyMustHaveLatestConditions will fail the test if there are
diff --git a/conformance/utils/suite/profiles.go b/conformance/utils/suite/profiles.go
index 2f589ed4..996fe346 100644
--- a/conformance/utils/suite/profiles.go
+++ b/conformance/utils/suite/profiles.go
@@ -119,7 +119,6 @@ var (
 		ExtendedFeatures: sets.New[features.FeatureName]().
 			Insert(features.SetsToNamesSet(
 				features.MeshExtendedFeatures,
-				features.HTTPRouteExtendedFeatures,
 			).UnsortedList()...),
 	}
 
diff --git a/conformance/utils/suite/suite.go b/conformance/utils/suite/suite.go
index 23c93653..877c030f 100644
--- a/conformance/utils/suite/suite.go
+++ b/conformance/utils/suite/suite.go
@@ -394,6 +394,11 @@ func (suite *ConformanceTestSuite) Setup(t *testing.T, tests []ConformanceTest)
 		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{caConfigMap}, suite.Cleanup)
 		secret = kubernetes.MustCreateCASignedCertSecret(t, "gateway-conformance-infra", "tls-checks-certificate", []string{"abc.example.com"}, ca, caPrivKey)
 		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
+		// TODO(kl52752) Merge CA certificates for Backend TLS Policy and move Deployment to common file.
+		caConfigMap, ca, caPrivKey = kubernetes.MustCreateCACertConfigMap(t, "gateway-conformance-infra", "backend-tls-with-san-certificate", []string{"abc.example.com", "spiffe://abc.example.com/test-identity"})
+		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{caConfigMap}, suite.Cleanup)
+		secret = kubernetes.MustCreateCASignedCertSecret(t, "gateway-conformance-infra", "tls-with-san-certificate", []string{"abc.example.com", "spiffe://abc.example.com/test-identity"}, ca, caPrivKey)
+		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
 
 		tlog.Logf(t, "Test Setup: Ensuring Gateways and Pods from base manifests are ready")
 		namespaces := []string{
diff --git a/examples/experimental/backend-tls.yaml b/examples/experimental/backend-tls.yaml
new file mode 100644
index 00000000..94b8be09
--- /dev/null
+++ b/examples/experimental/backend-tls.yaml
@@ -0,0 +1,18 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: backend-tls
+spec:
+  gatewayClassName: acme-lb
+  tls:
+    backend:
+      clientCertificateRef:
+        kind: Secret
+        group: ""
+        name: foo-example-cert
+  listeners:
+  - name: foo-https
+    protocol: HTTP
+    port: 80
+    hostname: foo.example.com
+---
diff --git a/examples/experimental/frontend-cert-validation.yaml b/examples/experimental/frontend-cert-validation.yaml
index a7a9d4a1..34ada262 100644
--- a/examples/experimental/frontend-cert-validation.yaml
+++ b/examples/experimental/frontend-cert-validation.yaml
@@ -5,12 +5,22 @@ metadata:
 spec:
   gatewayClassName: acme-lb
   tls:
-    default:
-      frontendValidation:
-        caCertificateRefs:
-        - kind: ConfigMap
-          group: ""
-          name: foo-example-com-ca-cert
+    frontend:
+      default:
+        validation:
+          caCertificateRefs:
+          - kind: ConfigMap
+            group: ""
+            name: foo-example-com-ca-cert
+      perPort:
+      - port: 8443
+        tls:
+          validation:
+            caCertificateRefs:
+            - kind: ConfigMap
+              group: ""
+              name: foo-example-com-ca-cert
+            mode: "AllowInsecureFallback"
   listeners:
   - name: foo-https
     protocol: HTTPS
@@ -21,5 +31,14 @@ spec:
       - kind: Secret
         group: ""
         name: foo-example-com-cert
+  - name: bar-https
+    protocol: HTTPS
+    port: 8443
+    hostname: bar.example.com
+    tls:
+      certificateRefs:
+      - kind: Secret
+        group: ""
+        name: bar-example-com-cert
 ---
 
diff --git a/geps/gep-3155/index.md b/geps/gep-3155/index.md
index b75b64cc..41477c22 100644
--- a/geps/gep-3155/index.md
+++ b/geps/gep-3155/index.md
@@ -43,13 +43,20 @@ Specifying credentials at the gateway level is the default operation mode, where
 backends will be presented with a single gateway certificate. Per-service overrides are
 subject for consideration as the future work.
 
-**1. Add a new `BackendTLS` field at the top level of Gateways**
+**1. Add a new `BackendValidation` field at TLSConfig struct located in GatewayTLSConfig.Default field**
 
 ```go
-type GatewaySpec struct {
-  // BackendTLS configures TLS settings for when this Gateway is connecting to
-  // backends with TLS.
-  BackendTLS GatewayBackendTLS `json:"backendTLS,omitempty"'`
+// TLSConfig describes TLS configuration that can apply to multiple Listeners
+// within this Gateway.
+type TLSConfig struct {
+    ...
+	// GatewayBackendTLS describes TLS configuration for gateway when connecting
+	// to backends.
+	// Support: Core
+	//
+	// +optional
+	// <gateway:experimental>
+	BackendValidation *GatewayBackendTLS `json:"backendValidation,omitempty"`
 }
 type GatewayBackendTLS struct {
   // ClientCertificateRef is a reference to an object that contains a Client
diff --git a/pkg/features/backendtlspolicy.go b/pkg/features/backendtlspolicy.go
index 95d50171..12c6a24c 100644
--- a/pkg/features/backendtlspolicy.go
+++ b/pkg/features/backendtlspolicy.go
@@ -25,6 +25,9 @@ import "k8s.io/apimachinery/pkg/util/sets"
 const (
 	// This option indicates support for BackendTLSPolicy.
 	SupportBackendTLSPolicy FeatureName = "BackendTLSPolicy"
+
+	// This option indicates support for BackendTLSPolicy SubjectAltName Validation.
+	SupportBackendTLSPolicySANValidation FeatureName = "BackendTLSPolicySANValidation"
 )
 
 // TLSRouteFeature contains metadata for the TLSRoute feature.
@@ -33,8 +36,21 @@ var BackendTLSPolicyFeature = Feature{
 	Channel: FeatureChannelExperimental,
 }
 
+// BackendTLSPolicySanValidationFeature contains metadata for the BackendTLSPolicy
+// SubjectAltName Validation feature.
+var BackendTLSPolicySanValidationFeature = Feature{
+	Name:    SupportBackendTLSPolicySANValidation,
+	Channel: FeatureChannelExperimental,
+}
+
 // BackendTLSPolicyCoreFeatures includes all the supported features for the
 // BackendTLSPolicy API at a Core level of support.
 var BackendTLSPolicyCoreFeatures = sets.New(
 	BackendTLSPolicyFeature,
 )
+
+// BackendTLSPolicyExtendedFeatures includes all the supported features for the
+// BackendTLSPolicy API at a Extended level of support.
+var BackendTLSPolicyExtendedFeatures = sets.New(
+	BackendTLSPolicySanValidationFeature,
+)
diff --git a/pkg/features/httproute.go b/pkg/features/httproute.go
index 6c484da9..53f93afd 100644
--- a/pkg/features/httproute.go
+++ b/pkg/features/httproute.go
@@ -100,6 +100,9 @@ const (
 
 	// This option indicates support for the name field in the HTTPRouteRule (extended conformance)
 	SupportHTTPRouteNamedRouteRule FeatureName = "HTTPRouteNamedRouteRule"
+
+	// This option indicates support for the cors filter in the HTTPRouteFilter (extended conformance)
+	SupportHTTPRouteCORS FeatureName = "HTTPRouteCORS"
 )
 
 var (
@@ -198,6 +201,11 @@ var (
 		Name:    SupportHTTPRouteNamedRouteRule,
 		Channel: FeatureChannelStandard,
 	}
+	// HTTPRouteCORS contains metadata for the SupportHTTPRouteCORS feature.
+	HTTPRouteCORS = Feature{
+		Name:    SupportHTTPRouteCORS,
+		Channel: FeatureChannelExperimental,
+	}
 )
 
 // HTTPRouteExtendedFeatures includes all extended features for HTTPRoute
@@ -223,4 +231,5 @@ var HTTPRouteExtendedFeatures = sets.New(
 	HTTPRouteBackendProtocolH2CFeature,
 	HTTPRouteBackendProtocolWebSocketFeature,
 	HTTPRouteNamedRouteRule,
+	HTTPRouteCORS,
 )
diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go
index 588319b3..1451e17d 100644
--- a/pkg/generated/openapi/zz_generated.openapi.go
+++ b/pkg/generated/openapi/zz_generated.openapi.go
@@ -90,6 +90,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"sigs.k8s.io/gateway-api/apis/v1.CookieConfig":                                    schema_sigsk8sio_gateway_api_apis_v1_CookieConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ForwardBodyConfig":                               schema_sigsk8sio_gateway_api_apis_v1_ForwardBodyConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.Fraction":                                        schema_sigsk8sio_gateway_api_apis_v1_Fraction(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.FrontendTLSConfig":                               schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation":                           schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.GRPCAuthConfig":                                  schema_sigsk8sio_gateway_api_apis_v1_GRPCAuthConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.GRPCBackendRef":                                  schema_sigsk8sio_gateway_api_apis_v1_GRPCBackendRef(ref),
@@ -3113,6 +3114,51 @@ func schema_sigsk8sio_gateway_api_apis_v1_Fraction(ref common.ReferenceCallback)
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "FrontendTLSConfig specifies frontend tls configuration for gateway.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"default": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Default specifies the default client certificate validation configuration for all Listeners handling HTTPS traffic, unless a per-port configuration is defined.\n\nsupport: Core\n\n<gateway:experimental>",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.TLSConfig"),
+						},
+					},
+					"perPort": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-map-keys": []interface{}{
+									"port",
+								},
+								"x-kubernetes-list-type": "map",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "PerPort specifies tls configuration assigned per port. Per port configuration is optional. Once set this configuration overrides the default configuration for all Listeners handling HTTPS traffic that match this port. Each override port requires a unique TLS configuration.\n\nsupport: Core\n\n<gateway:experimental>",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: map[string]interface{}{},
+										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"),
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"default"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.TLSConfig", "sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -3779,7 +3825,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewayBackendTLS(ref common.Reference
 				Properties: map[string]spec.Schema{
 					"clientCertificateRef": {
 						SchemaProps: spec.SchemaProps{
-							Description: "ClientCertificateRef is a reference to an object that contains a Client Certificate and the associated private key.\n\nReferences to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason.\n\nClientCertificateRef can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources.\n\nThis setting can be overridden on the service level by use of BackendTLSPolicy.\n\nSupport: Core\n\n<gateway:experimental>",
+							Description: "ClientCertificateRef is a reference to an object that contains a Client Certificate and the associated private key.\n\nReferences to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason.\n\nClientCertificateRef can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources.\n\nSupport: Core\n\n<gateway:experimental>",
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.SecretObjectReference"),
 						},
 					},
@@ -4149,12 +4195,6 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure"),
 						},
 					},
-					"backendTLS": {
-						SchemaProps: spec.SchemaProps{
-							Description: "BackendTLS configures TLS settings for when this Gateway is connecting to backends with TLS.\n\nSupport: Core\n\n<gateway:experimental>",
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS"),
-						},
-					},
 					"allowedListeners": {
 						SchemaProps: spec.SchemaProps{
 							Description: "AllowedListeners defines which ListenerSets can be attached to this Gateway. While this feature is experimental, the default value is to allow no ListenerSets.\n\n<gateway:experimental>",
@@ -4163,7 +4203,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 					},
 					"tls": {
 						SchemaProps: spec.SchemaProps{
-							Description: "GatewayTLSConfig specifies frontend tls configuration for gateway.\n\nSupport: Extended\n\n<gateway:experimental>",
+							Description: "TLS specifies frontend and backend tls configuration for entire gateway.\n\nSupport: Extended\n\n<gateway:experimental>",
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"),
 						},
 					},
@@ -4172,7 +4212,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.AllowedListeners", "sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS", "sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure", "sigs.k8s.io/gateway-api/apis/v1.GatewaySpecAddress", "sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig", "sigs.k8s.io/gateway-api/apis/v1.Listener"},
+			"sigs.k8s.io/gateway-api/apis/v1.AllowedListeners", "sigs.k8s.io/gateway-api/apis/v1.GatewayInfrastructure", "sigs.k8s.io/gateway-api/apis/v1.GatewaySpecAddress", "sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig", "sigs.k8s.io/gateway-api/apis/v1.Listener"},
 	}
 }
 
@@ -4314,44 +4354,26 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewayTLSConfig(ref common.ReferenceC
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "GatewayTLSConfig specifies frontend tls configuration for gateway.",
+				Description: "GatewayTLSConfig specifies frontend and backend tls configuration for gateway.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
-					"default": {
+					"backend": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Default specifies the default client certificate validation configuration for all Listeners handling HTTPS traffic, unless a per-port configuration is defined.\n\nsupport: Core\n\n<gateway:experimental>",
-							Default:     map[string]interface{}{},
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.TLSConfig"),
+							Description: "Backend describes TLS configuration for gateway when connecting to backends.\n\nNote that this contains only details for the Gateway as a TLS client, and does _not_ imply behavior about how to choose which backend should get a TLS connection. That is determined by the presence of a BackendTLSPolicy.\n\nSupport: Core\n\n<gateway:experimental>",
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS"),
 						},
 					},
-					"perPort": {
-						VendorExtensible: spec.VendorExtensible{
-							Extensions: spec.Extensions{
-								"x-kubernetes-list-map-keys": []interface{}{
-									"port",
-								},
-								"x-kubernetes-list-type": "map",
-							},
-						},
+					"frontend": {
 						SchemaProps: spec.SchemaProps{
-							Description: "PerPort specifies tls configuration assigned per port. Per port configuration is optional. Once set this configuration overrides the default configuration for all Listeners handling HTTPS traffic that match this port. Each override port requires a unique TLS configuration.\n\nsupport: Core\n\n<gateway:experimental>",
-							Type:        []string{"array"},
-							Items: &spec.SchemaOrArray{
-								Schema: &spec.Schema{
-									SchemaProps: spec.SchemaProps{
-										Default: map[string]interface{}{},
-										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"),
-									},
-								},
-							},
+							Description: "Frontend describes TLS config when client connects to Gateway. Support: Core\n\n<gateway:experimental>",
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.FrontendTLSConfig"),
 						},
 					},
 				},
-				Required: []string{"default"},
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.TLSConfig", "sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"},
+			"sigs.k8s.io/gateway-api/apis/v1.FrontendTLSConfig", "sigs.k8s.io/gateway-api/apis/v1.GatewayBackendTLS"},
 	}
 }
 
@@ -6230,15 +6252,13 @@ func schema_sigsk8sio_gateway_api_apis_v1_TLSConfig(ref common.ReferenceCallback
 				Description: "TLSConfig describes TLS configuration that can apply to multiple Listeners within this Gateway. Currently, it stores only the client certificate validation configuration, but this may be extended in the future.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
-					"frontendValidation": {
+					"validation": {
 						SchemaProps: spec.SchemaProps{
-							Description: "FrontendValidation holds configuration information for validating the frontend (client). Setting this field will result in mutual authentication when connecting to the gateway. In browsers this may result in a dialog appearing that requests a user to specify the client certificate. The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core\n\n<gateway:experimental>",
-							Default:     map[string]interface{}{},
+							Description: "Validation holds configuration information for validating the frontend (client). Setting this field will result in mutual authentication when connecting to the gateway. In browsers this may result in a dialog appearing that requests a user to specify the client certificate. The maximum depth of a certificate chain accepted in verification is Implementation specific.\n\nSupport: Core\n\n<gateway:experimental>",
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation"),
 						},
 					},
 				},
-				Required: []string{"frontendValidation"},
 			},
 		},
 		Dependencies: []string{



Test patch:
diff --git a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go
new file mode 100644
index 00000000..824d8dd1
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go
@@ -0,0 +1,98 @@
+/*
+Copyright 2025 The Kubernetes 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 tests
+
+import (
+	"testing"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
+	h "sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, BackendTLSPolicyInvalidCACertificateRef)
+}
+
+var BackendTLSPolicyInvalidCACertificateRef = suite.ConformanceTest{
+	ShortName:   "BackendTLSPolicyInvalidCACertificateRef",
+	Description: "A BackendTLSPolicy that specifies a single invalid CACertificateRef should have the Accepted and ResolvedRefs status condition set False with appropriate reasons, and HTTP requests to a backend targeted by this policy should fail with a 5xx response.",
+	Features: []features.FeatureName{
+		features.SupportGateway,
+		features.SupportHTTPRoute,
+		features.SupportBackendTLSPolicy,
+	},
+	Manifests: []string{"tests/backendtlspolicy-invalid-ca-certificate-ref.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		routeNN := types.NamespacedName{Name: "backendtlspolicy-invalid-ca-certificate-ref", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+
+		serverStr := "abc.example.com"
+
+		kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, []string{ns})
+		gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gatewayv1.HTTPRoute{}, false, routeNN)
+
+		for _, policyNN := range []types.NamespacedName{
+			{Name: "nonexistent-ca-certificate-ref", Namespace: ns},
+			{Name: "malformed-ca-certificate-ref", Namespace: ns},
+		} {
+			t.Run("BackendTLSPolicy_"+policyNN.Name, func(t *testing.T) {
+				t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a Accepted Condition with status False and Reason NoValidCACertificate", func(t *testing.T) {
+					acceptedCond := metav1.Condition{
+						Type:   string(gatewayv1alpha2.PolicyConditionAccepted),
+						Status: metav1.ConditionFalse,
+						Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonNoValidCACertificate),
+					}
+
+					kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, acceptedCond)
+				})
+
+				t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a ResolvedRefs Condition with status False and Reason InvalidCACertificateRef", func(t *testing.T) {
+					resolvedRefsCond := metav1.Condition{
+						Type:   string(gatewayv1alpha3.BackendTLSPolicyConditionResolvedRefs),
+						Status: metav1.ConditionFalse,
+						Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonInvalidCACertificateRef),
+					}
+
+					kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, resolvedRefsCond)
+				})
+
+				t.Run("HTTP Request to backend targeted by an invalid BackendTLSPolicy receive a 5xx", func(t *testing.T) {
+					h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+						h.ExpectedResponse{
+							Namespace: ns,
+							Request: h.Request{
+								Host: serverStr,
+								Path: "/backendtlspolicy-" + policyNN.Name,
+							},
+							Response: h.Response{
+								StatusCodes: []int{500, 502, 503},
+							},
+						})
+				})
+			})
+		}
+	},
+}
diff --git a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml
new file mode 100644
index 00000000..138812fd
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml
@@ -0,0 +1,97 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backendtlspolicy-invalid-ca-certificate-ref
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: same-namespace
+      namespace: gateway-conformance-infra
+  hostnames:
+    - abc.example.com
+  rules:
+    - backendRefs:
+        - name: backendtlspolicy-nonexistent-ca-certificate-ref-test
+          port: 443
+      matches:
+        - path:
+            type: Exact
+            value: /backendtlspolicy-nonexistent-ca-certificate-ref
+    - backendRefs:
+        - name: backendtlspolicy-malformed-ca-certificate-ref-test
+          port: 443
+      matches:
+        - path:
+            type: Exact
+            value: /backendtlspolicy-malformed-ca-certificate-ref
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-nonexistent-ca-certificate-ref-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: tls-backend
+  ports:
+    - name: "https"
+      protocol: TCP
+      appProtocol: HTTPS
+      port: 443
+      targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-malformed-ca-certificate-ref-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: tls-backend
+  ports:
+    - name: "https"
+      protocol: TCP
+      appProtocol: HTTPS
+      port: 443
+      targetPort: 8443
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: nonexistent-ca-certificate-ref
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+    - group: ""
+      kind: Service
+      name: "backendtlspolicy-nonexistent-ca-certificate-ref-test"
+  validation:
+    caCertificateRefs:
+      - group: ""
+        kind: ConfigMap
+        name: "nonexistent-ca-certificate"
+    hostname: "abc.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: malformed-ca-certificate-ref
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+    - group: ""
+      kind: Service
+      name: "backendtlspolicy-malformed-ca-certificate-ref-test"
+  validation:
+    caCertificateRefs:
+      - group: ""
+        kind: ConfigMap
+        name: "malformed-ca-certificate"
+    hostname: "abc.example.com"
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: malformed-ca-certificate
+  namespace: gateway-conformance-infra
+data: {}
diff --git a/conformance/tests/backendtlspolicy-invalid-kind.go b/conformance/tests/backendtlspolicy-invalid-kind.go
new file mode 100644
index 00000000..5a3bba59
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-invalid-kind.go
@@ -0,0 +1,93 @@
+/*
+Copyright 2025 The Kubernetes 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 tests
+
+import (
+	"testing"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
+	gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
+	h "sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, BackendTLSPolicyInvalidKind)
+}
+
+var BackendTLSPolicyInvalidKind = suite.ConformanceTest{
+	ShortName:   "BackendTLSPolicyInvalidKind",
+	Description: "A BackendTLSPolicy that specifies a single CACertificateRef with an invalid kind should have the Accepted and ResolvedRefs status condition set False with appropriate reasons, and HTTP requests to a backend targeted by this policy should fail with a 5xx response.",
+	Features: []features.FeatureName{
+		features.SupportGateway,
+		features.SupportHTTPRoute,
+		features.SupportBackendTLSPolicy,
+	},
+	Manifests: []string{"tests/backendtlspolicy-invalid-kind.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		routeNN := types.NamespacedName{Name: "backendtlspolicy-invalid-kind-test", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+
+		serverStr := "abc.example.com"
+
+		kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, []string{ns})
+		gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gatewayv1.HTTPRoute{}, false, routeNN)
+
+		policyNN := types.NamespacedName{Name: "invalid-kind", Namespace: ns}
+
+		t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a Accepted Condition with status False and Reason NoValidCACertificate", func(t *testing.T) {
+			acceptedCond := metav1.Condition{
+				Type:   string(gatewayv1alpha2.PolicyConditionAccepted),
+				Status: metav1.ConditionFalse,
+				Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonNoValidCACertificate),
+			}
+
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, acceptedCond)
+		})
+
+		t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a ResolvedRefs Condition with status False and Reason InvalidKind", func(t *testing.T) {
+			resolvedRefsCond := metav1.Condition{
+				Type:   string(gatewayv1alpha3.BackendTLSPolicyConditionResolvedRefs),
+				Status: metav1.ConditionFalse,
+				Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonInvalidKind),
+			}
+
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, resolvedRefsCond)
+		})
+
+		t.Run("HTTP Request to backend targeted by an invalid BackendTLSPolicy receive a 5xx", func(t *testing.T) {
+			h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendtlspolicy-" + policyNN.Name,
+					},
+					Response: h.Response{
+						StatusCodes: []int{500, 502, 503},
+					},
+				})
+		})
+	},
+}
diff --git a/conformance/tests/backendtlspolicy-invalid-kind.yaml b/conformance/tests/backendtlspolicy-invalid-kind.yaml
new file mode 100644
index 00000000..a7eaeb5d
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-invalid-kind.yaml
@@ -0,0 +1,51 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backendtlspolicy-invalid-kind-test
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: same-namespace
+      namespace: gateway-conformance-infra
+  hostnames:
+    - abc.example.com
+  rules:
+    - backendRefs:
+        - name: backendtlspolicy-invalid-kind-test
+          port: 443
+      matches:
+        - path:
+            type: Exact
+            value: /backendtlspolicy-invalid-kind
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-invalid-kind-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: tls-backend
+  ports:
+    - name: "https"
+      protocol: TCP
+      appProtocol: HTTPS
+      port: 443
+      targetPort: 8443
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: invalid-kind
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+    - group: ""
+      kind: Service
+      name: "backendtlspolicy-invalid-kind-test"
+  validation:
+    caCertificateRefs:
+      - group: invalid.io
+        kind: InvalidKind
+        name: "invalid-kind"
+    hostname: "abc.example.com"
diff --git a/conformance/tests/backendtlspolicy-san.go b/conformance/tests/backendtlspolicy-san.go
new file mode 100644
index 00000000..38e7a2b4
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-san.go
@@ -0,0 +1,163 @@
+/*
+Copyright 2025 The Kubernetes 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 tests
+
+import (
+	"testing"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/apis/v1alpha2"
+	h "sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, BackendTLSPolicySANValidation)
+}
+
+var BackendTLSPolicySANValidation = suite.ConformanceTest{
+	ShortName:   "BackendTLSPolicySANValidation",
+	Description: "BackendTLSPolicySANValidation extend BackendTLSPolicy with SubjectAltNames validation",
+	Features: []features.FeatureName{
+		features.SupportGateway,
+		features.SupportHTTPRoute,
+		features.SupportBackendTLSPolicy,
+		features.SupportBackendTLSPolicySANValidation,
+	},
+	Manifests: []string{"tests/backendtlspolicy-san.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		routeNN := types.NamespacedName{Name: "route-backendtlspolicy-san-test", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "gateway-backendtlspolicy", Namespace: ns}
+
+		kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, []string{ns})
+		gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gatewayv1.HTTPRoute{}, false, routeNN)
+		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
+
+		policyCond := metav1.Condition{
+			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Status: metav1.ConditionTrue,
+			Reason: string(v1alpha2.PolicyReasonAccepted),
+		}
+
+		serverStr := "abc.example.com"
+
+		// Verify that the request sent to Service with valid BackendTLSPolicy containing dns SAN should succeed.
+		t.Run("HTTP request sent to Service with valid BackendTLSPolicy containing dns SAN should succeed", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-san-dns", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSSanDns",
+						SNI:  serverStr,
+					},
+					Response: h.Response{StatusCode: 200},
+				})
+		})
+
+		// Verify that the request sent to a Service targeted by a BackendTLSPolicy with mismatched dns SAN should fail.
+		t.Run("HTTP request sent to Service targeted by BackendTLSPolicy with mismatched dns SAN should return an HTTP error", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-san-dns-mismatch", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSSanDnsMismatch",
+						SNI:  serverStr,
+					},
+				})
+		})
+
+		// Verify that the request sent to Service with valid BackendTLSPolicy containing uri SAN should succeed.
+		t.Run("HTTP request sent to Service with valid BackendTLSPolicy containing uri SAN should succeed", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-san-uri", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSSanUri",
+						SNI:  serverStr,
+					},
+					Response: h.Response{StatusCode: 200},
+				})
+		})
+
+		// Verify that the request sent to a Service targeted by a BackendTLSPolicy with mismatched uri SAN should fail.
+		t.Run("HTTP request sent to Service targeted by BackendTLSPolicy with mismatched uri SAN should return an HTTP error", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-san-uri-mismatch", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSSanUriMismatch",
+						SNI:  serverStr,
+					},
+				})
+		})
+
+		// Verify that the request sent to Service with valid BackendTLSPolicy containing multi SANs should succeed.
+		t.Run("HTTP request sent to Service with valid BackendTLSPolicy containing multi SAN should succeed", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-multiple-sans", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSMultiSans",
+						SNI:  serverStr,
+					},
+					Response: h.Response{StatusCode: 200},
+				})
+		})
+
+		// Verify that the request sent to a Service targeted by a BackendTLSPolicy with mismatched multi SAN should fail.
+		t.Run("HTTP request sent to Service targeted by BackendTLSPolicy with mismatched multi SAN should return an HTTP error", func(t *testing.T) {
+			policyNN := types.NamespacedName{Name: "backendtlspolicy-multiple-mismatch-sans", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, policyCond)
+
+			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSMultiMismatchSans",
+						SNI:  serverStr,
+					},
+				})
+		})
+	},
+}
diff --git a/conformance/tests/backendtlspolicy-san.yaml b/conformance/tests/backendtlspolicy-san.yaml
new file mode 100644
index 00000000..e3e0f79b
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-san.yaml
@@ -0,0 +1,341 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: route-backendtlspolicy-san-test
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: gateway-backendtlspolicy
+    namespace: gateway-conformance-infra
+  hostnames:
+  - abc.example.com
+  rules:
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-san-dns-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSSanDns
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-san-dns-mismatch-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSSanDnsMismatch
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-san-uri-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSSanUri
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-san-uri-mismatch-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSSanUriMismatch
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-multiple-sans-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSMultiSans
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-multiple-mismatch-sans-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSMultiMismatchSans
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-san-dns-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-san-dns-mismatch-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-san-uri-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-san-uri-mismatch-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-multiple-sans-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-multiple-mismatch-sans-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-san-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: backendtlspolicy-san-test
+  namespace: gateway-conformance-infra
+  labels:
+    app: backendtlspolicy-san-test
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: backendtlspolicy-san-test
+  template:
+    metadata:
+      labels:
+        app: backendtlspolicy-san-test
+    spec:
+      containers:
+      - name: backendtlspolicy-san-test
+        image: gcr.io/k8s-staging-gateway-api/echo-basic:v20240412-v1.0.0-394-g40c666fd
+        volumeMounts:
+        - name: secret-volume
+          mountPath: /etc/secret-volume
+        env:
+        - name: POD_NAME
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.name
+        - name: NAMESPACE
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace
+        - name: TLS_SERVER_CERT
+          value: /etc/secret-volume/crt
+        - name: TLS_SERVER_PRIVKEY
+          value: /etc/secret-volume/key
+        resources:
+          requests:
+            cpu: 10m
+      volumes:
+      - name: secret-volume
+        secret:
+          # This secret is generated dynamically by the test suite.
+          secretName: tls-with-san-certificate
+          items:
+          - key: tls.crt
+            path: crt
+          - key: tls.key
+            path: key
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-san-dns
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-san-dns-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "Hostname"
+      hostname: "abc.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-san-dns-mismatch
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-san-dns-mismatch-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "Hostname"
+      hostname: "dce.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-san-uri
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-san-uri-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "URI"
+      uri: "spiffe://abc.example.com/test-identity"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-san-uri-mismatch
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-san-uri-mismatch-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "URI"
+      uri: "spiffe://def.example.com/test-identity"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-multiple-sans
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-multiple-sans-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "URI"
+      uri: "spiffe://abc.example.com/test-identity"
+    - type: "Hostname"
+      hostname: "abc.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-multiple-mismatch-sans
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: backendtlspolicy-multiple-mismatch-sans-test
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-with-san-certificate"
+    hostname: "abc.example.com"
+    subjectAltNames:
+    - type: "URI"
+      uri: "spiffe://def.example.com/test-identity"
+    - type: "Hostname"
+      hostname: "def.example.com"
diff --git a/conformance/tests/backendtlspolicy.go b/conformance/tests/backendtlspolicy.go
index fc6c6576..62ed54c4 100644
--- a/conformance/tests/backendtlspolicy.go
+++ b/conformance/tests/backendtlspolicy.go
@@ -20,11 +20,11 @@ import (
 	"testing"
 
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/apis/v1alpha3"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -54,20 +54,20 @@ var BackendTLSPolicy = suite.ConformanceTest{
 		gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gatewayv1.HTTPRoute{}, false, routeNN)
 		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
 
-		policyCond := metav1.Condition{
+		acceptedCond := metav1.Condition{
 			Type:   string(v1alpha2.PolicyConditionAccepted),
 			Status: metav1.ConditionTrue,
 			Reason: string(v1alpha2.PolicyReasonAccepted),
 		}
+		resolvedRefsCond := metav1.Condition{
+			Type:   string(v1alpha3.BackendTLSPolicyConditionResolvedRefs),
+			Status: metav1.ConditionTrue,
+			Reason: string(v1alpha3.BackendTLSPolicyReasonResolvedRefs),
+		}
 
 		validPolicyNN := types.NamespacedName{Name: "normative-test-backendtlspolicy", Namespace: ns}
-		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, policyCond)
-
-		invalidPolicyNN := types.NamespacedName{Name: "backendtlspolicy-host-mismatch", Namespace: ns}
-		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidPolicyNN, gwNN, policyCond)
-
-		invalidCertPolicyNN := types.NamespacedName{Name: "backendtlspolicy-cert-mismatch", Namespace: ns}
-		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidCertPolicyNN, gwNN, policyCond)
+		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, acceptedCond)
+		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, resolvedRefsCond)
 
 		serverStr := "abc.example.com"
 
@@ -107,6 +107,10 @@ var BackendTLSPolicy = suite.ConformanceTest{
 
 		// Verify that the request sent to a Service targeted by a BackendTLSPolicy with mismatched host will fail.
 		t.Run("HTTP request sent to Service targeted by BackendTLSPolicy with mismatched hostname should return an HTTP error", func(t *testing.T) {
+			invalidPolicyNN := types.NamespacedName{Name: "backendtlspolicy-host-mismatch", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidPolicyNN, gwNN, acceptedCond)
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidPolicyNN, gwNN, resolvedRefsCond)
+
 			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
 				h.ExpectedResponse{
 					Namespace: ns,
@@ -120,6 +124,10 @@ var BackendTLSPolicy = suite.ConformanceTest{
 
 		// Verify that request sent to Service targeted by BackendTLSPolicy with mismatched cert should failed.
 		t.Run("HTTP request send to Service targeted by BackendTLSPolicy with mismatched cert should return HTTP error", func(t *testing.T) {
+			invalidCertPolicyNN := types.NamespacedName{Name: "backendtlspolicy-cert-mismatch", Namespace: ns}
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidCertPolicyNN, gwNN, acceptedCond)
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidCertPolicyNN, gwNN, resolvedRefsCond)
+
 			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
 				h.ExpectedResponse{
 					Namespace: ns,
diff --git a/conformance/tests/backendtlspolicy.yaml b/conformance/tests/backendtlspolicy.yaml
index e048cc2e..6d0cab8e 100644
--- a/conformance/tests/backendtlspolicy.yaml
+++ b/conformance/tests/backendtlspolicy.yaml
@@ -1,37 +1,4 @@
 apiVersion: gateway.networking.k8s.io/v1
-kind: Gateway
-metadata:
-  name: gateway-backendtlspolicy
-  namespace: gateway-conformance-infra
-spec:
-  gatewayClassName: "{GATEWAY_CLASS_NAME}"
-  listeners:
-  - name: http
-    port: 80
-    protocol: HTTP
-    hostname: "abc.example.com"
-    allowedRoutes:
-      namespaces:
-        from: Same
-      kinds:
-      - kind: HTTPRoute
-  - name: https
-    port: 443
-    protocol: HTTPS
-    tls:
-      mode: Terminate
-      certificateRefs:
-      - group: ""
-        kind: Secret
-        name: tls-checks-certificate
-    hostname: "abc.example.com"
-    allowedRoutes:
-      namespaces:
-        from: Same
-      kinds:
-      - kind: HTTPRoute
----
-apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
   name: gateway-conformance-infra-test
diff --git a/conformance/tests/cors-allow-credentials-behavior.go b/conformance/tests/cors-allow-credentials-behavior.go
new file mode 100644
index 00000000..391b3cee
--- /dev/null
+++ b/conformance/tests/cors-allow-credentials-behavior.go
@@ -0,0 +1,100 @@
+/*
+Copyright 2025 The Kubernetes 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 tests
+
+import (
+	"testing"
+
+	"k8s.io/apimachinery/pkg/types"
+
+	"sigs.k8s.io/gateway-api/conformance/utils/http"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+)
+
+func init() {
+	ConformanceTests = append(ConformanceTests, CORSAllowCredentialsBehavior)
+}
+
+var CORSAllowCredentialsBehavior = suite.ConformanceTest{
+	ShortName:   "CORSAllowCredentialsBehavior",
+	Description: "Validate ACA-Credentials responses",
+	Manifests:   []string{"tests/cors-allow-credentials-behavior.yaml"},
+	Features: []features.FeatureName{
+		features.SupportGateway,
+		features.SupportHTTPRoute,
+		features.SupportHTTPRouteCORS,
+	},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		routeNN := types.NamespacedName{Name: "cors-allow-credentials", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+		gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
+
+		origin := "https://app.example"
+
+		testCases := []http.ExpectedResponse{
+			{
+				Request: http.Request{
+					Method: "GET",
+					Path:   "/cors-behavior-creds-false",
+					Headers: map[string]string{
+						"Origin":        origin,
+						"Cookie":        "sid=abc123",
+						"Authorization": "Bearer test",
+					},
+				},
+				Response: http.Response{
+					StatusCode:    200,
+					AbsentHeaders: []string{"Access-Control-Allow-Credentials"},
+				},
+				Namespace: ns,
+			},
+			{
+				Request: http.Request{
+					Method: "GET",
+					Path:   "/cors-behavior-creds-true",
+					Headers: map[string]string{
+						"Origin":        origin,
+						"Cookie":        "sid=abc123",
+						"Authorization": "Bearer test",
+					},
+				},
+				Response: http.Response{
+					StatusCode: 200,
+					Headers: map[string]string{
+						"Access-Control-Allow-Credentials": "true",
+						"Access-Control-Allow-Origin":      origin,
+					},
+				},
+				Namespace: ns,
+			},
+		}
+
+		for i := range testCases {
+			// Declare tc here to avoid loop variable
+			// reuse issues across parallel tests.
+			tc := testCases[i]
+			t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
+				t.Parallel()
+				http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc)
+			})
+		}
+	},
+}
diff --git a/conformance/tests/cors-allow-credentials-behavior.yaml b/conformance/tests/cors-allow-credentials-behavior.yaml
new file mode 100644
index 00000000..13992e28
--- /dev/null
+++ b/conformance/tests/cors-allow-credentials-behavior.yaml
@@ -0,0 +1,32 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: cors-allow-credentials
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+  - name: same-namespace
+  rules:
+  - matches:
+    - path:
+        type: PathPrefix
+        value: /cors-behavior-creds-false
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+    filters:
+    - cors:
+        allowCredentials: false
+      type: CORS
+  - matches:
+    - path:
+        type: PathPrefix
+        value: /cors-behavior-creds-true
+    backendRefs:
+    - name: infra-backend-v1
+      port: 8080
+    filters:
+    - cors:
+        allowCredentials: true
+      type: CORS
+