Repository: kubernetes-sigs/gateway-api

Issue:
GEP-3567: Gateway TLS Updates for HTTP Connection Coalescing
**What would you like to be added**:
As a follow up to the [doc](https://docs.google.com/document/d/1g_TNN8eOaVDC3xesO9JFdvQbPFdSTHp1vb70TD3-Vrs/edit?tab=t.0#heading=h.qiz1tfw67tbp) that's been discussed in previous community meetings, this GEP will propose the following changes:

1. Formalizing guidance for implementations to send HTTP 421 when we see mismatched requests
2. Adding Gateway API documentation that describes the problem and possible solutions
3. Adding a new status condition that will warn users when configuration with overlapping hostname configuration is present with a reference to the documentation created in step 2
4. Introduce new top-level TLS configuration, starting with client-cert validation

Although we will make every effort to get as many of these changes as possible into Gateway API v1.3, it's unlikely that all of them will fit into this release.

**Why this is needed**:
Our current TLS configuration can lead to confusing and inconsistent behavior across implementations. These problems are only made worse as we add client cert validation. This GEP aims to warn users about problematic configuration and provide a safer API surface.


Discussion:
@k8s-triage-robot: The Kubernetes project currently lacks enough contributors to adequately respond to all issues.

This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity, `lifecycle/stale` is applied
- After 30d of inactivity since `lifecycle/stale` was applied, `lifecycle/rotten` is applied
- After 30d of inactivity since `lifecycle/rotten` was applied, the issue is closed

You can:
- Mark this issue as fresh with `/remove-lifecycle stale`
- Close this issue with `/close`
- Offer to help out with [Issue Triage][1]

Please send feedback to sig-contributor-experience at [kubernetes/community](https://github.com/kubernetes/community).

/lifecycle stale

[1]: https://www.kubernetes.dev/docs/guide/issue-triage/@youngnick: /remove-lifecycle stale@kl52752: GEP https://github.com/kubernetes-sigs/gateway-api/pull/3838 is addressing point 4 in this GEP@PT-GD: I'm transcribing somethnig I posted in the [Istio Slack workspace](https://istio.slack.com/archives/C37A4KAAD/p1752241004933669?thread_ts=1752175467.513259&cid=C37A4KAAD) in the hopes that it resonates here:

> Solved my own problem: https://istio.io/latest/docs/ops/common-problems/network-issues/#404-errors-occur-when-multiple-gateways-configured-with-same-tls-certificate
> So: The issue is that a k8s gateway API listener has one and only one hostname which can either be an FQDN or a wildcard, however a wildcard certificate supports requests both to the apex as well as the subdomains. It feels like it'll be pretty common for people to create apex and wildcard listeners but use the same TLS certificate.
> I feel like I'm not the only person who's going to run into this. Maybe this situation needs to have a Kiali validation warning like "multiple listeners in a gateway with same TLS certificate" added?
> Even better would be having a way to make gateway listeners more closely match TLS wildcard certificate behavior, such that a wildcard listener also matched the apex.
> 

The behavior I'm referring is not Isio implementation-specific, but is inherent in the Gateway API listener definition. Is there a better way of handling this discrepancy between Gateway Listener hostnames [must be either an FQDN *or* a wildcard]  and wildcard certificate handling [a wildcard certificate supports both the apex and hosts one label below the apex].

Solution patch:
diff --git a/apis/v1/gateway_types.go b/apis/v1/gateway_types.go
index 86de1bad..fdb31043 100644
--- a/apis/v1/gateway_types.go
+++ b/apis/v1/gateway_types.go
@@ -295,6 +295,14 @@ type GatewaySpec struct {
 	//
 	// +optional
 	AllowedListeners *AllowedListeners `json:"allowedListeners,omitempty"`
+	//
+	// GatewayTLSConfig specifies frontend tls configuration for gateway.
+	//
+	// Support: Extended
+	//
+	// +optional
+	// <gateway:experimental>
+	TLS *GatewayTLSConfig `json:"tls,omitempty"`
 }
 
 // AllowedListeners defines which ListenerSets can be attached to this Gateway.
@@ -414,7 +422,7 @@ type Listener struct {
 	// the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
 	// if the Protocol field is "HTTP", "TCP", or "UDP".
 	//
-	// The association of SNIs to Certificate defined in GatewayTLSConfig is
+	// The association of SNIs to Certificate defined in ListenerTLSConfig is
 	// defined based on the Hostname field for this listener.
 	//
 	// The GatewayClass MUST use the longest matching SNI out of all
@@ -423,7 +431,7 @@ type Listener struct {
 	// Support: Core
 	//
 	// +optional
-	TLS *GatewayTLSConfig `json:"tls,omitempty"`
+	TLS *ListenerTLSConfig `json:"tls,omitempty"`
 
 	// AllowedRoutes defines the types of routes that MAY be attached to a
 	// Listener and the trusted namespaces where those Route resources MAY be
@@ -526,10 +534,10 @@ type GatewayBackendTLS struct {
 	ClientCertificateRef *SecretObjectReference `json:"clientCertificateRef,omitempty"`
 }
 
-// GatewayTLSConfig describes a TLS configuration.
+// ListenerTLSConfig describes a TLS configuration for a listener.
 //
 // +kubebuilder:validation:XValidation:message="certificateRefs or options must be specified when mode is Terminate",rule="self.mode == 'Terminate' ? size(self.certificateRefs) > 0 || size(self.options) > 0 : true"
-type GatewayTLSConfig struct {
+type ListenerTLSConfig struct {
 	// Mode defines the TLS behavior for the TLS session initiated by the client.
 	// There are two possible modes:
 	//
@@ -578,18 +586,6 @@ type GatewayTLSConfig struct {
 	// +kubebuilder:validation:MaxItems=64
 	CertificateRefs []SecretObjectReference `json:"certificateRefs,omitempty"`
 
-	// FrontendValidation holds configuration information for validating the frontend (client).
-	// Setting this field will require clients to send a client certificate
-	// required for validation during the TLS handshake. 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: Extended
-	//
-	// +optional
-	// <gateway:experimental>
-	FrontendValidation *FrontendTLSValidation `json:"frontendValidation,omitempty"`
-
 	// Options are a list of key/value pairs to enable extended TLS
 	// configuration for each implementation. For example, configuring the
 	// minimum TLS version or supported cipher suites.
@@ -606,6 +602,35 @@ type GatewayTLSConfig struct {
 	Options map[AnnotationKey]AnnotationValue `json:"options,omitempty"`
 }
 
+// GatewayTLSConfig specifies frontend tls configuration for gateway.
+type GatewayTLSConfig struct {
+	// Default specifies the default client certificate validation configuration
+	// for all Listeners handling HTTPS traffic, unless a per-port configuration
+	// is defined.
+	//
+	// support: Core
+	//
+	// +required
+	// <gateway:experimental>
+	Default TLSConfig `json:"default"`
+
+	// 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
+	//
+	// +optional
+	// +listType=map
+	// +listMapKey=port
+	// +kubebuilder:validation:MaxItems=64
+	// +kubebuilder:validation:XValidation:message="Port for TLS configuration must be unique within the Gateway",rule="self.all(t1, self.exists_one(t2, t1.port == t2.port))"
+	// <gateway:experimental>
+	PerPort []TLSPortConfig `json:"perPort,omitempty"`
+}
+
 // TLSModeType type defines how a Gateway handles TLS sessions.
 //
 // +kubebuilder:validation:Enum=Terminate;Passthrough
@@ -624,6 +649,46 @@ const (
 	TLSModePassthrough TLSModeType = "Passthrough"
 )
 
+// 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 TLSConfig struct {
+	// 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
+	//
+	// +required
+	// <gateway:experimental>
+	FrontendValidation FrontendTLSValidation `json:"frontendValidation"`
+}
+
+type TLSPortConfig struct {
+	// 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
+	//
+	// +required
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
+	// <gateway:experimental>
+	Port PortNumber `json:"port"`
+
+	// TLS store the configuration that will be applied to all Listeners handling
+	// HTTPS traffic and matching given port.
+	//
+	// Support: Core
+	//
+	// +required
+	// <gateway:experimental>
+	TLS TLSConfig `json:"tls"`
+}
+
 // FrontendTLSValidation holds configuration information that can be used to validate
 // the frontend initiating the TLS connection
 type FrontendTLSValidation struct {
@@ -640,8 +705,8 @@ type FrontendTLSValidation struct {
 	// 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 reference, or other kinds
-	// of resources).
+	// 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
@@ -653,9 +718,49 @@ type FrontendTLSValidation struct {
 	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=8
 	// +kubebuilder:validation:MinItems=1
-	CACertificateRefs []ObjectReference `json:"caCertificateRefs,omitempty"`
+	CACertificateRefs []ObjectReference `json:"caCertificateRefs"`
+
+	// 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
+	//
+	// +optional
+	// +kubebuilder:default=AllowValidOnly
+	Mode FrontendValidationModeType `json:"mode,omitempty"`
 }
 
+// FrontendValidationModeType type defines how a Gateway validates client certificates.
+//
+// +kubebuilder:validation:Enum=AllowValidOnly;AllowInsecureFallback
+type FrontendValidationModeType string
+
+const (
+	// AllowValidOnly indicates that a client certificate is required
+	// during the TLS handshake and MUST pass validation.
+	//
+	// Support: Core
+	AllowValidOnly FrontendValidationModeType = "AllowValidOnly"
+
+	// AllowInsecureFallback indicates that a client certificate may not be
+	// presented during the handshake or the validation against CA certificates may fail.
+	//
+	// Support: Extended
+	AllowInsecureFallback FrontendValidationModeType = "AllowInsecureFallback"
+)
+
 // AllowedRoutes defines which Routes may be attached to this Listener.
 type AllowedRoutes struct {
 	// Namespaces indicates namespaces from which Routes may be attached to this
@@ -993,6 +1098,13 @@ const (
 	// information on which address is causing the problem and how to resolve it
 	// in the condition message.
 	GatewayReasonAddressNotUsable GatewayConditionReason = "AddressNotUsable"
+	// This condition indicates `FrontendValidationModeType` changed from
+	// `AllowValidOnly` to `AllowInsecureFallback`.
+	GatewayConditionInsecureFrontendValidationMode GatewayConditionReason = "InsecureFrontendValidationMode"
+	// This reason MUST be set for GatewayConditionInsecureFrontendValidationMode
+	// when client change FrontendValidationModeType for a Gateway or per port override
+	// to `AllowInsecureFallback`.
+	GatewayReasonConfigurationChanged GatewayConditionReason = "ConfigurationChanged"
 )
 
 const (
diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go
index 9bc1c8c5..d7e4a6c2 100644
--- a/apis/v1/zz_generated.deepcopy.go
+++ b/apis/v1/zz_generated.deepcopy.go
@@ -752,6 +752,11 @@ func (in *GatewaySpec) DeepCopyInto(out *GatewaySpec) {
 		*out = new(AllowedListeners)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.TLS != nil {
+		in, out := &in.TLS, &out.TLS
+		*out = new(GatewayTLSConfig)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewaySpec.
@@ -843,30 +848,14 @@ 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
-	if in.Mode != nil {
-		in, out := &in.Mode, &out.Mode
-		*out = new(TLSModeType)
-		**out = **in
-	}
-	if in.CertificateRefs != nil {
-		in, out := &in.CertificateRefs, &out.CertificateRefs
-		*out = make([]SecretObjectReference, len(*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.FrontendValidation != nil {
-		in, out := &in.FrontendValidation, &out.FrontendValidation
-		*out = new(FrontendTLSValidation)
-		(*in).DeepCopyInto(*out)
-	}
-	if in.Options != nil {
-		in, out := &in.Options, &out.Options
-		*out = make(map[AnnotationKey]AnnotationValue, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayTLSConfig.
@@ -1481,7 +1470,7 @@ func (in *Listener) DeepCopyInto(out *Listener) {
 	}
 	if in.TLS != nil {
 		in, out := &in.TLS, &out.TLS
-		*out = new(GatewayTLSConfig)
+		*out = new(ListenerTLSConfig)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.AllowedRoutes != nil {
@@ -1555,6 +1544,40 @@ func (in *ListenerStatus) DeepCopy() *ListenerStatus {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ListenerTLSConfig) DeepCopyInto(out *ListenerTLSConfig) {
+	*out = *in
+	if in.Mode != nil {
+		in, out := &in.Mode, &out.Mode
+		*out = new(TLSModeType)
+		**out = **in
+	}
+	if in.CertificateRefs != nil {
+		in, out := &in.CertificateRefs, &out.CertificateRefs
+		*out = make([]SecretObjectReference, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	if in.Options != nil {
+		in, out := &in.Options, &out.Options
+		*out = make(map[AnnotationKey]AnnotationValue, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListenerTLSConfig.
+func (in *ListenerTLSConfig) DeepCopy() *ListenerTLSConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(ListenerTLSConfig)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *LocalObjectReference) DeepCopyInto(out *LocalObjectReference) {
 	*out = *in
@@ -1839,3 +1862,35 @@ func (in *SupportedFeature) DeepCopy() *SupportedFeature {
 	in.DeepCopyInto(out)
 	return out
 }
+
+// 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)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSConfig.
+func (in *TLSConfig) DeepCopy() *TLSConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(TLSConfig)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *TLSPortConfig) DeepCopyInto(out *TLSPortConfig) {
+	*out = *in
+	in.TLS.DeepCopyInto(&out.TLS)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSPortConfig.
+func (in *TLSPortConfig) DeepCopy() *TLSPortConfig {
+	if in == nil {
+		return nil
+	}
+	out := new(TLSPortConfig)
+	in.DeepCopyInto(out)
+	return out
+}
diff --git a/apis/v1beta1/gateway_types.go b/apis/v1beta1/gateway_types.go
index 1998c2ac..60bac20c 100644
--- a/apis/v1beta1/gateway_types.go
+++ b/apis/v1beta1/gateway_types.go
@@ -88,9 +88,9 @@ type Listener = v1.Listener
 // +k8s:deepcopy-gen=false
 type ProtocolType = v1.ProtocolType
 
-// GatewayTLSConfig describes a TLS configuration.
+// ListenerTLSConfig describes a TLS configuration.
 // +k8s:deepcopy-gen=false
-type GatewayTLSConfig = v1.GatewayTLSConfig
+type ListenerTLSConfig = v1.ListenerTLSConfig
 
 // TLSModeType type defines how a Gateway handles TLS sessions.
 //
diff --git a/apisx/v1alpha1/shared_types.go b/apisx/v1alpha1/shared_types.go
index 441d4758..848ff53b 100644
--- a/apisx/v1alpha1/shared_types.go
+++ b/apisx/v1alpha1/shared_types.go
@@ -25,7 +25,7 @@ type (
 	// +k8s:deepcopy-gen=false
 	AllowedRoutes = v1.AllowedRoutes
 	// +k8s:deepcopy-gen=false
-	GatewayTLSConfig = v1.GatewayTLSConfig
+	ListenerTLSConfig = v1.ListenerTLSConfig
 	// +k8s:deepcopy-gen=false
 	Group = v1.Group
 	// +k8s:deepcopy-gen=false
diff --git a/apisx/v1alpha1/xlistenerset_types.go b/apisx/v1alpha1/xlistenerset_types.go
index fd108e2b..f8198c86 100644
--- a/apisx/v1alpha1/xlistenerset_types.go
+++ b/apisx/v1alpha1/xlistenerset_types.go
@@ -179,14 +179,14 @@ type ListenerEntry struct {
 	// the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
 	// if the Protocol field is "HTTP", "TCP", or "UDP".
 	//
-	// The association of SNIs to Certificate defined in GatewayTLSConfig is
+	// The association of SNIs to Certificate defined in ListenerTLSConfig is
 	// defined based on the Hostname field for this listener.
 	//
 	// The GatewayClass MUST use the longest matching SNI out of all
 	// available certificates for any TLS handshake.
 	//
 	// +optional
-	TLS *GatewayTLSConfig `json:"tls,omitempty"`
+	TLS *ListenerTLSConfig `json:"tls,omitempty"`
 
 	// AllowedRoutes defines the types of routes that MAY be attached to a
 	// Listener and the trusted namespaces where those Route resources MAY be
diff --git a/apisx/v1alpha1/zz_generated.deepcopy.go b/apisx/v1alpha1/zz_generated.deepcopy.go
index bd534869..802d3719 100644
--- a/apisx/v1alpha1/zz_generated.deepcopy.go
+++ b/apisx/v1alpha1/zz_generated.deepcopy.go
@@ -92,7 +92,7 @@ func (in *ListenerEntry) DeepCopyInto(out *ListenerEntry) {
 	}
 	if in.TLS != nil {
 		in, out := &in.TLS, &out.TLS
-		*out = new(GatewayTLSConfig)
+		*out = new(ListenerTLSConfig)
 		(*in).DeepCopyInto(*out)
 	}
 	if in.AllowedRoutes != nil {
diff --git a/applyconfiguration/apis/v1/frontendtlsvalidation.go b/applyconfiguration/apis/v1/frontendtlsvalidation.go
index 5342400c..fada2ba1 100644
--- a/applyconfiguration/apis/v1/frontendtlsvalidation.go
+++ b/applyconfiguration/apis/v1/frontendtlsvalidation.go
@@ -18,10 +18,15 @@ limitations under the License.
 
 package v1
 
+import (
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
 // FrontendTLSValidationApplyConfiguration represents a declarative configuration of the FrontendTLSValidation type for use
 // with apply.
 type FrontendTLSValidationApplyConfiguration struct {
 	CACertificateRefs []ObjectReferenceApplyConfiguration `json:"caCertificateRefs,omitempty"`
+	Mode              *apisv1.FrontendValidationModeType  `json:"mode,omitempty"`
 }
 
 // FrontendTLSValidationApplyConfiguration constructs a declarative configuration of the FrontendTLSValidation type for use with
@@ -42,3 +47,11 @@ func (b *FrontendTLSValidationApplyConfiguration) WithCACertificateRefs(values .
 	}
 	return b
 }
+
+// WithMode sets the Mode 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 Mode field is set to the value of the last call.
+func (b *FrontendTLSValidationApplyConfiguration) WithMode(value apisv1.FrontendValidationModeType) *FrontendTLSValidationApplyConfiguration {
+	b.Mode = &value
+	return b
+}
diff --git a/applyconfiguration/apis/v1/gatewayspec.go b/applyconfiguration/apis/v1/gatewayspec.go
index bdfeba84..b123a40f 100644
--- a/applyconfiguration/apis/v1/gatewayspec.go
+++ b/applyconfiguration/apis/v1/gatewayspec.go
@@ -31,6 +31,7 @@ type GatewaySpecApplyConfiguration struct {
 	Infrastructure   *GatewayInfrastructureApplyConfiguration `json:"infrastructure,omitempty"`
 	BackendTLS       *GatewayBackendTLSApplyConfiguration     `json:"backendTLS,omitempty"`
 	AllowedListeners *AllowedListenersApplyConfiguration      `json:"allowedListeners,omitempty"`
+	TLS              *GatewayTLSConfigApplyConfiguration      `json:"tls,omitempty"`
 }
 
 // GatewaySpecApplyConfiguration constructs a declarative configuration of the GatewaySpec type for use with
@@ -96,3 +97,11 @@ func (b *GatewaySpecApplyConfiguration) WithAllowedListeners(value *AllowedListe
 	b.AllowedListeners = value
 	return b
 }
+
+// WithTLS sets the TLS 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 TLS field is set to the value of the last call.
+func (b *GatewaySpecApplyConfiguration) WithTLS(value *GatewayTLSConfigApplyConfiguration) *GatewaySpecApplyConfiguration {
+	b.TLS = value
+	return b
+}
diff --git a/applyconfiguration/apis/v1/gatewaytlsconfig.go b/applyconfiguration/apis/v1/gatewaytlsconfig.go
index 896e3e56..dbd3f443 100644
--- a/applyconfiguration/apis/v1/gatewaytlsconfig.go
+++ b/applyconfiguration/apis/v1/gatewaytlsconfig.go
@@ -18,17 +18,11 @@ limitations under the License.
 
 package v1
 
-import (
-	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
-)
-
 // GatewayTLSConfigApplyConfiguration represents a declarative configuration of the GatewayTLSConfig type for use
 // with apply.
 type GatewayTLSConfigApplyConfiguration struct {
-	Mode               *apisv1.TLSModeType                             `json:"mode,omitempty"`
-	CertificateRefs    []SecretObjectReferenceApplyConfiguration       `json:"certificateRefs,omitempty"`
-	FrontendValidation *FrontendTLSValidationApplyConfiguration        `json:"frontendValidation,omitempty"`
-	Options            map[apisv1.AnnotationKey]apisv1.AnnotationValue `json:"options,omitempty"`
+	Default *TLSConfigApplyConfiguration      `json:"default,omitempty"`
+	PerPort []TLSPortConfigApplyConfiguration `json:"perPort,omitempty"`
 }
 
 // GatewayTLSConfigApplyConfiguration constructs a declarative configuration of the GatewayTLSConfig type for use with
@@ -37,45 +31,23 @@ func GatewayTLSConfig() *GatewayTLSConfigApplyConfiguration {
 	return &GatewayTLSConfigApplyConfiguration{}
 }
 
-// WithMode sets the Mode field in the declarative configuration to the given value
+// 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 Mode field is set to the value of the last call.
-func (b *GatewayTLSConfigApplyConfiguration) WithMode(value apisv1.TLSModeType) *GatewayTLSConfigApplyConfiguration {
-	b.Mode = &value
+// 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
 	return b
 }
 
-// WithCertificateRefs adds the given value to the CertificateRefs field in the declarative configuration
+// 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 CertificateRefs field.
-func (b *GatewayTLSConfigApplyConfiguration) WithCertificateRefs(values ...*SecretObjectReferenceApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
+// 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 WithCertificateRefs")
+			panic("nil value passed to WithPerPort")
 		}
-		b.CertificateRefs = append(b.CertificateRefs, *values[i])
-	}
-	return b
-}
-
-// WithFrontendValidation sets the FrontendValidation 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 *GatewayTLSConfigApplyConfiguration) WithFrontendValidation(value *FrontendTLSValidationApplyConfiguration) *GatewayTLSConfigApplyConfiguration {
-	b.FrontendValidation = value
-	return b
-}
-
-// WithOptions puts the entries into the Options field in the declarative configuration
-// and returns the receiver, so that objects can be build by chaining "With" function invocations.
-// If called multiple times, the entries provided by each call will be put on the Options field,
-// overwriting an existing map entries in Options field with the same key.
-func (b *GatewayTLSConfigApplyConfiguration) WithOptions(entries map[apisv1.AnnotationKey]apisv1.AnnotationValue) *GatewayTLSConfigApplyConfiguration {
-	if b.Options == nil && len(entries) > 0 {
-		b.Options = make(map[apisv1.AnnotationKey]apisv1.AnnotationValue, len(entries))
-	}
-	for k, v := range entries {
-		b.Options[k] = v
+		b.PerPort = append(b.PerPort, *values[i])
 	}
 	return b
 }
diff --git a/applyconfiguration/apis/v1/listener.go b/applyconfiguration/apis/v1/listener.go
index 35be06a7..c7d3b080 100644
--- a/applyconfiguration/apis/v1/listener.go
+++ b/applyconfiguration/apis/v1/listener.go
@@ -25,12 +25,12 @@ import (
 // ListenerApplyConfiguration represents a declarative configuration of the Listener type for use
 // with apply.
 type ListenerApplyConfiguration struct {
-	Name          *apisv1.SectionName                 `json:"name,omitempty"`
-	Hostname      *apisv1.Hostname                    `json:"hostname,omitempty"`
-	Port          *apisv1.PortNumber                  `json:"port,omitempty"`
-	Protocol      *apisv1.ProtocolType                `json:"protocol,omitempty"`
-	TLS           *GatewayTLSConfigApplyConfiguration `json:"tls,omitempty"`
-	AllowedRoutes *AllowedRoutesApplyConfiguration    `json:"allowedRoutes,omitempty"`
+	Name          *apisv1.SectionName                  `json:"name,omitempty"`
+	Hostname      *apisv1.Hostname                     `json:"hostname,omitempty"`
+	Port          *apisv1.PortNumber                   `json:"port,omitempty"`
+	Protocol      *apisv1.ProtocolType                 `json:"protocol,omitempty"`
+	TLS           *ListenerTLSConfigApplyConfiguration `json:"tls,omitempty"`
+	AllowedRoutes *AllowedRoutesApplyConfiguration     `json:"allowedRoutes,omitempty"`
 }
 
 // ListenerApplyConfiguration constructs a declarative configuration of the Listener type for use with
@@ -74,7 +74,7 @@ func (b *ListenerApplyConfiguration) WithProtocol(value apisv1.ProtocolType) *Li
 // WithTLS sets the TLS 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 TLS field is set to the value of the last call.
-func (b *ListenerApplyConfiguration) WithTLS(value *GatewayTLSConfigApplyConfiguration) *ListenerApplyConfiguration {
+func (b *ListenerApplyConfiguration) WithTLS(value *ListenerTLSConfigApplyConfiguration) *ListenerApplyConfiguration {
 	b.TLS = value
 	return b
 }
diff --git a/applyconfiguration/apis/v1/listenertlsconfig.go b/applyconfiguration/apis/v1/listenertlsconfig.go
new file mode 100644
index 00000000..6ab72f15
--- /dev/null
+++ b/applyconfiguration/apis/v1/listenertlsconfig.go
@@ -0,0 +1,72 @@
+/*
+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
+
+import (
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+// ListenerTLSConfigApplyConfiguration represents a declarative configuration of the ListenerTLSConfig type for use
+// with apply.
+type ListenerTLSConfigApplyConfiguration struct {
+	Mode            *apisv1.TLSModeType                             `json:"mode,omitempty"`
+	CertificateRefs []SecretObjectReferenceApplyConfiguration       `json:"certificateRefs,omitempty"`
+	Options         map[apisv1.AnnotationKey]apisv1.AnnotationValue `json:"options,omitempty"`
+}
+
+// ListenerTLSConfigApplyConfiguration constructs a declarative configuration of the ListenerTLSConfig type for use with
+// apply.
+func ListenerTLSConfig() *ListenerTLSConfigApplyConfiguration {
+	return &ListenerTLSConfigApplyConfiguration{}
+}
+
+// WithMode sets the Mode 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 Mode field is set to the value of the last call.
+func (b *ListenerTLSConfigApplyConfiguration) WithMode(value apisv1.TLSModeType) *ListenerTLSConfigApplyConfiguration {
+	b.Mode = &value
+	return b
+}
+
+// WithCertificateRefs adds the given value to the CertificateRefs 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 CertificateRefs field.
+func (b *ListenerTLSConfigApplyConfiguration) WithCertificateRefs(values ...*SecretObjectReferenceApplyConfiguration) *ListenerTLSConfigApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithCertificateRefs")
+		}
+		b.CertificateRefs = append(b.CertificateRefs, *values[i])
+	}
+	return b
+}
+
+// WithOptions puts the entries into the Options field in the declarative configuration
+// and returns the receiver, so that objects can be build by chaining "With" function invocations.
+// If called multiple times, the entries provided by each call will be put on the Options field,
+// overwriting an existing map entries in Options field with the same key.
+func (b *ListenerTLSConfigApplyConfiguration) WithOptions(entries map[apisv1.AnnotationKey]apisv1.AnnotationValue) *ListenerTLSConfigApplyConfiguration {
+	if b.Options == nil && len(entries) > 0 {
+		b.Options = make(map[apisv1.AnnotationKey]apisv1.AnnotationValue, len(entries))
+	}
+	for k, v := range entries {
+		b.Options[k] = v
+	}
+	return b
+}
diff --git a/applyconfiguration/apis/v1/tlsconfig.go b/applyconfiguration/apis/v1/tlsconfig.go
new file mode 100644
index 00000000..1dfa5e02
--- /dev/null
+++ b/applyconfiguration/apis/v1/tlsconfig.go
@@ -0,0 +1,39 @@
+/*
+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
+
+// TLSConfigApplyConfiguration represents a declarative configuration of the TLSConfig type for use
+// with apply.
+type TLSConfigApplyConfiguration struct {
+	FrontendValidation *FrontendTLSValidationApplyConfiguration `json:"frontendValidation,omitempty"`
+}
+
+// TLSConfigApplyConfiguration constructs a declarative configuration of the TLSConfig type for use with
+// apply.
+func TLSConfig() *TLSConfigApplyConfiguration {
+	return &TLSConfigApplyConfiguration{}
+}
+
+// WithFrontendValidation sets the FrontendValidation 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
+	return b
+}
diff --git a/applyconfiguration/apis/v1/tlsportconfig.go b/applyconfiguration/apis/v1/tlsportconfig.go
new file mode 100644
index 00000000..bc9043a1
--- /dev/null
+++ b/applyconfiguration/apis/v1/tlsportconfig.go
@@ -0,0 +1,52 @@
+/*
+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
+
+import (
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+// TLSPortConfigApplyConfiguration represents a declarative configuration of the TLSPortConfig type for use
+// with apply.
+type TLSPortConfigApplyConfiguration struct {
+	Port *apisv1.PortNumber           `json:"port,omitempty"`
+	TLS  *TLSConfigApplyConfiguration `json:"tls,omitempty"`
+}
+
+// TLSPortConfigApplyConfiguration constructs a declarative configuration of the TLSPortConfig type for use with
+// apply.
+func TLSPortConfig() *TLSPortConfigApplyConfiguration {
+	return &TLSPortConfigApplyConfiguration{}
+}
+
+// WithPort sets the Port 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 Port field is set to the value of the last call.
+func (b *TLSPortConfigApplyConfiguration) WithPort(value apisv1.PortNumber) *TLSPortConfigApplyConfiguration {
+	b.Port = &value
+	return b
+}
+
+// WithTLS sets the TLS 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 TLS field is set to the value of the last call.
+func (b *TLSPortConfigApplyConfiguration) WithTLS(value *TLSConfigApplyConfiguration) *TLSPortConfigApplyConfiguration {
+	b.TLS = value
+	return b
+}
diff --git a/applyconfiguration/apisx/v1alpha1/listenerentry.go b/applyconfiguration/apisx/v1alpha1/listenerentry.go
index e6396bf1..b72cf4e0 100644
--- a/applyconfiguration/apisx/v1alpha1/listenerentry.go
+++ b/applyconfiguration/apisx/v1alpha1/listenerentry.go
@@ -26,12 +26,12 @@ import (
 // ListenerEntryApplyConfiguration represents a declarative configuration of the ListenerEntry type for use
 // with apply.
 type ListenerEntryApplyConfiguration struct {
-	Name          *v1.SectionName                            `json:"name,omitempty"`
-	Hostname      *v1.Hostname                               `json:"hostname,omitempty"`
-	Port          *v1.PortNumber                             `json:"port,omitempty"`
-	Protocol      *v1.ProtocolType                           `json:"protocol,omitempty"`
-	TLS           *apisv1.GatewayTLSConfigApplyConfiguration `json:"tls,omitempty"`
-	AllowedRoutes *apisv1.AllowedRoutesApplyConfiguration    `json:"allowedRoutes,omitempty"`
+	Name          *v1.SectionName                             `json:"name,omitempty"`
+	Hostname      *v1.Hostname                                `json:"hostname,omitempty"`
+	Port          *v1.PortNumber                              `json:"port,omitempty"`
+	Protocol      *v1.ProtocolType                            `json:"protocol,omitempty"`
+	TLS           *apisv1.ListenerTLSConfigApplyConfiguration `json:"tls,omitempty"`
+	AllowedRoutes *apisv1.AllowedRoutesApplyConfiguration     `json:"allowedRoutes,omitempty"`
 }
 
 // ListenerEntryApplyConfiguration constructs a declarative configuration of the ListenerEntry type for use with
@@ -75,7 +75,7 @@ func (b *ListenerEntryApplyConfiguration) WithProtocol(value v1.ProtocolType) *L
 // WithTLS sets the TLS 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 TLS field is set to the value of the last call.
-func (b *ListenerEntryApplyConfiguration) WithTLS(value *apisv1.GatewayTLSConfigApplyConfiguration) *ListenerEntryApplyConfiguration {
+func (b *ListenerEntryApplyConfiguration) WithTLS(value *apisv1.ListenerTLSConfigApplyConfiguration) *ListenerEntryApplyConfiguration {
 	b.TLS = value
 	return b
 }
diff --git a/applyconfiguration/internal/internal.go b/applyconfiguration/internal/internal.go
index 92508d3a..f7108040 100644
--- a/applyconfiguration/internal/internal.go
+++ b/applyconfiguration/internal/internal.go
@@ -307,6 +307,9 @@ var schemaYAML = typed.YAMLObject(`types:
           elementType:
             namedType: io.k8s.sigs.gateway-api.apis.v1.ObjectReference
           elementRelationship: atomic
+    - name: mode
+      type:
+        scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1.GRPCBackendRef
   map:
     fields:
@@ -598,6 +601,9 @@ var schemaYAML = typed.YAMLObject(`types:
           elementRelationship: associative
           keys:
           - name
+    - name: tls
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayTLSConfig
 - name: io.k8s.sigs.gateway-api.apis.v1.GatewaySpecAddress
   map:
     fields:
@@ -645,23 +651,18 @@ var schemaYAML = typed.YAMLObject(`types:
 - name: io.k8s.sigs.gateway-api.apis.v1.GatewayTLSConfig
   map:
     fields:
-    - name: certificateRefs
+    - name: default
       type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1.SecretObjectReference
-          elementRelationship: atomic
-    - name: frontendValidation
-      type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSValidation
-    - name: mode
-      type:
-        scalar: string
-    - name: options
+        namedType: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
+      default: {}
+    - name: perPort
       type:
-        map:
+        list:
           elementType:
-            scalar: string
+            namedType: io.k8s.sigs.gateway-api.apis.v1.TLSPortConfig
+          elementRelationship: associative
+          keys:
+          - port
 - name: io.k8s.sigs.gateway-api.apis.v1.HTTPBackendRef
   map:
     fields:
@@ -1033,7 +1034,7 @@ var schemaYAML = typed.YAMLObject(`types:
       default: ""
     - name: tls
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayTLSConfig
+        namedType: io.k8s.sigs.gateway-api.apis.v1.ListenerTLSConfig
 - name: io.k8s.sigs.gateway-api.apis.v1.ListenerNamespaces
   map:
     fields:
@@ -1068,6 +1069,23 @@ var schemaYAML = typed.YAMLObject(`types:
           elementType:
             namedType: io.k8s.sigs.gateway-api.apis.v1.RouteGroupKind
           elementRelationship: atomic
+- name: io.k8s.sigs.gateway-api.apis.v1.ListenerTLSConfig
+  map:
+    fields:
+    - name: certificateRefs
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.SecretObjectReference
+          elementRelationship: atomic
+    - name: mode
+      type:
+        scalar: string
+    - name: options
+      type:
+        map:
+          elementType:
+            scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1.LocalObjectReference
   map:
     fields:
@@ -1235,6 +1253,24 @@ var schemaYAML = typed.YAMLObject(`types:
       type:
         scalar: string
       default: ""
+- name: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
+  map:
+    fields:
+    - name: frontendValidation
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.FrontendTLSValidation
+      default: {}
+- name: io.k8s.sigs.gateway-api.apis.v1.TLSPortConfig
+  map:
+    fields:
+    - name: port
+      type:
+        scalar: numeric
+      default: 0
+    - name: tls
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.TLSConfig
+      default: {}
 - name: io.k8s.sigs.gateway-api.apis.v1alpha2.GRPCRoute
   map:
     fields:
@@ -1801,7 +1837,7 @@ var schemaYAML = typed.YAMLObject(`types:
       default: ""
     - name: tls
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.GatewayTLSConfig
+        namedType: io.k8s.sigs.gateway-api.apis.v1.ListenerTLSConfig
 - name: io.k8s.sigs.gateway-api.apisx.v1alpha1.ListenerEntryStatus
   map:
     fields:
diff --git a/applyconfiguration/utils.go b/applyconfiguration/utils.go
index 8014f68c..71851d89 100644
--- a/applyconfiguration/utils.go
+++ b/applyconfiguration/utils.go
@@ -140,6 +140,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.ListenerNamespacesApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("ListenerStatus"):
 		return &apisv1.ListenerStatusApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("ListenerTLSConfig"):
+		return &apisv1.ListenerTLSConfigApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("LocalObjectReference"):
 		return &apisv1.LocalObjectReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("LocalParametersReference"):
@@ -164,6 +166,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.SessionPersistenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("SupportedFeature"):
 		return &apisv1.SupportedFeatureApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("TLSConfig"):
+		return &apisv1.TLSConfigApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("TLSPortConfig"):
+		return &apisv1.TLSPortConfigApplyConfiguration{}
 
 		// Group=gateway.networking.k8s.io, Version=v1alpha2
 	case v1alpha2.SchemeGroupVersion.WithKind("GRPCRoute"):
diff --git a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
index 2e2462a0..f04f7b97 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
@@ -802,7 +802,7 @@ spec:
                         the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
                         if the Protocol field is "HTTP", "TCP", or "UDP".
 
-                        The association of SNIs to Certificate defined in GatewayTLSConfig is
+                        The association of SNIs to Certificate defined in ListenerTLSConfig is
                         defined based on the Hostname field for this listener.
 
                         The GatewayClass MUST use the longest matching SNI out of all
@@ -890,96 +890,6 @@ spec:
                           maxItems: 64
                           type: array
                           x-kubernetes-list-type: atomic
-                        frontendValidation:
-                          description: |-
-                            FrontendValidation holds configuration information for validating the frontend (client).
-                            Setting this field will require clients to send a client certificate
-                            required for validation during the TLS handshake. 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: Extended
-                          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 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
-                          required:
-                          - caCertificateRefs
-                          type: object
                         mode:
                           default: Terminate
                           description: |-
@@ -1058,6 +968,297 @@ spec:
                   rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol
                     == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname
                     == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
+              tls:
+                description: |-
+                  GatewayTLSConfig specifies frontend tls configuration for gateway.
+
+                  Support: Extended
+                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:
+                          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
+                    required:
+                    - frontendValidation
+                    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.
+
+                            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:
+                                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
+                          required:
+                          - frontendValidation
+                          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
+                type: object
             required:
             - gatewayClassName
             - listeners
@@ -2148,7 +2349,7 @@ spec:
                         the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
                         if the Protocol field is "HTTP", "TCP", or "UDP".
 
-                        The association of SNIs to Certificate defined in GatewayTLSConfig is
+                        The association of SNIs to Certificate defined in ListenerTLSConfig is
                         defined based on the Hostname field for this listener.
 
                         The GatewayClass MUST use the longest matching SNI out of all
@@ -2236,96 +2437,6 @@ spec:
                           maxItems: 64
                           type: array
                           x-kubernetes-list-type: atomic
-                        frontendValidation:
-                          description: |-
-                            FrontendValidation holds configuration information for validating the frontend (client).
-                            Setting this field will require clients to send a client certificate
-                            required for validation during the TLS handshake. 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: Extended
-                          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 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
-                          required:
-                          - caCertificateRefs
-                          type: object
                         mode:
                           default: Terminate
                           description: |-
@@ -2404,6 +2515,297 @@ spec:
                   rule: 'self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol
                     == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname
                     == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))'
+              tls:
+                description: |-
+                  GatewayTLSConfig specifies frontend tls configuration for gateway.
+
+                  Support: Extended
+                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:
+                          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
+                    required:
+                    - frontendValidation
+                    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.
+
+                            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:
+                                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
+                          required:
+                          - frontendValidation
+                          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
+                type: object
             required:
             - gatewayClassName
             - listeners
diff --git a/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml b/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
index 1a266cca..6d5a5bd5 100644
--- a/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
+++ b/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
@@ -323,7 +323,7 @@ spec:
                         the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
                         if the Protocol field is "HTTP", "TCP", or "UDP".
 
-                        The association of SNIs to Certificate defined in GatewayTLSConfig is
+                        The association of SNIs to Certificate defined in ListenerTLSConfig is
                         defined based on the Hostname field for this listener.
 
                         The GatewayClass MUST use the longest matching SNI out of all
@@ -409,96 +409,6 @@ spec:
                           maxItems: 64
                           type: array
                           x-kubernetes-list-type: atomic
-                        frontendValidation:
-                          description: |-
-                            FrontendValidation holds configuration information for validating the frontend (client).
-                            Setting this field will require clients to send a client certificate
-                            required for validation during the TLS handshake. 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: Extended
-                          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 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
-                          required:
-                          - caCertificateRefs
-                          type: object
                         mode:
                           default: Terminate
                           description: |-
diff --git a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
index bcb64881..8b7b0a02 100644
--- a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
@@ -657,7 +657,7 @@ spec:
                         the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
                         if the Protocol field is "HTTP", "TCP", or "UDP".
 
-                        The association of SNIs to Certificate defined in GatewayTLSConfig is
+                        The association of SNIs to Certificate defined in ListenerTLSConfig is
                         defined based on the Hostname field for this listener.
 
                         The GatewayClass MUST use the longest matching SNI out of all
@@ -1768,7 +1768,7 @@ spec:
                         the Protocol field is "HTTPS" or "TLS". It is invalid to set this field
                         if the Protocol field is "HTTP", "TCP", or "UDP".
 
-                        The association of SNIs to Certificate defined in GatewayTLSConfig is
+                        The association of SNIs to Certificate defined in ListenerTLSConfig is
                         defined based on the Hostname field for this listener.
 
                         The GatewayClass MUST use the longest matching SNI out of all
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index 8075132d..1501d935 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -1026,3 +1026,15 @@ func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeo
 
 	require.NoErrorf(t, waitErr, "error waiting for BackendTLSPolicy status to have a Condition %v", condition)
 }
+
+// BackendTLSPolicyMustHaveLatestConditions will fail the test if there are
+// conditions that were not updated
+func BackendTLSPolicyMustHaveLatestConditions(t *testing.T, r *v1alpha3.BackendTLSPolicy) {
+	t.Helper()
+
+	for _, ancestor := range r.Status.Ancestors {
+		if err := ConditionsHaveLatestObservedGeneration(r, ancestor.Conditions); err != nil {
+			tlog.Fatalf(t, "BackendTLSPolicy(controller=%v, ancestorRef=%#v) %v", ancestor.ControllerName, parentRefToString(ancestor.AncestorRef), err)
+		}
+	}
+}
diff --git a/examples/experimental/frontend-cert-validation.yaml b/examples/experimental/frontend-cert-validation.yaml
index 7f103aed..a7a9d4a1 100644
--- a/examples/experimental/frontend-cert-validation.yaml
+++ b/examples/experimental/frontend-cert-validation.yaml
@@ -4,6 +4,13 @@ metadata:
   name: client-validation-basic
 spec:
   gatewayClassName: acme-lb
+  tls:
+    default:
+      frontendValidation:
+        caCertificateRefs:
+        - kind: ConfigMap
+          group: ""
+          name: foo-example-com-ca-cert
   listeners:
   - name: foo-https
     protocol: HTTPS
@@ -14,10 +21,5 @@ spec:
       - kind: Secret
         group: ""
         name: foo-example-com-cert
-      frontendValidation:
-        caCertificateRefs:
-        - kind: ConfigMap
-          group: ""
-          name: foo-example-com-ca-cert
 ---
 
diff --git a/geps/gep-91/index.md b/geps/gep-91/index.md
index 8eedb7bd..d71aef76 100644
--- a/geps/gep-91/index.md
+++ b/geps/gep-91/index.md
@@ -26,21 +26,28 @@ This use case has been highlighted in the [TLS Configuration GEP][] under segmen
 
 ### API
 
-* Introduce two new structs `TLSConfig` and `FrontendTLSValidation` allowing for the definition of certificate validation used to authenticate the peer (frontend) in a TLS connection. A new `tls` field, storing an array of `TLSConfigs`, will be added to the gateway object.
+* Introduce new structs: `GatewayTLSConfig`, `TLSConfig`, `TLSPortConfig`, `FrontendTLSValidation` allowing for the definition of certificate validation used to authenticate the peer (frontend) in a TLS connection. A new `tls` field with gateway tls configuration will be added to the gateway object.
+* `TLSConfig` will allow defining client certificate validation per port which will be applied to all Listeners matching this port. We might want to extend this struct with other tls configurations.
+* `TLSPortConfig` will allow defining client certificate validation per port which will be applied to all Listeners matching this port.
+* `GatewayTLSConfig` struct contains default and (optional) per port configuration. Default configuration will apply to all Listeners which are not matching per port override.
 * This new field is separate from the existing [BackendTLSPolicy][] configuration. [BackendTLSPolicy][] controls TLS certificate validation for connections *from* the Gateway to the backend service.
 This proposal adds the ability to validate the TLS certificate presented by the *client* connecting to the Gateway (the frontend).
 These two validation mechanisms operate independently and can be used simultaneously.
 * Introduce a `caCertificateRefs` field within `FrontendTLSValidation` that can be used to specify a list of CA Certificates that can be used as a trust anchor to validate the certificates presented by the client.
 * Add a new `FrontendValidationModeType` enum within `FrontendTLSValidation` indicating how gateway should validate client certificates. As for now we support following values but it might change in the future:
-  1) `AllowValidOnly`
-  2) `AllowInvalidOrMissingCert`
+  1) `AllowValidOnly` (Core Support)
+  2) `AllowInsecureFallback` (Extended Support)
+
+    `AllowInsecureFallback` mode indicates 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.
+    When `FrontendValidationModeType` is changed from `AllowValidOnly` to `AllowInsecureFallback` the `InsecureFrontendValidationMode` condition MUST be set to `True` with Reason `ConfigurationChanged` on gateway.
 * Introduce a `ObjectReference` structure that can be used to specify `caCertificateRefs` references.
-* Introduce a `tls` field within the Gateway Spec to allow for a common TLS configuration to apply across all listeners.
 
 ### Impact on listeners
 
 This proposal removes frontendTLSValidation from Listener's TLS configuration and introduces gateways level per port configuration. This is a breaking change for exisitng implementation which uses this feature from Experimental API.
- Once gateway level TLS is configured (either by default or for a specific port), the TLS settings will apply to all existing and newly created Listeners that match the configuration.
+ Once gateway level TLS is configured (either by default or for a specific port), the TLS settings will apply to all existing and newly created Listeners serving HTTPS that match the configuration.
 
 #### GO
 
@@ -78,43 +85,58 @@ type ObjectReference struct {
 	Namespace *Namespace `json:"namespace,omitempty"`
 }
 
-// GatewayTLSConfigs stores TLS configurations for a Gateway.
-//
-// * If the `port` field in `TLSConfig` is not set, the TLS configuration applies
-//   to all listeners in the gateway. We call this `default` configuration.
-// * If the `port` field in `TLSConfig` is set, the TLS configuration applies
-//   only to listeners with a matching port. Each port requires a unique TLS configuration.
-// * Per-port configurations can override the `default` configuration.
-// * The `default` configuration is optional. Clients can apply TLS configuration
-//   to a subset of listeners by creating only per-port configurations. Listeners
-//   with a port that does not match any TLS configuration will not have
-//   `frontendValidation` set.
-type GatewayTLSConfigs = []TLSConfig
-
-// TLSConfig describes a TLS configuration that can be applied to all Gateway
-// Listeners or to all Listeners matching the Port if set.
+// GatewayTLSConfig specifies frontend tls configuration for gateway.
+type GatewayTLSConfig struct {
+    // default specifies the default client certificate validation configuration
+    // for all Listeners handling HTTPS traffic, unless a per-port configuration
+    // is defined.
+    //
+    // support: Core
+    //
+    // +required
+    // <gateway:experimental>
+    Default FrontendTLSValidation `json:"default"`
+
+    // 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
+    //
+    PerPort []TLSConfig `json:"PerPort,omitempty"`
+}
+
+// TLSConfig describes a TLS configuration. Currently, it stores only the client
+// certificate validation configuration, but this may be extended in the future.
 type TLSConfig struct {
-	// The Port indicates the Port Number to which the TLS configuration will be
-	// applied. If the field is not set the TLS Configuration will be applied to
-	// all Listeners.
-	//
-	// Support: Extended
-	//
-	// +optional
-	// <gateway:experimental>
-	Port *PortNumber
 	// 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
+	// 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.
 	//
-	// Each field may be overidden by an equivalent setting applied at the Listener level.
-	//
 	// Support: Extended
 	//
-	// +optional
+	// +required
+	// <gateway:experimental>
+	FrontendValidation FrontendTLSValidation `json:"frontendValidation"`
+}
+
+type TLSPortConfig struct {
+	// 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
+	//
+	// +required
 	// <gateway:experimental>
-	FrontendValidation *FrontendTLSValidation `json:"frontendValidation,omitempty"`
+	Port PortNumber `json:"port"`
+	// TLS store the configuration that will be applied to all Listeners handling
+	// HTTPS traffic and matching given port.
+	TLS TLSConfig `json:"tls"`
 }
 
 // FrontendTLSValidation holds configuration information that can be used to validate
@@ -151,21 +173,25 @@ type FrontendTLSValidation struct {
 	// - 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`.
-	// - AllowInvalidOrMissingCert: In this mode, the gateway will accept
-	//   connections even if the client certificate is not presented or fails verification.
+	// - 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: Extended
+	// Support: Core
 	//
 	// +optional
 	// +kubebuilder:default=AllowValidOnly
-	Mode *FrontendValidationModeType `json:"mode,omitempty"`
+	Mode FrontendValidationModeType `json:"mode,omitempty"`
 }
 
-// FrontendValidationModeType type defines how a Gateway or Listener validates client certificates.
+// FrontendValidationModeType type defines how a Gateway validates client certificates.
 //
-// +kubebuilder:validation:Enum=AllowValidOnly;AllowInvalidOrMissingCert
+// +kubebuilder:validation:Enum=AllowValidOnly;AllowInsecureFallback
 type FrontendValidationModeType string
 
 const (
@@ -173,15 +199,20 @@ const (
 	// during the TLS handshake and MUST pass validation.
 	AllowValidOnly FrontendValidationModeType = "AllowValidOnly"
 
-	// AllowInvalidOrMissingCert indicates that a client certificate may not be
+	// AllowInsecureFallback indicates that a client certificate may not be
 	// presented during the handshake or the validation against CA certificates may fail.
-	AllowInvalidOrMissingCert FrontendValidationModeType = "AllowInvalidOrMissingCert"
+	AllowInsecureFallback FrontendValidationModeType = "AllowInsecureFallback"
 )
 
 type GatewaySpec struct {
     ...
-    // TLSConfigs stores TLS configurations for a Gateway.
-    TLSConfigs GatewayTLSConfigs
+    // GatewayTLSConfig specifies frontend tls configuration for gateway.
+	//
+	// Support: Core
+	//
+	// +optional
+	// <gateway:experimental>
+	TLS *GatewayTLSConfig `json:"tls,omitempty"`
 }
 
 ```
@@ -198,11 +229,12 @@ metadata:
 spec:
   gatewayClassName: acme-lb
   tls:
-    - frontendValidation:
-        caCertificateRefs:
-        - kind: ConfigMap
-          group: ""
-          name: default-cert
+    default:
+    frontendValidation:
+      caCertificateRefs:
+      - kind: ConfigMap
+        group: ""
+        name: default-cert
   listeners:
   - name: foo-https
     protocol: HTTPS
@@ -234,18 +266,20 @@ metadata:
 spec:
   gatewayClassName: acme-lb
   tls:
-    - port: 443
+    default:
       frontendValidation:
         caCertificateRefs:
-        - kind: ConfigMap
-          group: ""
-          name: foo-example-com-ca-cert
-    - frontendValidation:
-        caCertificateRefs:
-        - kind: ConfigMap
-          group: ""
-          name: default-cert
-        mode: AllowInvalidOrMissingCert
+          - kind: ConfigMap
+            group: ""
+            name: default-cert
+        mode: AllowInsecureFallback
+    perPort:
+      - port: 443
+        frontendValidation:
+          caCertificateRefs:
+          - kind: ConfigMap
+            group: ""
+            name: foo-example-com-ca-cert
   listeners:
   - name: foo-https
     protocol: HTTPS
@@ -321,7 +355,6 @@ This GEP aims to standardize this behavior as an official part of the upstream s
 
 [TLS Handshake Protocol]: https://www.rfc-editor.org/rfc/rfc5246#section-7.4
 [Certificate Path Validation]: https://www.rfc-editor.org/rfc/rfc5280#section-6
-[GatewayTLSConfig]: ../../reference/spec.md#gateway.networking.k8s.io/v1.GatewayTLSConfig
 [BackendTLSPolicy]: ../../api-types/backendtlspolicy.md
 [TLS Configuration GEP]: ../gep-2907/index.md
 [Gateway API TLS Use Cases]: https://docs.google.com/document/d/17sctu2uMJtHmJTGtBi_awGB0YzoCLodtR6rUNmKMCs8/edit?pli=1#heading=h.cxuq8vo8pcxm
diff --git a/go.mod b/go.mod
index dcb0a21e..c818773d 100644
--- a/go.mod
+++ b/go.mod
@@ -11,11 +11,11 @@ require (
 	google.golang.org/grpc v1.74.2
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
 	google.golang.org/protobuf v1.36.7
-	k8s.io/api v0.33.3
-	k8s.io/apiextensions-apiserver v0.33.3
-	k8s.io/apimachinery v0.33.3
-	k8s.io/client-go v0.33.3
-	k8s.io/code-generator v0.33.3
+	k8s.io/api v0.33.4
+	k8s.io/apiextensions-apiserver v0.33.4
+	k8s.io/apimachinery v0.33.4
+	k8s.io/client-go v0.33.4
+	k8s.io/code-generator v0.33.4
 	k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
 	k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
 	sigs.k8s.io/controller-runtime v0.21.0
diff --git a/go.sum b/go.sum
index 67c2a445..b6f7fbce 100644
--- a/go.sum
+++ b/go.sum
@@ -244,16 +244,16 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
-k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
-k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
-k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
-k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
-k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
-k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
-k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
-k8s.io/code-generator v0.33.3 h1:6+34LhYkIuQ/yn/E3qlpVqjQaP8smzCu4NE1A8b0LWs=
-k8s.io/code-generator v0.33.3/go.mod h1:6Y02+HQJYgNphv9z3wJB5w+sjYDIEBQW7sh62PkufvA=
+k8s.io/api v0.33.4 h1:oTzrFVNPXBjMu0IlpA2eDDIU49jsuEorGHB4cvKupkk=
+k8s.io/api v0.33.4/go.mod h1:VHQZ4cuxQ9sCUMESJV5+Fe8bGnqAARZ08tSTdHWfeAc=
+k8s.io/apiextensions-apiserver v0.33.4 h1:rtq5SeXiDbXmSwxsF0MLe2Mtv3SwprA6wp+5qh/CrOU=
+k8s.io/apiextensions-apiserver v0.33.4/go.mod h1:mWXcZQkQV1GQyxeIjYApuqsn/081hhXPZwZ2URuJeSs=
+k8s.io/apimachinery v0.33.4 h1:SOf/JW33TP0eppJMkIgQ+L6atlDiP/090oaX0y9pd9s=
+k8s.io/apimachinery v0.33.4/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
+k8s.io/client-go v0.33.4 h1:TNH+CSu8EmXfitntjUPwaKVPN0AYMbc9F1bBS8/ABpw=
+k8s.io/client-go v0.33.4/go.mod h1:LsA0+hBG2DPwovjd931L/AoaezMPX9CmBgyVyBZmbCY=
+k8s.io/code-generator v0.33.4 h1:DiA801QxqApRIBh3OWULasVAUA237XnYvFNMh+E34Y8=
+k8s.io/code-generator v0.33.4/go.mod h1:ifWxKWhEl/Z1K7WmWAyOBEf3ex/i546ingCzLC8YVIY=
 k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 h1:2OX19X59HxDprNCVrWi6jb7LW1PoqTlYqEq5H2oetog=
 k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
diff --git a/mkdocs.yml b/mkdocs.yml
index 18393ce4..1052a445 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -27,7 +27,16 @@ theme:
     - navigation.top
     - navigation.expand
   palette:
-    primary: custom
+    - scheme: default
+      primary: custom
+      toggle:
+        icon: material/brightness-7
+        name: Switch to dark mode
+    - scheme: slate
+      primary: custom
+      toggle:
+        icon: material/brightness-4
+        name: Switch to light mode
   custom_dir: site-src/overrides
 edit_uri: edit/main/site-src/
 plugins:
diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go
index 9885f104..d412463a 100644
--- a/pkg/generated/openapi/zz_generated.openapi.go
+++ b/pkg/generated/openapi/zz_generated.openapi.go
@@ -136,6 +136,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"sigs.k8s.io/gateway-api/apis/v1.Listener":                                        schema_sigsk8sio_gateway_api_apis_v1_Listener(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ListenerNamespaces":                              schema_sigsk8sio_gateway_api_apis_v1_ListenerNamespaces(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ListenerStatus":                                  schema_sigsk8sio_gateway_api_apis_v1_ListenerStatus(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.ListenerTLSConfig":                               schema_sigsk8sio_gateway_api_apis_v1_ListenerTLSConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.LocalObjectReference":                            schema_sigsk8sio_gateway_api_apis_v1_LocalObjectReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.LocalParametersReference":                        schema_sigsk8sio_gateway_api_apis_v1_LocalParametersReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ObjectReference":                                 schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref),
@@ -148,6 +149,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"sigs.k8s.io/gateway-api/apis/v1.SecretObjectReference":                           schema_sigsk8sio_gateway_api_apis_v1_SecretObjectReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.SessionPersistence":                              schema_sigsk8sio_gateway_api_apis_v1_SessionPersistence(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.SupportedFeature":                                schema_sigsk8sio_gateway_api_apis_v1_SupportedFeature(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.TLSConfig":                                       schema_sigsk8sio_gateway_api_apis_v1_TLSConfig(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig":                                   schema_sigsk8sio_gateway_api_apis_v1_TLSPortConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.supportedFeatureInternal":                        schema_sigsk8sio_gateway_api_apis_v1_supportedFeatureInternal(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha2.GRPCRoute":                                 schema_sigsk8sio_gateway_api_apis_v1alpha2_GRPCRoute(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha2.GRPCRouteList":                             schema_sigsk8sio_gateway_api_apis_v1alpha2_GRPCRouteList(ref),
@@ -3100,7 +3103,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref common.Refer
 							},
 						},
 						SchemaProps: spec.SchemaProps{
-							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.\n\nA 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.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific (More than one reference, or other kinds of resources).\n\nReferences 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.",
+							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.\n\nA 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.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific (More than one certificate in a ConfigMap with different keys or more than one reference, or other kinds of resources).\n\nReferences 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.",
 							Type:        []string{"array"},
 							Items: &spec.SchemaOrArray{
 								Schema: &spec.Schema{
@@ -3112,6 +3115,13 @@ func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref common.Refer
 							},
 						},
 					},
+					"mode": {
+						SchemaProps: spec.SchemaProps{
+							Description: "FrontendValidationMode defines the mode for validating the client certificate. There are two possible modes:\n\n- AllowValidOnly: In this mode, the gateway will accept connections only if\n  the client presents a valid certificate. This certificate must successfully\n  pass validation against the CA certificates specified in `CACertificateRefs`.\n- AllowInsecureFallback: In this mode, the gateway will accept connections\n  even if the client certificate is not presented or fails verification.\n\n  This approach delegates client authorization to the backend and introduce\n  a significant security risk. It should be used in testing environments or\n  on a temporary basis in non-testing environments.\n\nDefaults to AllowValidOnly.\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
 				},
 				Required: []string{"caCertificateRefs"},
 			},
@@ -4094,12 +4104,18 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.AllowedListeners"),
 						},
 					},
+					"tls": {
+						SchemaProps: spec.SchemaProps{
+							Description: "GatewayTLSConfig specifies frontend tls configuration for gateway.\n\nSupport: Extended\n\n<gateway:experimental>",
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"),
+						},
+					},
 				},
 				Required: []string{"gatewayClassName", "listeners"},
 			},
 		},
 		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.Listener"},
+			"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"},
 	}
 }
 
@@ -4241,61 +4257,44 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewayTLSConfig(ref common.ReferenceC
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Type: []string{"object"},
+				Description: "GatewayTLSConfig specifies frontend tls configuration for gateway.",
+				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
-					"mode": {
+					"default": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes:\n\n- Terminate: The TLS session between the downstream client and the\n  Gateway is terminated at the Gateway. This mode requires certificates\n  to be specified in some way, such as populating the certificateRefs\n  field.\n- Passthrough: The TLS session is NOT terminated by the Gateway. This\n  implies that the Gateway can't decipher the TLS stream except for\n  the ClientHello message of the TLS protocol. The certificateRefs field\n  is ignored in this mode.\n\nSupport: Core",
-							Type:        []string{"string"},
-							Format:      "",
+							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"),
 						},
 					},
-					"certificateRefs": {
+					"perPort": {
 						VendorExtensible: spec.VendorExtensible{
 							Extensions: spec.Extensions{
-								"x-kubernetes-list-type": "atomic",
+								"x-kubernetes-list-map-keys": []interface{}{
+									"port",
+								},
+								"x-kubernetes-list-type": "map",
 							},
 						},
 						SchemaProps: spec.SchemaProps{
-							Description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener.\n\nA single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific.\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\nThis field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise.\n\nCertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources.\n\nSupport: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\nSupport: Implementation-specific (More than one reference or other resource types)",
+							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.SecretObjectReference"),
-									},
-								},
-							},
-						},
-					},
-					"frontendValidation": {
-						SchemaProps: spec.SchemaProps{
-							Description: "FrontendValidation holds configuration information for validating the frontend (client). Setting this field will require clients to send a client certificate required for validation during the TLS handshake. 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: Extended\n\n<gateway:experimental>",
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation"),
-						},
-					},
-					"options": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites.\n\nA set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API.\n\nSupport: Implementation-specific",
-							Type:        []string{"object"},
-							AdditionalProperties: &spec.SchemaOrBool{
-								Allows: true,
-								Schema: &spec.Schema{
-									SchemaProps: spec.SchemaProps{
-										Default: "",
-										Type:    []string{"string"},
-										Format:  "",
+										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"),
 									},
 								},
 							},
 						},
 					},
 				},
+				Required: []string{"default"},
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation", "sigs.k8s.io/gateway-api/apis/v1.SecretObjectReference"},
+			"sigs.k8s.io/gateway-api/apis/v1.TLSConfig", "sigs.k8s.io/gateway-api/apis/v1.TLSPortConfig"},
 	}
 }
 
@@ -5399,8 +5398,8 @@ func schema_sigsk8sio_gateway_api_apis_v1_Listener(ref common.ReferenceCallback)
 					},
 					"tls": {
 						SchemaProps: spec.SchemaProps{
-							Description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\nThe association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener.\n\nThe GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake.\n\nSupport: Core",
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"),
+							Description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\nThe association of SNIs to Certificate defined in ListenerTLSConfig is defined based on the Hostname field for this listener.\n\nThe GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake.\n\nSupport: Core",
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.ListenerTLSConfig"),
 						},
 					},
 					"allowedRoutes": {
@@ -5414,7 +5413,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_Listener(ref common.ReferenceCallback)
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.AllowedRoutes", "sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"},
+			"sigs.k8s.io/gateway-api/apis/v1.AllowedRoutes", "sigs.k8s.io/gateway-api/apis/v1.ListenerTLSConfig"},
 	}
 }
 
@@ -5519,6 +5518,62 @@ func schema_sigsk8sio_gateway_api_apis_v1_ListenerStatus(ref common.ReferenceCal
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_ListenerTLSConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Type: []string{"object"},
+				Properties: map[string]spec.Schema{
+					"mode": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Mode defines the TLS behavior for the TLS session initiated by the client. There are two possible modes:\n\n- Terminate: The TLS session between the downstream client and the\n  Gateway is terminated at the Gateway. This mode requires certificates\n  to be specified in some way, such as populating the certificateRefs\n  field.\n- Passthrough: The TLS session is NOT terminated by the Gateway. This\n  implies that the Gateway can't decipher the TLS stream except for\n  the ClientHello message of the TLS protocol. The certificateRefs field\n  is ignored in this mode.\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"certificateRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener.\n\nA single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific.\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\nThis field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise.\n\nCertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources.\n\nSupport: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\nSupport: Implementation-specific (More than one reference or other resource types)",
+							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.SecretObjectReference"),
+									},
+								},
+							},
+						},
+					},
+					"options": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Options are a list of key/value pairs to enable extended TLS configuration for each implementation. For example, configuring the minimum TLS version or supported cipher suites.\n\nA set of common keys MAY be defined by the API in the future. To avoid any ambiguity, implementation-specific definitions MUST use domain-prefixed names, such as `example.com/my-custom-option`. Un-prefixed names are reserved for key names defined by Gateway API.\n\nSupport: Implementation-specific",
+							Type:        []string{"object"},
+							AdditionalProperties: &spec.SchemaOrBool{
+								Allows: true,
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: "",
+										Type:    []string{"string"},
+										Format:  "",
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.SecretObjectReference"},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_LocalObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -5997,6 +6052,59 @@ func schema_sigsk8sio_gateway_api_apis_v1_SupportedFeature(ref common.ReferenceC
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_TLSConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				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": {
+						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{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation"),
+						},
+					},
+				},
+				Required: []string{"frontendValidation"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.FrontendTLSValidation"},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_TLSPortConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Type: []string{"object"},
+				Properties: map[string]spec.Schema{
+					"port": {
+						SchemaProps: spec.SchemaProps{
+							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.\n\nSupport: Core\n\n<gateway:experimental>",
+							Default:     0,
+							Type:        []string{"integer"},
+							Format:      "int32",
+						},
+					},
+					"tls": {
+						SchemaProps: spec.SchemaProps{
+							Description: "TLS store the configuration that will be applied to all Listeners handling HTTPS traffic and matching given port.\n\nSupport: Core\n\n<gateway:experimental>",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.TLSConfig"),
+						},
+					},
+				},
+				Required: []string{"port", "tls"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.TLSConfig"},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_supportedFeatureInternal(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -8204,8 +8312,8 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_ListenerEntry(ref common.Refere
 					},
 					"tls": {
 						SchemaProps: spec.SchemaProps{
-							Description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\nThe association of SNIs to Certificate defined in GatewayTLSConfig is defined based on the Hostname field for this listener.\n\nThe GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake.",
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"),
+							Description: "TLS is the TLS configuration for the Listener. This field is required if the Protocol field is \"HTTPS\" or \"TLS\". It is invalid to set this field if the Protocol field is \"HTTP\", \"TCP\", or \"UDP\".\n\nThe association of SNIs to Certificate defined in ListenerTLSConfig is defined based on the Hostname field for this listener.\n\nThe GatewayClass MUST use the longest matching SNI out of all available certificates for any TLS handshake.",
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.ListenerTLSConfig"),
 						},
 					},
 					"allowedRoutes": {
@@ -8219,7 +8327,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_ListenerEntry(ref common.Refere
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.AllowedRoutes", "sigs.k8s.io/gateway-api/apis/v1.GatewayTLSConfig"},
+			"sigs.k8s.io/gateway-api/apis/v1.AllowedRoutes", "sigs.k8s.io/gateway-api/apis/v1.ListenerTLSConfig"},
 	}
 }
 
diff --git a/site-src/contributing/devguide.md b/site-src/contributing/devguide.md
index 6d3acfdf..ee5e5bd4 100644
--- a/site-src/contributing/devguide.md
+++ b/site-src/contributing/devguide.md
@@ -36,7 +36,9 @@ command in PR and issue comments][issue-cmds]. For example,
 Before you start developing with Gateway API, we'd recommend having the
 following prerequisites installed:
 
-* [Kind](https://kubernetes.io/docs/tasks/tools/#kind): This is a standalone local Kubernetes cluster. At least one container runtime is required. We recommend installing [Docker](https://docs.docker.com/engine/install/). While you can opt for alternatives like [Podman](https://podman.io/docs/installation), please be aware that doing so is at your own risk.
+* [KinD](https://kubernetes.io/docs/tasks/tools/#kind): This is a standalone local Kubernetes cluster. At least one container runtime is required.
+* [Docker](https://docs.docker.com/engine/install/): This is a prerequisite for running KinD. While you can opt for alternatives like [Podman](https://podman.io/docs/installation), please be aware that doing so is at your own risk.
+* [BuildX](https://github.com/docker/buildx): Prerequisite for `make verify` to run.
 * [Kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl): This is the Kubernetes command-line tool.
 * [Go](https://golang.org/doc/install): It is the main programming language in this project. Please check this [file](https://github.com/kubernetes-sigs/gateway-api/blob/main/go.mod#L3) to find out the least `Go` version otherwise you might encounter compilation errors.
 * [Digest::SHA](https://metacpan.org/pod/Digest::SHA): It is a required dependency. You can obtain it by installing the `perl-Digest-SHA` package.



Test patch:
diff --git a/conformance/tests/backendtlspolicy-observed-generation-bump.go b/conformance/tests/backendtlspolicy-observed-generation-bump.go
new file mode 100644
index 00000000..a3cd4000
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-observed-generation-bump.go
@@ -0,0 +1,88 @@
+/*
+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 (
+	"context"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	"sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/apis/v1alpha3"
+	"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, BackendTLSPolicyObservedGenerationBump)
+}
+
+var BackendTLSPolicyObservedGenerationBump = suite.ConformanceTest{
+	ShortName:   "BackendTLSPolicyObservedGenerationBump",
+	Description: "A BackendTLSPolicy in the gateway-conformance-infra namespace should update the observedGeneration in all of it's Status.Conditions after an update to the spec",
+	Features: []features.FeatureName{
+		features.SupportGateway,
+		features.SupportHTTPRoute,
+		features.SupportBackendTLSPolicy,
+	},
+	Manifests: []string{"tests/backendtlspolicy-observed-generation-bump.yaml"},
+	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
+		ns := "gateway-conformance-infra"
+		policyNN := types.NamespacedName{Name: "observed-generation-bump", Namespace: ns}
+		gwNN := types.NamespacedName{Name: "same-namespace", Namespace: ns}
+
+		t.Run("observedGeneration should increment", func(t *testing.T) {
+			ctx, cancel := context.WithTimeout(context.Background(), suite.TimeoutConfig.LatestObservedGenerationSet)
+			defer cancel()
+
+			namespaces := []string{"gateway-conformance-infra"}
+			kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, namespaces)
+
+			original := &v1alpha3.BackendTLSPolicy{}
+			err := suite.Client.Get(ctx, policyNN, original)
+			require.NoError(t, err, "error getting HTTPRoute")
+
+			// Sanity check
+			kubernetes.BackendTLSPolicyMustHaveLatestConditions(t, original)
+
+			mutate := original.DeepCopy()
+			mutate.Spec.Validation.Hostname = "foo.example.com"
+			err = suite.Client.Patch(ctx, mutate, client.MergeFrom(original))
+			require.NoError(t, err, "error patching the BackendTLSPolicy")
+
+			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, metav1.Condition{
+				Type:   string(v1alpha2.PolicyConditionAccepted),
+				Status: metav1.ConditionTrue,
+				Reason: "", // any reason
+			})
+
+			updated := &v1alpha3.BackendTLSPolicy{}
+			err = suite.Client.Get(ctx, policyNN, updated)
+			require.NoError(t, err, "error getting BackendTLSPolicy")
+
+			// Sanity check
+			kubernetes.BackendTLSPolicyMustHaveLatestConditions(t, updated)
+
+			require.NotEqual(t, original.Generation, updated.Generation, "generation should change after an update")
+		})
+	},
+}
diff --git a/conformance/tests/backendtlspolicy-observed-generation-bump.yaml b/conformance/tests/backendtlspolicy-observed-generation-bump.yaml
new file mode 100644
index 00000000..c21bd45b
--- /dev/null
+++ b/conformance/tests/backendtlspolicy-observed-generation-bump.yaml
@@ -0,0 +1,45 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: backendtlspolicy-observed-generation-bump
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: same-namespace
+  rules:
+    - backendRefs:
+        - name: observed-generation-bump-test
+          port: 443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: observed-generation-bump-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: observed-generation-bump-test
+  ports:
+    - name: "https"
+      protocol: TCP
+      port: 443
+      targetPort: 8443
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: observed-generation-bump
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+    - group: ""
+      kind: Service
+      name: "observed-generation-bump-test"
+      sectionName: "https"
+  validation:
+    caCertificateRefs:
+      - group: ""
+        kind: ConfigMap
+        # This ConfigMap is generated dynamically by the test suite.
+        name: "backend-tls-checks-certificate"
+    hostname: "abc.example.com"
diff --git a/pkg/test/cel/gateway_test.go b/pkg/test/cel/gateway_test.go
index 7f8d8676..ba85b50f 100644
--- a/pkg/test/cel/gateway_test.go
+++ b/pkg/test/cel/gateway_test.go
@@ -60,7 +60,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("http"),
 						Protocol: gatewayv1.HTTPProtocolType,
 						Port:     gatewayv1.PortNumber(8080),
-						TLS:      &gatewayv1.GatewayTLSConfig{},
+						TLS:      &gatewayv1.ListenerTLSConfig{},
 					},
 				}
 			},
@@ -74,7 +74,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("https"),
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8080),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: ptrTo(gatewayv1.TLSModeType("Passthrough")),
 						},
 					},
@@ -90,7 +90,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("https"),
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8080),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							CertificateRefs: []gatewayv1.SecretObjectReference{
 								{Name: gatewayv1.ObjectName("foo")},
 							},
@@ -107,7 +107,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("tcp"),
 						Protocol: gatewayv1.TCPProtocolType,
 						Port:     gatewayv1.PortNumber(8080),
-						TLS:      &gatewayv1.GatewayTLSConfig{},
+						TLS:      &gatewayv1.ListenerTLSConfig{},
 					},
 				}
 			},
@@ -212,7 +212,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("https"),
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 						},
 					},
@@ -229,7 +229,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("tls"),
 						Protocol: gatewayv1.TLSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 						},
 					},
@@ -246,7 +246,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("https"),
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 							CertificateRefs: []gatewayv1.SecretObjectReference{
 								{Name: gatewayv1.ObjectName("foo")},
@@ -265,7 +265,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("tls"),
 						Protocol: gatewayv1.TLSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 							CertificateRefs: []gatewayv1.SecretObjectReference{
 								{Name: gatewayv1.ObjectName("foo")},
@@ -284,7 +284,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("https"),
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 							Options: map[gatewayv1.AnnotationKey]gatewayv1.AnnotationValue{
 								"networking.example.com/tls-version": "1.2",
@@ -303,7 +303,7 @@ func TestValidateGateway(t *testing.T) {
 						Name:     gatewayv1.SectionName("tls"),
 						Protocol: gatewayv1.TLSProtocolType,
 						Port:     gatewayv1.PortNumber(8443),
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							Mode: &tlsMode,
 							Options: map[gatewayv1.AnnotationKey]gatewayv1.AnnotationValue{
 								"networking.example.com/tls-version": "1.2",
@@ -473,7 +473,7 @@ func TestValidateGateway(t *testing.T) {
 						Protocol: gatewayv1.HTTPSProtocolType,
 						Port:     gatewayv1.PortNumber(8000),
 						Hostname: &hostnameFoo,
-						TLS: &gatewayv1.GatewayTLSConfig{
+						TLS: &gatewayv1.ListenerTLSConfig{
 							CertificateRefs: []gatewayv1.SecretObjectReference{
 								{Name: gatewayv1.ObjectName("foo")},
 							},