Repository: kubernetes-sigs/gateway-api

Issue:
Gateway.Spec.Addresses.Value should be optional
**What would you like to be added**:
I'd like [Gateway.Spec.Addresses.Value](https://github.com/kubernetes-sigs/gateway-api/blob/64c85004dff1adfdec7599fcf403f2b54fb7e38b/apis/v1/gateway_types.go#L677) to be optional.

**Why this is needed**:
It should be valid to request a _type_ of address without specifying the value that address should have. For example, on Google Cloud, we have a [Cross Region ILB](https://cloud.google.com/load-balancing/docs/l7-internal/setting-up-l7-cross-reg-internal) and we'd like users to be able to request ephemeral addresses in specific locations. That is currently quite challenging when the `value` of a requested address must be specified.

Note: Per our [versioning policy](https://gateway-api.sigs.k8s.io/concepts/versioning/#minor-version-eg-v040-v050) it is valid to make required fields optional in a minor release across any release channel.

Discussion:
@EyalPazz: /assign

Solution patch:
diff --git a/apis/v1/backendtlspolicy_types.go b/apis/v1/backendtlspolicy_types.go
new file mode 100644
index 00000000..5a755eb1
--- /dev/null
+++ b/apis/v1/backendtlspolicy_types.go
@@ -0,0 +1,318 @@
+/*
+Copyright 2023 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 v1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+// +genclient
+// +kubebuilder:object:root=true
+// +kubebuilder:subresource:status
+// +kubebuilder:storageversion
+// +kubebuilder:resource:categories=gateway-api,shortName=btlspolicy
+// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
+//
+// BackendTLSPolicy is a Direct Attached Policy.
+// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=Direct"
+
+// BackendTLSPolicy provides a way to configure how a Gateway
+// connects to a Backend via TLS.
+type BackendTLSPolicy struct {
+	metav1.TypeMeta `json:",inline"`
+	// +optional
+	metav1.ObjectMeta `json:"metadata,omitempty"`
+
+	// Spec defines the desired state of BackendTLSPolicy.
+	// +required
+	Spec BackendTLSPolicySpec `json:"spec"`
+
+	// Status defines the current state of BackendTLSPolicy.
+	// +optional
+	Status PolicyStatus `json:"status,omitempty"`
+}
+
+// BackendTLSPolicyList contains a list of BackendTLSPolicies
+// +kubebuilder:object:root=true
+type BackendTLSPolicyList struct {
+	metav1.TypeMeta `json:",inline"`
+	metav1.ListMeta `json:"metadata,omitempty"`
+	Items           []BackendTLSPolicy `json:"items"`
+}
+
+// BackendTLSPolicySpec defines the desired state of BackendTLSPolicy.
+//
+// Support: Extended
+type BackendTLSPolicySpec struct {
+	// TargetRefs identifies an API object to apply the policy to.
+	// Only Services have Extended support. Implementations MAY support
+	// additional objects, with Implementation Specific support.
+	// Note that this config applies to the entire referenced resource
+	// by default, but this default may change in the future to provide
+	// a more granular application of the policy.
+	//
+	// TargetRefs must be _distinct_. This means either that:
+	//
+	// * They select different targets. If this is the case, then targetRef
+	//   entries are distinct. In terms of fields, this means that the
+	//   multi-part key defined by `group`, `kind`, and `name` must
+	//   be unique across all targetRef entries in the BackendTLSPolicy.
+	// * They select different sectionNames in the same target.
+	//
+	//
+	// When more than one BackendTLSPolicy selects the same target and
+	// sectionName, implementations MUST determine precedence using the
+	// following criteria, continuing on ties:
+	//
+	// * The older policy by creation timestamp takes precedence. For
+	//   example, a policy with a creation timestamp of "2021-07-15
+	//   01:02:03" MUST be given precedence over a policy with a
+	//   creation timestamp of "2021-07-15 01:02:04".
+	// * The policy appearing first in alphabetical order by {name}.
+	//   For example, a policy named `bar` is given precedence over a
+	//   policy named `baz`.
+	//
+	// For any BackendTLSPolicy that does not take precedence, the
+	// implementation MUST ensure the `Accepted` Condition is set to
+	// `status: False`, with Reason `Conflicted`.
+	//
+	// Support: Extended for Kubernetes Service
+	//
+	// Support: Implementation-specific for any other resource
+	//
+	// +required
+	// +listType=atomic
+	// +kubebuilder:validation:MinItems=1
+	// +kubebuilder:validation:MaxItems=16
+	// +kubebuilder:validation:XValidation:message="sectionName must be specified when targetRefs includes 2 or more references to the same target",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))"
+	// +kubebuilder:validation:XValidation:message="sectionName must be unique when targetRefs includes 2 or more references to the same target",rule="self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))"
+	TargetRefs []LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"`
+
+	// Validation contains backend TLS validation configuration.
+	// +required
+	Validation BackendTLSPolicyValidation `json:"validation"`
+
+	// 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.
+	//
+	// A 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.
+	//
+	// Support: Implementation-specific
+	//
+	// +optional
+	// +kubebuilder:validation:MaxProperties=16
+	Options map[AnnotationKey]AnnotationValue `json:"options,omitempty"`
+}
+
+// BackendTLSPolicyValidation contains backend TLS validation configuration.
+// +kubebuilder:validation:XValidation:message="must not contain both CACertificateRefs and WellKnownCACertificates",rule="!(has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")"
+// +kubebuilder:validation:XValidation:message="must specify either CACertificateRefs or WellKnownCACertificates",rule="(has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")"
+type BackendTLSPolicyValidation struct {
+	// CACertificateRefs contains one or more references to Kubernetes objects that
+	// contain a PEM-encoded TLS CA certificate bundle, which is used to
+	// validate a TLS handshake between the Gateway and backend Pod.
+	//
+	// If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
+	// specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
+	// not both. If CACertificateRefs is empty or unspecified, the configuration for
+	// WellKnownCACertificates MUST be honored instead if supported by the implementation.
+	//
+	// A CACertificateRef is invalid if:
+	//
+	// * It refers to a resource that cannot be resolved (e.g., the referenced resource
+	//   does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key
+	//   named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`
+	//   and the Message of the Condition must indicate which reference is invalid and why.
+	//
+	// * It refers to an unknown or unsupported kind of resource. In this case, the Reason
+	//   must be set to `InvalidKind` and the Message of the Condition must explain which
+	//   kind of resource is unknown or unsupported.
+	//
+	// * It refers to a resource in another namespace. This may change in future
+	//   spec updates.
+	//
+	// Implementations MAY choose to perform further validation of the certificate
+	// content (e.g., checking expiry or enforcing specific formats). In such cases,
+	// an implementation-specific Reason and Message must be set for the invalid reference.
+	//
+	// In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on
+	// the BackendTLSPolicy is set to `status: False`, with a Reason and Message
+	// that indicate the cause of the error. Connections using an invalid
+	// CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error
+	// response. If ALL CACertificateRefs are invalid, the implementation MUST also
+	// ensure the `Accepted` Condition on the BackendTLSPolicy is set to
+	// `status: False`, with a Reason `NoValidCACertificate`.
+	//
+	//
+	// A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
+	// Implementations MAY choose to support attaching multiple certificates to
+	// a backend, but this behavior is implementation-specific.
+	//
+	// Support: Core - An optional single reference to a Kubernetes ConfigMap,
+	// with the CA certificate in a key named `ca.crt`.
+	//
+	// Support: Implementation-specific - More than one reference, other kinds
+	// of resources, or a single reference that includes multiple certificates.
+	//
+	// +optional
+	// +listType=atomic
+	// +kubebuilder:validation:MaxItems=8
+	CACertificateRefs []LocalObjectReference `json:"caCertificateRefs,omitempty"`
+
+	// WellKnownCACertificates specifies whether system CA certificates may be used in
+	// the TLS handshake between the gateway and backend pod.
+	//
+	// If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
+	// must be specified with at least one entry for a valid configuration. Only one of
+	// CACertificateRefs or WellKnownCACertificates may be specified, not both.
+	// If an implementation does not support the WellKnownCACertificates field, or
+	// the supplied value is not recognized, the implementation MUST ensure the
+	// `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with
+	// a Reason `Invalid`.
+	//
+	// Support: Implementation-specific
+	//
+	// +optional
+	// +listType=atomic
+	WellKnownCACertificates *WellKnownCACertificatesType `json:"wellKnownCACertificates,omitempty"`
+
+	// Hostname is used for two purposes in the connection between Gateways and
+	// backends:
+	//
+	// 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
+	// 2. Hostname MUST be used for authentication and MUST match the certificate
+	//    served by the matching backend, unless SubjectAltNames is specified.
+	// 3. If SubjectAltNames are specified, Hostname can be used for certificate selection
+	//    but MUST NOT be used for authentication. If you want to use the value
+	//    of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.
+	//
+	// Support: Core
+	//
+	// +required
+	Hostname PreciseHostname `json:"hostname"`
+
+	// SubjectAltNames contains one or more Subject Alternative Names.
+	// When specified the certificate served from the backend MUST
+	// have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
+	//
+	// Support: Extended
+	//
+	// +optional
+	// +listType=atomic
+	// +kubebuilder:validation:MaxItems=5
+	SubjectAltNames []SubjectAltName `json:"subjectAltNames,omitempty"`
+}
+
+// SubjectAltName represents Subject Alternative Name.
+// +kubebuilder:validation:XValidation:message="SubjectAltName element must contain Hostname, if Type is set to Hostname",rule="!(self.type == \"Hostname\" && (!has(self.hostname) || self.hostname == \"\"))"
+// +kubebuilder:validation:XValidation:message="SubjectAltName element must not contain Hostname, if Type is not set to Hostname",rule="!(self.type != \"Hostname\" && has(self.hostname) && self.hostname != \"\")"
+// +kubebuilder:validation:XValidation:message="SubjectAltName element must contain URI, if Type is set to URI",rule="!(self.type == \"URI\" && (!has(self.uri) || self.uri == \"\"))"
+// +kubebuilder:validation:XValidation:message="SubjectAltName element must not contain URI, if Type is not set to URI",rule="!(self.type != \"URI\" && has(self.uri) && self.uri != \"\")"
+type SubjectAltName struct {
+	// Type determines the format of the Subject Alternative Name. Always required.
+	//
+	// Support: Core
+	//
+	// +required
+	Type SubjectAltNameType `json:"type"`
+
+	// Hostname contains Subject Alternative Name specified in DNS name format.
+	// Required when Type is set to Hostname, ignored otherwise.
+	//
+	// Support: Core
+	//
+	// +optional
+	Hostname Hostname `json:"hostname,omitempty"`
+
+	// URI contains Subject Alternative Name specified in a full URI format.
+	// It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
+	// Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
+	// Required when Type is set to URI, ignored otherwise.
+	//
+	// Support: Core
+	//
+	// +optional
+	URI AbsoluteURI `json:"uri,omitempty"`
+}
+
+// WellKnownCACertificatesType is the type of CA certificate that will be used
+// when the caCertificateRefs field is unspecified.
+// +kubebuilder:validation:Enum=System
+type WellKnownCACertificatesType string
+
+const (
+	// WellKnownCACertificatesSystem indicates that well known system CA certificates should be used.
+	WellKnownCACertificatesSystem WellKnownCACertificatesType = "System"
+)
+
+// SubjectAltNameType is the type of the Subject Alternative Name.
+// +kubebuilder:validation:Enum=Hostname;URI
+type SubjectAltNameType string
+
+const (
+	// HostnameSubjectAltNameType specifies hostname-based SAN.
+	//
+	// Support: Core
+	HostnameSubjectAltNameType SubjectAltNameType = "Hostname"
+
+	// URISubjectAltNameType specifies URI-based SAN, e.g. SPIFFE id.
+	//
+	// Support: Core
+	URISubjectAltNameType SubjectAltNameType = "URI"
+)
+
+const (
+	// This reason is used with the "Accepted" condition when it is
+	// set to false because all CACertificateRefs of the
+	// BackendTLSPolicy are invalid.
+	BackendTLSPolicyReasonNoValidCACertificate PolicyConditionReason = "NoValidCACertificate"
+)
+
+const (
+	// This condition indicates whether the controller was able to resolve all
+	// object references for the BackendTLSPolicy.
+	//
+	// Possible reasons for this condition to be True are:
+	//
+	// * "ResolvedRefs"
+	//
+	// Possible reasons for this condition to be False are:
+	//
+	// * "InvalidCACertificateRef"
+	// * "InvalidKind"
+	//
+	// Controllers may raise this condition with other reasons, but should
+	// prefer to use the reasons listed above to improve interoperability.
+	BackendTLSPolicyConditionResolvedRefs PolicyConditionType = "ResolvedRefs"
+
+	// This reason is used with the "ResolvedRefs" condition when the condition
+	// is true.
+	BackendTLSPolicyReasonResolvedRefs PolicyConditionReason = "ResolvedRefs"
+
+	// This reason is used with the "ResolvedRefs" condition when one of the
+	// BackendTLSPolicy's CACertificateRefs is invalid.
+	// A CACertificateRef is considered invalid when it refers to a nonexistent
+	// resource or when the data within that resource is malformed.
+	BackendTLSPolicyReasonInvalidCACertificateRef PolicyConditionReason = "InvalidCACertificateRef"
+
+	// This reason is used with the "ResolvedRefs" condition when one of the
+	// BackendTLSPolicy's CACertificateRefs references an unknown or unsupported
+	// Group and/or Kind.
+	BackendTLSPolicyReasonInvalidKind PolicyConditionReason = "InvalidKind"
+)
diff --git a/apis/v1/gateway_types.go b/apis/v1/gateway_types.go
index 10eb5bee..58d97518 100644
--- a/apis/v1/gateway_types.go
+++ b/apis/v1/gateway_types.go
@@ -246,7 +246,7 @@ type GatewaySpec struct {
 	// Addresses requested for this Gateway. This is optional and behavior can
 	// depend on the implementation. If a value is set in the spec and the
 	// requested address is invalid or unavailable, the implementation MUST
-	// indicate this in the associated entry in GatewayStatus.Addresses.
+	// indicate this in an associated entry in GatewayStatus.Conditions.
 	//
 	// The Addresses field represents a request for the address(es) on the
 	// "outside of the Gateway", that traffic bound for this Gateway will use.
@@ -268,8 +268,8 @@ type GatewaySpec struct {
 	// +listType=atomic
 	// <gateway:validateIPAddress>
 	// +kubebuilder:validation:MaxItems=16
-	// +kubebuilder:validation:XValidation:message="IPAddress values must be unique",rule="self.all(a1, a1.type == 'IPAddress' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )"
-	// +kubebuilder:validation:XValidation:message="Hostname values must be unique",rule="self.all(a1, a1.type == 'Hostname' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )"
+	// +kubebuilder:validation:XValidation:message="IPAddress values must be unique",rule="self.all(a1, a1.type == 'IPAddress' && has(a1.value) ? self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value == a1.value) : true )"
+	// +kubebuilder:validation:XValidation:message="Hostname values must be unique",rule="self.all(a1, a1.type == 'Hostname'  && has(a1.value) ? self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value == a1.value) : true )"
 	Addresses []GatewaySpecAddress `json:"addresses,omitempty"`
 
 	// Infrastructure defines infrastructure level attributes about this Gateway instance.
@@ -884,7 +884,7 @@ type RouteGroupKind struct {
 
 // GatewaySpecAddress describes an address that can be bound to a Gateway.
 //
-// +kubebuilder:validation:XValidation:message="Hostname value must only contain valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)",rule="self.type == 'Hostname' ? self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\"): true"
+// +kubebuilder:validation:XValidation:message="Hostname value must be empty or contain only valid characters (matching ^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)",rule="self.type == 'Hostname' ? (!has(self.value) || self.value.matches(r\"\"\"^(\\*\\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$\"\"\")): true"
 type GatewaySpecAddress struct {
 	// Type of the address.
 	//
diff --git a/apis/v1/policy_types.go b/apis/v1/policy_types.go
new file mode 100644
index 00000000..552db9bf
--- /dev/null
+++ b/apis/v1/policy_types.go
@@ -0,0 +1,279 @@
+/*
+Copyright 2021 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 v1
+
+import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+const (
+	// PolicyLabelKey is the label whose presence identifies a CRD that the
+	// Gateway API Policy attachment model. The value of the label SHOULD be one
+	// of the following:
+	//  - A label value of "Inherited" indicates that this Policy is inheritable.
+	//    An example of inheritable policy is one which if applied at the Gateway
+	//    level would affect all attached HTTPRoutes and their respective
+	//    Backends.
+	//  - A label value of "Direct" indicates that the policy only affects the
+	//    resource to which it is attached and does not affect it's sub resources.
+	PolicyLabelKey = "gateway.networking.k8s.io/policy"
+)
+
+// LocalPolicyTargetReference identifies an API object to apply a direct or
+// inherited policy to. This should be used as part of Policy resources
+// that can target Gateway API resources. For more information on how this
+// policy attachment model works, and a sample Policy resource, refer to
+// the policy attachment documentation for Gateway API.
+type LocalPolicyTargetReference struct {
+	// Group is the group of the target resource.
+	// +required
+	Group Group `json:"group"`
+
+	// Kind is kind of the target resource.
+	// +required
+	Kind Kind `json:"kind"`
+
+	// Name is the name of the target resource.
+	// +required
+	Name ObjectName `json:"name"`
+}
+
+// NamespacedPolicyTargetReference identifies an API object to apply a direct or
+// inherited policy to, potentially in a different namespace. This should only
+// be used as part of Policy resources that need to be able to target resources
+// in different namespaces. For more information on how this policy attachment
+// model works, and a sample Policy resource, refer to the policy attachment
+// documentation for Gateway API.
+type NamespacedPolicyTargetReference struct {
+	// Group is the group of the target resource.
+	// +required
+	Group Group `json:"group"`
+
+	// Kind is kind of the target resource.
+	// +required
+	Kind Kind `json:"kind"`
+
+	// Name is the name of the target resource.
+	// +required
+	Name ObjectName `json:"name"`
+
+	// Namespace is the namespace of the referent. When unspecified, the local
+	// namespace is inferred. Even when policy targets a resource in a different
+	// namespace, it MUST only apply to traffic originating from the same
+	// namespace as the policy.
+	//
+	// +optional
+	Namespace *Namespace `json:"namespace,omitempty"`
+}
+
+// LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
+// direct policy to. This should be used as part of Policy resources that can
+// target single resources. For more information on how this policy attachment
+// mode works, and a sample Policy resource, refer to the policy attachment
+// documentation for Gateway API.
+//
+// Note: This should only be used for direct policy attachment when references
+// to SectionName are actually needed. In all other cases,
+// LocalPolicyTargetReference should be used.
+type LocalPolicyTargetReferenceWithSectionName struct {
+	LocalPolicyTargetReference `json:",inline"`
+
+	// SectionName is the name of a section within the target resource. When
+	// unspecified, this targetRef targets the entire resource. In the following
+	// resources, SectionName is interpreted as the following:
+	//
+	// * Gateway: Listener name
+	// * HTTPRoute: HTTPRouteRule name
+	// * Service: Port name
+	//
+	// If a SectionName is specified, but does not exist on the targeted object,
+	// the Policy must fail to attach, and the policy implementation should record
+	// a `ResolvedRefs` or similar Condition in the Policy's status.
+	//
+	// +optional
+	SectionName *SectionName `json:"sectionName,omitempty"`
+}
+
+// PolicyConditionType is a type of condition for a policy. This type should be
+// used with a Policy resource Status.Conditions field.
+type PolicyConditionType string
+
+// PolicyConditionReason is a reason for a policy condition.
+type PolicyConditionReason string
+
+const (
+	// PolicyConditionAccepted indicates whether the policy has been accepted or
+	// rejected by a targeted resource, and why.
+	//
+	// Possible reasons for this condition to be True are:
+	//
+	// * "Accepted"
+	//
+	// Possible reasons for this condition to be False are:
+	//
+	// * "Conflicted"
+	// * "Invalid"
+	// * "TargetNotFound"
+	//
+	PolicyConditionAccepted PolicyConditionType = "Accepted"
+
+	// PolicyReasonAccepted is used with the "Accepted" condition when the policy
+	// has been accepted by the targeted resource.
+	PolicyReasonAccepted PolicyConditionReason = "Accepted"
+
+	// PolicyReasonConflicted is used with the "Accepted" condition when the
+	// policy has not been accepted by a targeted resource because there is
+	// another policy that targets the same resource and a merge is not possible.
+	PolicyReasonConflicted PolicyConditionReason = "Conflicted"
+
+	// PolicyReasonInvalid is used with the "Accepted" condition when the policy
+	// is syntactically or semantically invalid.
+	PolicyReasonInvalid PolicyConditionReason = "Invalid"
+
+	// PolicyReasonTargetNotFound is used with the "Accepted" condition when the
+	// policy is attached to an invalid target resource.
+	PolicyReasonTargetNotFound PolicyConditionReason = "TargetNotFound"
+)
+
+// PolicyAncestorStatus describes the status of a route with respect to an
+// associated Ancestor.
+//
+// Ancestors refer to objects that are either the Target of a policy or above it
+// in terms of object hierarchy. For example, if a policy targets a Service, the
+// Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
+// the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most
+// useful object to place Policy status on, so we recommend that implementations
+// SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
+// have a _very_ good reason otherwise.
+//
+// In the context of policy attachment, the Ancestor is used to distinguish which
+// resource results in a distinct application of this policy. For example, if a policy
+// targets a Service, it may have a distinct result per attached Gateway.
+//
+// Policies targeting the same resource may have different effects depending on the
+// ancestors of those resources. For example, different Gateways targeting the same
+// Service may have different capabilities, especially if they have different underlying
+// implementations.
+//
+// For example, in BackendTLSPolicy, the Policy attaches to a Service that is
+// used as a backend in a HTTPRoute that is itself attached to a Gateway.
+// In this case, the relevant object for status is the Gateway, and that is the
+// ancestor object referred to in this status.
+//
+// Note that a parent is also an ancestor, so for objects where the parent is the
+// relevant object for status, this struct SHOULD still be used.
+//
+// This struct is intended to be used in a slice that's effectively a map,
+// with a composite key made up of the AncestorRef and the ControllerName.
+type PolicyAncestorStatus struct {
+	// AncestorRef corresponds with a ParentRef in the spec that this
+	// PolicyAncestorStatus struct describes the status of.
+	// +required
+	AncestorRef ParentReference `json:"ancestorRef"`
+
+	// ControllerName is a domain/path string that indicates the name of the
+	// controller that wrote this status. This corresponds with the
+	// controllerName field on GatewayClass.
+	//
+	// Example: "example.net/gateway-controller".
+	//
+	// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+	// valid Kubernetes names
+	// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+	//
+	// Controllers MUST populate this field when writing status. Controllers should ensure that
+	// entries to status populated with their ControllerName are cleaned up when they are no
+	// longer necessary.
+	// +required
+	ControllerName GatewayController `json:"controllerName"`
+
+	// Conditions describes the status of the Policy with respect to the given Ancestor.
+	//
+	// <gateway:util:excludeFromCRD>
+	//
+	// Notes for implementors:
+	//
+	// Conditions are a listType `map`, which means that they function like a
+	// map with a key of the `type` field _in the k8s apiserver_.
+	//
+	// This means that implementations must obey some rules when updating this
+	// section.
+	//
+	// * Implementations MUST perform a read-modify-write cycle on this field
+	//   before modifying it. That is, when modifying this field, implementations
+	//   must be confident they have fetched the most recent version of this field,
+	//   and ensure that changes they make are on that recent version.
+	// * Implementations MUST NOT remove or reorder Conditions that they are not
+	//   directly responsible for. For example, if an implementation sees a Condition
+	//   with type `special.io/SomeField`, it MUST NOT remove, change or update that
+	//   Condition.
+	// * Implementations MUST always _merge_ changes into Conditions of the same Type,
+	//   rather than creating more than one Condition of the same Type.
+	// * Implementations MUST always update the `observedGeneration` field of the
+	//   Condition to the `metadata.generation` of the Gateway at the time of update creation.
+	// * If the `observedGeneration` of a Condition is _greater than_ the value the
+	//   implementation knows about, then it MUST NOT perform the update on that Condition,
+	//   but must wait for a future reconciliation and status update. (The assumption is that
+	//   the implementation's copy of the object is stale and an update will be re-triggered
+	//   if relevant.)
+	//
+	// </gateway:util:excludeFromCRD>
+	//
+	// +required
+	// +listType=map
+	// +listMapKey=type
+	// +kubebuilder:validation:MinItems=1
+	// +kubebuilder:validation:MaxItems=8
+	Conditions []metav1.Condition `json:"conditions,omitempty"`
+}
+
+// PolicyStatus defines the common attributes that all Policies should include within
+// their status.
+type PolicyStatus struct {
+	// Ancestors is a list of ancestor resources (usually Gateways) that are
+	// associated with the policy, and the status of the policy with respect to
+	// each ancestor. When this policy attaches to a parent, the controller that
+	// manages the parent and the ancestors MUST add an entry to this list when
+	// the controller first sees the policy and SHOULD update the entry as
+	// appropriate when the relevant ancestor is modified.
+	//
+	// Note that choosing the relevant ancestor is left to the Policy designers;
+	// an important part of Policy design is designing the right object level at
+	// which to namespace this status.
+	//
+	// Note also that implementations MUST ONLY populate ancestor status for
+	// the Ancestor resources they are responsible for. Implementations MUST
+	// use the ControllerName field to uniquely identify the entries in this list
+	// that they are responsible for.
+	//
+	// Note that to achieve this, the list of PolicyAncestorStatus structs
+	// MUST be treated as a map with a composite key, made up of the AncestorRef
+	// and ControllerName fields combined.
+	//
+	// A maximum of 16 ancestors will be represented in this list. An empty list
+	// means the Policy is not relevant for any ancestors.
+	//
+	// If this slice is full, implementations MUST NOT add further entries.
+	// Instead they MUST consider the policy unimplementable and signal that
+	// on any related resources such as the ancestor that would be referenced
+	// here. For example, if this list was full on BackendTLSPolicy, no
+	// additional Gateways would be able to reference the Service targeted by
+	// the BackendTLSPolicy.
+	//
+	// +required
+	// +listType=atomic
+	// +kubebuilder:validation:MaxItems=16
+	Ancestors []PolicyAncestorStatus `json:"ancestors"`
+}
diff --git a/apis/v1/zz_generated.deepcopy.go b/apis/v1/zz_generated.deepcopy.go
index be8e2485..174c2927 100644
--- a/apis/v1/zz_generated.deepcopy.go
+++ b/apis/v1/zz_generated.deepcopy.go
@@ -128,6 +128,125 @@ func (in *BackendRef) DeepCopy() *BackendRef {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendTLSPolicy) DeepCopyInto(out *BackendTLSPolicy) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+	in.Spec.DeepCopyInto(&out.Spec)
+	in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSPolicy.
+func (in *BackendTLSPolicy) DeepCopy() *BackendTLSPolicy {
+	if in == nil {
+		return nil
+	}
+	out := new(BackendTLSPolicy)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *BackendTLSPolicy) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendTLSPolicyList) DeepCopyInto(out *BackendTLSPolicyList) {
+	*out = *in
+	out.TypeMeta = in.TypeMeta
+	in.ListMeta.DeepCopyInto(&out.ListMeta)
+	if in.Items != nil {
+		in, out := &in.Items, &out.Items
+		*out = make([]BackendTLSPolicy, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSPolicyList.
+func (in *BackendTLSPolicyList) DeepCopy() *BackendTLSPolicyList {
+	if in == nil {
+		return nil
+	}
+	out := new(BackendTLSPolicyList)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *BackendTLSPolicyList) DeepCopyObject() runtime.Object {
+	if c := in.DeepCopy(); c != nil {
+		return c
+	}
+	return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendTLSPolicySpec) DeepCopyInto(out *BackendTLSPolicySpec) {
+	*out = *in
+	if in.TargetRefs != nil {
+		in, out := &in.TargetRefs, &out.TargetRefs
+		*out = make([]LocalPolicyTargetReferenceWithSectionName, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+	in.Validation.DeepCopyInto(&out.Validation)
+	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 BackendTLSPolicySpec.
+func (in *BackendTLSPolicySpec) DeepCopy() *BackendTLSPolicySpec {
+	if in == nil {
+		return nil
+	}
+	out := new(BackendTLSPolicySpec)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *BackendTLSPolicyValidation) DeepCopyInto(out *BackendTLSPolicyValidation) {
+	*out = *in
+	if in.CACertificateRefs != nil {
+		in, out := &in.CACertificateRefs, &out.CACertificateRefs
+		*out = make([]LocalObjectReference, len(*in))
+		copy(*out, *in)
+	}
+	if in.WellKnownCACertificates != nil {
+		in, out := &in.WellKnownCACertificates, &out.WellKnownCACertificates
+		*out = new(WellKnownCACertificatesType)
+		**out = **in
+	}
+	if in.SubjectAltNames != nil {
+		in, out := &in.SubjectAltNames, &out.SubjectAltNames
+		*out = make([]SubjectAltName, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSPolicyValidation.
+func (in *BackendTLSPolicyValidation) DeepCopy() *BackendTLSPolicyValidation {
+	if in == nil {
+		return nil
+	}
+	out := new(BackendTLSPolicyValidation)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *CommonRouteSpec) DeepCopyInto(out *CommonRouteSpec) {
 	*out = *in
@@ -1724,6 +1843,62 @@ func (in *LocalParametersReference) DeepCopy() *LocalParametersReference {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LocalPolicyTargetReference) DeepCopyInto(out *LocalPolicyTargetReference) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalPolicyTargetReference.
+func (in *LocalPolicyTargetReference) DeepCopy() *LocalPolicyTargetReference {
+	if in == nil {
+		return nil
+	}
+	out := new(LocalPolicyTargetReference)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *LocalPolicyTargetReferenceWithSectionName) DeepCopyInto(out *LocalPolicyTargetReferenceWithSectionName) {
+	*out = *in
+	out.LocalPolicyTargetReference = in.LocalPolicyTargetReference
+	if in.SectionName != nil {
+		in, out := &in.SectionName, &out.SectionName
+		*out = new(SectionName)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalPolicyTargetReferenceWithSectionName.
+func (in *LocalPolicyTargetReferenceWithSectionName) DeepCopy() *LocalPolicyTargetReferenceWithSectionName {
+	if in == nil {
+		return nil
+	}
+	out := new(LocalPolicyTargetReferenceWithSectionName)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *NamespacedPolicyTargetReference) DeepCopyInto(out *NamespacedPolicyTargetReference) {
+	*out = *in
+	if in.Namespace != nil {
+		in, out := &in.Namespace, &out.Namespace
+		*out = new(Namespace)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespacedPolicyTargetReference.
+func (in *NamespacedPolicyTargetReference) DeepCopy() *NamespacedPolicyTargetReference {
+	if in == nil {
+		return nil
+	}
+	out := new(NamespacedPolicyTargetReference)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ObjectReference) DeepCopyInto(out *ObjectReference) {
 	*out = *in
@@ -1804,6 +1979,51 @@ func (in *ParentReference) DeepCopy() *ParentReference {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyAncestorStatus) DeepCopyInto(out *PolicyAncestorStatus) {
+	*out = *in
+	in.AncestorRef.DeepCopyInto(&out.AncestorRef)
+	if in.Conditions != nil {
+		in, out := &in.Conditions, &out.Conditions
+		*out = make([]metav1.Condition, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyAncestorStatus.
+func (in *PolicyAncestorStatus) DeepCopy() *PolicyAncestorStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyAncestorStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PolicyStatus) DeepCopyInto(out *PolicyStatus) {
+	*out = *in
+	if in.Ancestors != nil {
+		in, out := &in.Ancestors, &out.Ancestors
+		*out = make([]PolicyAncestorStatus, len(*in))
+		for i := range *in {
+			(*in)[i].DeepCopyInto(&(*out)[i])
+		}
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyStatus.
+func (in *PolicyStatus) DeepCopy() *PolicyStatus {
+	if in == nil {
+		return nil
+	}
+	out := new(PolicyStatus)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *RouteGroupKind) DeepCopyInto(out *RouteGroupKind) {
 	*out = *in
@@ -1964,6 +2184,21 @@ func (in *SessionPersistence) DeepCopy() *SessionPersistence {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *SubjectAltName) DeepCopyInto(out *SubjectAltName) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubjectAltName.
+func (in *SubjectAltName) DeepCopy() *SubjectAltName {
+	if in == nil {
+		return nil
+	}
+	out := new(SubjectAltName)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *SupportedFeature) DeepCopyInto(out *SupportedFeature) {
 	*out = *in
diff --git a/apis/v1/zz_generated.register.go b/apis/v1/zz_generated.register.go
index 115de0a1..1f390588 100644
--- a/apis/v1/zz_generated.register.go
+++ b/apis/v1/zz_generated.register.go
@@ -61,6 +61,8 @@ func init() {
 // Adds the list of known types to Scheme.
 func addKnownTypes(scheme *runtime.Scheme) error {
 	scheme.AddKnownTypes(SchemeGroupVersion,
+		&BackendTLSPolicy{},
+		&BackendTLSPolicyList{},
 		&GRPCRoute{},
 		&GRPCRouteList{},
 		&Gateway{},
diff --git a/apis/v1alpha2/policy_types.go b/apis/v1alpha2/policy_types.go
index d24bb2ee..8b8181a3 100644
--- a/apis/v1alpha2/policy_types.go
+++ b/apis/v1alpha2/policy_types.go
@@ -16,264 +16,18 @@ limitations under the License.
 
 package v1alpha2
 
-import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+import v1 "sigs.k8s.io/gateway-api/apis/v1"
 
-const (
-	// PolicyLabelKey is the label whose presence identifies a CRD that the
-	// Gateway API Policy attachment model. The value of the label SHOULD be one
-	// of the following:
-	//  - A label value of "Inherited" indicates that this Policy is inheritable.
-	//    An example of inheritable policy is one which if applied at the Gateway
-	//    level would affect all attached HTTPRoutes and their respective
-	//    Backends.
-	//  - A label value of "Direct" indicates that the policy only affects the
-	//    resource to which it is attached and does not affect it's sub resources.
-	PolicyLabelKey = "gateway.networking.k8s.io/policy"
-)
+type LocalPolicyTargetReference v1.LocalPolicyTargetReference
 
-// LocalPolicyTargetReference identifies an API object to apply a direct or
-// inherited policy to. This should be used as part of Policy resources
-// that can target Gateway API resources. For more information on how this
-// policy attachment model works, and a sample Policy resource, refer to
-// the policy attachment documentation for Gateway API.
-type LocalPolicyTargetReference struct {
-	// Group is the group of the target resource.
-	// +required
-	Group Group `json:"group"`
+type NamespacedPolicyTargetReference v1.NamespacedPolicyTargetReference
 
-	// Kind is kind of the target resource.
-	// +required
-	Kind Kind `json:"kind"`
+type LocalPolicyTargetReferenceWithSectionName v1.LocalPolicyTargetReferenceWithSectionName
 
-	// Name is the name of the target resource.
-	// +required
-	Name ObjectName `json:"name"`
-}
+type PolicyConditionType v1.PolicyConditionType
 
-// NamespacedPolicyTargetReference identifies an API object to apply a direct or
-// inherited policy to, potentially in a different namespace. This should only
-// be used as part of Policy resources that need to be able to target resources
-// in different namespaces. For more information on how this policy attachment
-// model works, and a sample Policy resource, refer to the policy attachment
-// documentation for Gateway API.
-type NamespacedPolicyTargetReference struct {
-	// Group is the group of the target resource.
-	// +required
-	Group Group `json:"group"`
+type PolicyConditionReason v1.PolicyConditionReason
 
-	// Kind is kind of the target resource.
-	// +required
-	Kind Kind `json:"kind"`
+type PolicyAncestorStatus v1.PolicyAncestorStatus
 
-	// Name is the name of the target resource.
-	// +required
-	Name ObjectName `json:"name"`
-
-	// Namespace is the namespace of the referent. When unspecified, the local
-	// namespace is inferred. Even when policy targets a resource in a different
-	// namespace, it MUST only apply to traffic originating from the same
-	// namespace as the policy.
-	//
-	// +optional
-	Namespace *Namespace `json:"namespace,omitempty"`
-}
-
-// LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
-// direct policy to. This should be used as part of Policy resources that can
-// target single resources. For more information on how this policy attachment
-// mode works, and a sample Policy resource, refer to the policy attachment
-// documentation for Gateway API.
-//
-// Note: This should only be used for direct policy attachment when references
-// to SectionName are actually needed. In all other cases,
-// LocalPolicyTargetReference should be used.
-type LocalPolicyTargetReferenceWithSectionName struct {
-	LocalPolicyTargetReference `json:",inline"`
-
-	// SectionName is the name of a section within the target resource. When
-	// unspecified, this targetRef targets the entire resource. In the following
-	// resources, SectionName is interpreted as the following:
-	//
-	// * Gateway: Listener name
-	// * HTTPRoute: HTTPRouteRule name
-	// * Service: Port name
-	//
-	// If a SectionName is specified, but does not exist on the targeted object,
-	// the Policy must fail to attach, and the policy implementation should record
-	// a `ResolvedRefs` or similar Condition in the Policy's status.
-	//
-	// +optional
-	SectionName *SectionName `json:"sectionName,omitempty"`
-}
-
-// PolicyConditionType is a type of condition for a policy. This type should be
-// used with a Policy resource Status.Conditions field.
-type PolicyConditionType string
-
-// PolicyConditionReason is a reason for a policy condition.
-type PolicyConditionReason string
-
-const (
-	// PolicyConditionAccepted indicates whether the policy has been accepted or
-	// rejected by a targeted resource, and why.
-	//
-	// Possible reasons for this condition to be True are:
-	//
-	// * "Accepted"
-	//
-	// Possible reasons for this condition to be False are:
-	//
-	// * "Conflicted"
-	// * "Invalid"
-	// * "TargetNotFound"
-	//
-	PolicyConditionAccepted PolicyConditionType = "Accepted"
-
-	// PolicyReasonAccepted is used with the "Accepted" condition when the policy
-	// has been accepted by the targeted resource.
-	PolicyReasonAccepted PolicyConditionReason = "Accepted"
-
-	// PolicyReasonConflicted is used with the "Accepted" condition when the
-	// policy has not been accepted by a targeted resource because there is
-	// another policy that targets the same resource and a merge is not possible.
-	PolicyReasonConflicted PolicyConditionReason = "Conflicted"
-
-	// PolicyReasonInvalid is used with the "Accepted" condition when the policy
-	// is syntactically or semantically invalid.
-	PolicyReasonInvalid PolicyConditionReason = "Invalid"
-
-	// PolicyReasonTargetNotFound is used with the "Accepted" condition when the
-	// policy is attached to an invalid target resource.
-	PolicyReasonTargetNotFound PolicyConditionReason = "TargetNotFound"
-)
-
-// PolicyAncestorStatus describes the status of a route with respect to an
-// associated Ancestor.
-//
-// Ancestors refer to objects that are either the Target of a policy or above it
-// in terms of object hierarchy. For example, if a policy targets a Service, the
-// Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
-// the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most
-// useful object to place Policy status on, so we recommend that implementations
-// SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
-// have a _very_ good reason otherwise.
-//
-// In the context of policy attachment, the Ancestor is used to distinguish which
-// resource results in a distinct application of this policy. For example, if a policy
-// targets a Service, it may have a distinct result per attached Gateway.
-//
-// Policies targeting the same resource may have different effects depending on the
-// ancestors of those resources. For example, different Gateways targeting the same
-// Service may have different capabilities, especially if they have different underlying
-// implementations.
-//
-// For example, in BackendTLSPolicy, the Policy attaches to a Service that is
-// used as a backend in a HTTPRoute that is itself attached to a Gateway.
-// In this case, the relevant object for status is the Gateway, and that is the
-// ancestor object referred to in this status.
-//
-// Note that a parent is also an ancestor, so for objects where the parent is the
-// relevant object for status, this struct SHOULD still be used.
-//
-// This struct is intended to be used in a slice that's effectively a map,
-// with a composite key made up of the AncestorRef and the ControllerName.
-type PolicyAncestorStatus struct {
-	// AncestorRef corresponds with a ParentRef in the spec that this
-	// PolicyAncestorStatus struct describes the status of.
-	// +required
-	AncestorRef ParentReference `json:"ancestorRef"`
-
-	// ControllerName is a domain/path string that indicates the name of the
-	// controller that wrote this status. This corresponds with the
-	// controllerName field on GatewayClass.
-	//
-	// Example: "example.net/gateway-controller".
-	//
-	// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
-	// valid Kubernetes names
-	// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
-	//
-	// Controllers MUST populate this field when writing status. Controllers should ensure that
-	// entries to status populated with their ControllerName are cleaned up when they are no
-	// longer necessary.
-	// +required
-	ControllerName GatewayController `json:"controllerName"`
-
-	// Conditions describes the status of the Policy with respect to the given Ancestor.
-	//
-	// <gateway:util:excludeFromCRD>
-	//
-	// Notes for implementors:
-	//
-	// Conditions are a listType `map`, which means that they function like a
-	// map with a key of the `type` field _in the k8s apiserver_.
-	//
-	// This means that implementations must obey some rules when updating this
-	// section.
-	//
-	// * Implementations MUST perform a read-modify-write cycle on this field
-	//   before modifying it. That is, when modifying this field, implementations
-	//   must be confident they have fetched the most recent version of this field,
-	//   and ensure that changes they make are on that recent version.
-	// * Implementations MUST NOT remove or reorder Conditions that they are not
-	//   directly responsible for. For example, if an implementation sees a Condition
-	//   with type `special.io/SomeField`, it MUST NOT remove, change or update that
-	//   Condition.
-	// * Implementations MUST always _merge_ changes into Conditions of the same Type,
-	//   rather than creating more than one Condition of the same Type.
-	// * Implementations MUST always update the `observedGeneration` field of the
-	//   Condition to the `metadata.generation` of the Gateway at the time of update creation.
-	// * If the `observedGeneration` of a Condition is _greater than_ the value the
-	//   implementation knows about, then it MUST NOT perform the update on that Condition,
-	//   but must wait for a future reconciliation and status update. (The assumption is that
-	//   the implementation's copy of the object is stale and an update will be re-triggered
-	//   if relevant.)
-	//
-	// </gateway:util:excludeFromCRD>
-	//
-	// +required
-	// +listType=map
-	// +listMapKey=type
-	// +kubebuilder:validation:MinItems=1
-	// +kubebuilder:validation:MaxItems=8
-	Conditions []metav1.Condition `json:"conditions,omitempty"`
-}
-
-// PolicyStatus defines the common attributes that all Policies should include within
-// their status.
-type PolicyStatus struct {
-	// Ancestors is a list of ancestor resources (usually Gateways) that are
-	// associated with the policy, and the status of the policy with respect to
-	// each ancestor. When this policy attaches to a parent, the controller that
-	// manages the parent and the ancestors MUST add an entry to this list when
-	// the controller first sees the policy and SHOULD update the entry as
-	// appropriate when the relevant ancestor is modified.
-	//
-	// Note that choosing the relevant ancestor is left to the Policy designers;
-	// an important part of Policy design is designing the right object level at
-	// which to namespace this status.
-	//
-	// Note also that implementations MUST ONLY populate ancestor status for
-	// the Ancestor resources they are responsible for. Implementations MUST
-	// use the ControllerName field to uniquely identify the entries in this list
-	// that they are responsible for.
-	//
-	// Note that to achieve this, the list of PolicyAncestorStatus structs
-	// MUST be treated as a map with a composite key, made up of the AncestorRef
-	// and ControllerName fields combined.
-	//
-	// A maximum of 16 ancestors will be represented in this list. An empty list
-	// means the Policy is not relevant for any ancestors.
-	//
-	// If this slice is full, implementations MUST NOT add further entries.
-	// Instead they MUST consider the policy unimplementable and signal that
-	// on any related resources such as the ancestor that would be referenced
-	// here. For example, if this list was full on BackendTLSPolicy, no
-	// additional Gateways would be able to reference the Service targeted by
-	// the BackendTLSPolicy.
-	//
-	// +required
-	// +listType=atomic
-	// +kubebuilder:validation:MaxItems=16
-	Ancestors []PolicyAncestorStatus `json:"ancestors"`
-}
+type PolicyStatus v1.PolicyStatus
diff --git a/apis/v1alpha2/zz_generated.deepcopy.go b/apis/v1alpha2/zz_generated.deepcopy.go
index 8b09c2d7..486af9f0 100644
--- a/apis/v1alpha2/zz_generated.deepcopy.go
+++ b/apis/v1alpha2/zz_generated.deepcopy.go
@@ -21,8 +21,9 @@ limitations under the License.
 package v1alpha2
 
 import (
-	"k8s.io/apimachinery/pkg/apis/meta/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	runtime "k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/gateway-api/apis/v1"
 )
 
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
@@ -102,10 +103,10 @@ func (in *LocalPolicyTargetReference) DeepCopy() *LocalPolicyTargetReference {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *LocalPolicyTargetReferenceWithSectionName) DeepCopyInto(out *LocalPolicyTargetReferenceWithSectionName) {
 	*out = *in
-	in.LocalPolicyTargetReference.DeepCopyInto(&out.LocalPolicyTargetReference)
+	out.LocalPolicyTargetReference = in.LocalPolicyTargetReference
 	if in.SectionName != nil {
 		in, out := &in.SectionName, &out.SectionName
-		*out = new(SectionName)
+		*out = new(v1.SectionName)
 		**out = **in
 	}
 }
@@ -125,7 +126,7 @@ func (in *NamespacedPolicyTargetReference) DeepCopyInto(out *NamespacedPolicyTar
 	*out = *in
 	if in.Namespace != nil {
 		in, out := &in.Namespace, &out.Namespace
-		*out = new(Namespace)
+		*out = new(v1.Namespace)
 		**out = **in
 	}
 }
@@ -146,7 +147,7 @@ func (in *PolicyAncestorStatus) DeepCopyInto(out *PolicyAncestorStatus) {
 	in.AncestorRef.DeepCopyInto(&out.AncestorRef)
 	if in.Conditions != nil {
 		in, out := &in.Conditions, &out.Conditions
-		*out = make([]v1.Condition, len(*in))
+		*out = make([]metav1.Condition, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
@@ -168,7 +169,7 @@ func (in *PolicyStatus) DeepCopyInto(out *PolicyStatus) {
 	*out = *in
 	if in.Ancestors != nil {
 		in, out := &in.Ancestors, &out.Ancestors
-		*out = make([]PolicyAncestorStatus, len(*in))
+		*out = make([]v1.PolicyAncestorStatus, len(*in))
 		for i := range *in {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
diff --git a/apis/v1alpha3/backendtlspolicy_types.go b/apis/v1alpha3/backendtlspolicy_types.go
index cbd2c464..4917063b 100644
--- a/apis/v1alpha3/backendtlspolicy_types.go
+++ b/apis/v1alpha3/backendtlspolicy_types.go
@@ -20,304 +20,16 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 
 	v1 "sigs.k8s.io/gateway-api/apis/v1"
-	"sigs.k8s.io/gateway-api/apis/v1alpha2"
 )
 
 // +genclient
 // +kubebuilder:object:root=true
-// +kubebuilder:subresource:status
-// +kubebuilder:storageversion
-// +kubebuilder:resource:categories=gateway-api,shortName=btlspolicy
-// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
-//
-// BackendTLSPolicy is a Direct Attached Policy.
-// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=Direct"
+// +kubebuilder:deprecatedversion:warning="The v1alpha3 version of BackendTLSPolicy has been deprecated and will be removed in a future release of the API. Please upgrade to v1."
+type BackendTLSPolicy v1.BackendTLSPolicy
 
-// BackendTLSPolicy provides a way to configure how a Gateway
-// connects to a Backend via TLS.
-type BackendTLSPolicy struct {
-	metav1.TypeMeta `json:",inline"`
-	// +optional
-	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	// Spec defines the desired state of BackendTLSPolicy.
-	// +required
-	Spec BackendTLSPolicySpec `json:"spec"`
-
-	// Status defines the current state of BackendTLSPolicy.
-	// +optional
-	Status v1alpha2.PolicyStatus `json:"status,omitempty"`
-}
-
-// BackendTLSPolicyList contains a list of BackendTLSPolicies
 // +kubebuilder:object:root=true
 type BackendTLSPolicyList struct {
 	metav1.TypeMeta `json:",inline"`
 	metav1.ListMeta `json:"metadata,omitempty"`
 	Items           []BackendTLSPolicy `json:"items"`
 }
-
-// BackendTLSPolicySpec defines the desired state of BackendTLSPolicy.
-//
-// Support: Extended
-type BackendTLSPolicySpec struct {
-	// TargetRefs identifies an API object to apply the policy to.
-	// Only Services have Extended support. Implementations MAY support
-	// additional objects, with Implementation Specific support.
-	// Note that this config applies to the entire referenced resource
-	// by default, but this default may change in the future to provide
-	// a more granular application of the policy.
-	//
-	// TargetRefs must be _distinct_. This means either that:
-	//
-	// * They select different targets. If this is the case, then targetRef
-	//   entries are distinct. In terms of fields, this means that the
-	//   multi-part key defined by `group`, `kind`, and `name` must
-	//   be unique across all targetRef entries in the BackendTLSPolicy.
-	// * They select different sectionNames in the same target.
-	//
-	//
-	// When more than one BackendTLSPolicy selects the same target and
-	// sectionName, implementations MUST determine precedence using the
-	// following criteria, continuing on ties:
-	//
-	// * The older policy by creation timestamp takes precedence. For
-	//   example, a policy with a creation timestamp of "2021-07-15
-	//   01:02:03" MUST be given precedence over a policy with a
-	//   creation timestamp of "2021-07-15 01:02:04".
-	// * The policy appearing first in alphabetical order by {name}.
-	//   For example, a policy named `bar` is given precedence over a
-	//   policy named `baz`.
-	//
-	// For any BackendTLSPolicy that does not take precedence, the
-	// implementation MUST ensure the `Accepted` Condition is set to
-	// `status: False`, with Reason `Conflicted`.
-	//
-	// Support: Extended for Kubernetes Service
-	//
-	// Support: Implementation-specific for any other resource
-	//
-	// +required
-	// +listType=atomic
-	// +kubebuilder:validation:MinItems=1
-	// +kubebuilder:validation:MaxItems=16
-	// +kubebuilder:validation:XValidation:message="sectionName must be specified when targetRefs includes 2 or more references to the same target",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))"
-	// +kubebuilder:validation:XValidation:message="sectionName must be unique when targetRefs includes 2 or more references to the same target",rule="self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))"
-	TargetRefs []v1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"`
-
-	// Validation contains backend TLS validation configuration.
-	// +required
-	Validation BackendTLSPolicyValidation `json:"validation"`
-
-	// 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.
-	//
-	// A 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.
-	//
-	// Support: Implementation-specific
-	//
-	// +optional
-	// +kubebuilder:validation:MaxProperties=16
-	Options map[v1.AnnotationKey]v1.AnnotationValue `json:"options,omitempty"`
-}
-
-// BackendTLSPolicyValidation contains backend TLS validation configuration.
-// +kubebuilder:validation:XValidation:message="must not contain both CACertificateRefs and WellKnownCACertificates",rule="!(has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")"
-// +kubebuilder:validation:XValidation:message="must specify either CACertificateRefs or WellKnownCACertificates",rule="(has(self.caCertificateRefs) && size(self.caCertificateRefs) > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates != \"\")"
-type BackendTLSPolicyValidation struct {
-	// CACertificateRefs contains one or more references to Kubernetes objects that
-	// contain a PEM-encoded TLS CA certificate bundle, which is used to
-	// validate a TLS handshake between the Gateway and backend Pod.
-	//
-	// If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
-	// specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
-	// not both. If CACertificateRefs is empty or unspecified, the configuration for
-	// WellKnownCACertificates MUST be honored instead if supported by the implementation.
-	//
-	// A CACertificateRef is invalid if:
-	//
-	// * It refers to a resource that cannot be resolved (e.g., the referenced resource
-	//   does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key
-	//   named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`
-	//   and the Message of the Condition must indicate which reference is invalid and why.
-	//
-	// * It refers to an unknown or unsupported kind of resource. In this case, the Reason
-	//   must be set to `InvalidKind` and the Message of the Condition must explain which
-	//   kind of resource is unknown or unsupported.
-	//
-	// * It refers to a resource in another namespace. This may change in future
-	//   spec updates.
-	//
-	// Implementations MAY choose to perform further validation of the certificate
-	// content (e.g., checking expiry or enforcing specific formats). In such cases,
-	// an implementation-specific Reason and Message must be set for the invalid reference.
-	//
-	// In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on
-	// the BackendTLSPolicy is set to `status: False`, with a Reason and Message
-	// that indicate the cause of the error. Connections using an invalid
-	// CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error
-	// response. If ALL CACertificateRefs are invalid, the implementation MUST also
-	// ensure the `Accepted` Condition on the BackendTLSPolicy is set to
-	// `status: False`, with a Reason `NoValidCACertificate`.
-	//
-	//
-	// A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
-	// Implementations MAY choose to support attaching multiple certificates to
-	// a backend, but this behavior is implementation-specific.
-	//
-	// Support: Core - An optional single reference to a Kubernetes ConfigMap,
-	// with the CA certificate in a key named `ca.crt`.
-	//
-	// Support: Implementation-specific - More than one reference, other kinds
-	// of resources, or a single reference that includes multiple certificates.
-	//
-	// +optional
-	// +listType=atomic
-	// +kubebuilder:validation:MaxItems=8
-	CACertificateRefs []v1.LocalObjectReference `json:"caCertificateRefs,omitempty"`
-
-	// WellKnownCACertificates specifies whether system CA certificates may be used in
-	// the TLS handshake between the gateway and backend pod.
-	//
-	// If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
-	// must be specified with at least one entry for a valid configuration. Only one of
-	// CACertificateRefs or WellKnownCACertificates may be specified, not both.
-	// If an implementation does not support the WellKnownCACertificates field, or
-	// the supplied value is not recognized, the implementation MUST ensure the
-	// `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with
-	// a Reason `Invalid`.
-	//
-	// Support: Implementation-specific
-	//
-	// +optional
-	// +listType=atomic
-	WellKnownCACertificates *WellKnownCACertificatesType `json:"wellKnownCACertificates,omitempty"`
-
-	// Hostname is used for two purposes in the connection between Gateways and
-	// backends:
-	//
-	// 1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
-	// 2. Hostname MUST be used for authentication and MUST match the certificate
-	//    served by the matching backend, unless SubjectAltNames is specified.
-	// 3. If SubjectAltNames are specified, Hostname can be used for certificate selection
-	//    but MUST NOT be used for authentication. If you want to use the value
-	//    of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.
-	//
-	// Support: Core
-	//
-	// +required
-	Hostname v1.PreciseHostname `json:"hostname"`
-
-	// SubjectAltNames contains one or more Subject Alternative Names.
-	// When specified the certificate served from the backend MUST
-	// have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
-	//
-	// Support: Extended
-	//
-	// +optional
-	// +listType=atomic
-	// +kubebuilder:validation:MaxItems=5
-	SubjectAltNames []SubjectAltName `json:"subjectAltNames,omitempty"`
-}
-
-// SubjectAltName represents Subject Alternative Name.
-// +kubebuilder:validation:XValidation:message="SubjectAltName element must contain Hostname, if Type is set to Hostname",rule="!(self.type == \"Hostname\" && (!has(self.hostname) || self.hostname == \"\"))"
-// +kubebuilder:validation:XValidation:message="SubjectAltName element must not contain Hostname, if Type is not set to Hostname",rule="!(self.type != \"Hostname\" && has(self.hostname) && self.hostname != \"\")"
-// +kubebuilder:validation:XValidation:message="SubjectAltName element must contain URI, if Type is set to URI",rule="!(self.type == \"URI\" && (!has(self.uri) || self.uri == \"\"))"
-// +kubebuilder:validation:XValidation:message="SubjectAltName element must not contain URI, if Type is not set to URI",rule="!(self.type != \"URI\" && has(self.uri) && self.uri != \"\")"
-type SubjectAltName struct {
-	// Type determines the format of the Subject Alternative Name. Always required.
-	//
-	// Support: Core
-	//
-	// +required
-	Type SubjectAltNameType `json:"type"`
-
-	// Hostname contains Subject Alternative Name specified in DNS name format.
-	// Required when Type is set to Hostname, ignored otherwise.
-	//
-	// Support: Core
-	//
-	// +optional
-	Hostname v1.Hostname `json:"hostname,omitempty"`
-
-	// URI contains Subject Alternative Name specified in a full URI format.
-	// It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
-	// Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
-	// Required when Type is set to URI, ignored otherwise.
-	//
-	// Support: Core
-	//
-	// +optional
-	URI v1.AbsoluteURI `json:"uri,omitempty"`
-}
-
-// WellKnownCACertificatesType is the type of CA certificate that will be used
-// when the caCertificateRefs field is unspecified.
-// +kubebuilder:validation:Enum=System
-type WellKnownCACertificatesType string
-
-const (
-	// WellKnownCACertificatesSystem indicates that well known system CA certificates should be used.
-	WellKnownCACertificatesSystem WellKnownCACertificatesType = "System"
-)
-
-// SubjectAltNameType is the type of the Subject Alternative Name.
-// +kubebuilder:validation:Enum=Hostname;URI
-type SubjectAltNameType string
-
-const (
-	// HostnameSubjectAltNameType specifies hostname-based SAN.
-	//
-	// Support: Core
-	HostnameSubjectAltNameType SubjectAltNameType = "Hostname"
-
-	// URISubjectAltNameType specifies URI-based SAN, e.g. SPIFFE id.
-	//
-	// Support: Core
-	URISubjectAltNameType SubjectAltNameType = "URI"
-)
-
-const (
-	// This reason is used with the "Accepted" condition when it is
-	// set to false because all CACertificateRefs of the
-	// BackendTLSPolicy are invalid.
-	BackendTLSPolicyReasonNoValidCACertificate v1alpha2.PolicyConditionReason = "NoValidCACertificate"
-)
-
-const (
-	// This condition indicates whether the controller was able to resolve all
-	// object references for the BackendTLSPolicy.
-	//
-	// Possible reasons for this condition to be True are:
-	//
-	// * "ResolvedRefs"
-	//
-	// Possible reasons for this condition to be False are:
-	//
-	// * "InvalidCACertificateRef"
-	// * "InvalidKind"
-	//
-	// Controllers may raise this condition with other reasons, but should
-	// prefer to use the reasons listed above to improve interoperability.
-	BackendTLSPolicyConditionResolvedRefs v1alpha2.PolicyConditionType = "ResolvedRefs"
-
-	// This reason is used with the "ResolvedRefs" condition when the condition
-	// is true.
-	BackendTLSPolicyReasonResolvedRefs v1alpha2.PolicyConditionReason = "ResolvedRefs"
-
-	// This reason is used with the "ResolvedRefs" condition when one of the
-	// BackendTLSPolicy's CACertificateRefs is invalid.
-	// A CACertificateRef is considered invalid when it refers to a nonexistent
-	// resource or when the data within that resource is malformed.
-	BackendTLSPolicyReasonInvalidCACertificateRef v1alpha2.PolicyConditionReason = "InvalidCACertificateRef"
-
-	// This reason is used with the "ResolvedRefs" condition when one of the
-	// BackendTLSPolicy's CACertificateRefs references an unknown or unsupported
-	// Group and/or Kind.
-	BackendTLSPolicyReasonInvalidKind v1alpha2.PolicyConditionReason = "InvalidKind"
-)
diff --git a/apis/v1alpha3/zz_generated.deepcopy.go b/apis/v1alpha3/zz_generated.deepcopy.go
index 9b659ead..479672b6 100644
--- a/apis/v1alpha3/zz_generated.deepcopy.go
+++ b/apis/v1alpha3/zz_generated.deepcopy.go
@@ -22,7 +22,6 @@ package v1alpha3
 
 import (
 	runtime "k8s.io/apimachinery/pkg/runtime"
-	"sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/apis/v1alpha2"
 )
 
@@ -85,81 +84,6 @@ func (in *BackendTLSPolicyList) DeepCopyObject() runtime.Object {
 	return nil
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BackendTLSPolicySpec) DeepCopyInto(out *BackendTLSPolicySpec) {
-	*out = *in
-	if in.TargetRefs != nil {
-		in, out := &in.TargetRefs, &out.TargetRefs
-		*out = make([]v1alpha2.LocalPolicyTargetReferenceWithSectionName, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
-	}
-	in.Validation.DeepCopyInto(&out.Validation)
-	if in.Options != nil {
-		in, out := &in.Options, &out.Options
-		*out = make(map[v1.AnnotationKey]v1.AnnotationValue, len(*in))
-		for key, val := range *in {
-			(*out)[key] = val
-		}
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSPolicySpec.
-func (in *BackendTLSPolicySpec) DeepCopy() *BackendTLSPolicySpec {
-	if in == nil {
-		return nil
-	}
-	out := new(BackendTLSPolicySpec)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *BackendTLSPolicyValidation) DeepCopyInto(out *BackendTLSPolicyValidation) {
-	*out = *in
-	if in.CACertificateRefs != nil {
-		in, out := &in.CACertificateRefs, &out.CACertificateRefs
-		*out = make([]v1.LocalObjectReference, len(*in))
-		copy(*out, *in)
-	}
-	if in.WellKnownCACertificates != nil {
-		in, out := &in.WellKnownCACertificates, &out.WellKnownCACertificates
-		*out = new(WellKnownCACertificatesType)
-		**out = **in
-	}
-	if in.SubjectAltNames != nil {
-		in, out := &in.SubjectAltNames, &out.SubjectAltNames
-		*out = make([]SubjectAltName, len(*in))
-		copy(*out, *in)
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTLSPolicyValidation.
-func (in *BackendTLSPolicyValidation) DeepCopy() *BackendTLSPolicyValidation {
-	if in == nil {
-		return nil
-	}
-	out := new(BackendTLSPolicyValidation)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *SubjectAltName) DeepCopyInto(out *SubjectAltName) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SubjectAltName.
-func (in *SubjectAltName) DeepCopy() *SubjectAltName {
-	if in == nil {
-		return nil
-	}
-	out := new(SubjectAltName)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *TLSRoute) DeepCopyInto(out *TLSRoute) {
 	*out = *in
diff --git a/apisx/v1alpha1/shared_types.go b/apisx/v1alpha1/shared_types.go
index 01331bf8..94851df2 100644
--- a/apisx/v1alpha1/shared_types.go
+++ b/apisx/v1alpha1/shared_types.go
@@ -18,7 +18,6 @@ package v1alpha1
 
 import (
 	v1 "sigs.k8s.io/gateway-api/apis/v1"
-	v1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
 )
 
 type (
@@ -34,8 +33,8 @@ type (
 	SectionName                = v1.SectionName
 	Namespace                  = v1.Namespace
 	Duration                   = v1.Duration
-	PolicyStatus               = v1alpha2.PolicyStatus
-	LocalPolicyTargetReference = v1alpha2.LocalPolicyTargetReference
+	PolicyStatus               = v1.PolicyStatus
+	LocalPolicyTargetReference = v1.LocalPolicyTargetReference
 	SessionPersistence         = v1.SessionPersistence
 )
 
diff --git a/apisx/v1alpha1/zz_generated.deepcopy.go b/apisx/v1alpha1/zz_generated.deepcopy.go
index d8bc7aa8..9e93ad9e 100644
--- a/apisx/v1alpha1/zz_generated.deepcopy.go
+++ b/apisx/v1alpha1/zz_generated.deepcopy.go
@@ -32,9 +32,7 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec)
 	if in.TargetRefs != nil {
 		in, out := &in.TargetRefs, &out.TargetRefs
 		*out = make([]LocalPolicyTargetReference, len(*in))
-		for i := range *in {
-			(*in)[i].DeepCopyInto(&(*out)[i])
-		}
+		copy(*out, *in)
 	}
 	if in.RetryConstraint != nil {
 		in, out := &in.RetryConstraint, &out.RetryConstraint
diff --git a/applyconfiguration/apis/v1/backendtlspolicy.go b/applyconfiguration/apis/v1/backendtlspolicy.go
new file mode 100644
index 00000000..4b33502d
--- /dev/null
+++ b/applyconfiguration/apis/v1/backendtlspolicy.go
@@ -0,0 +1,281 @@
+/*
+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 (
+	apismetav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	types "k8s.io/apimachinery/pkg/types"
+	managedfields "k8s.io/apimachinery/pkg/util/managedfields"
+	metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+	internal "sigs.k8s.io/gateway-api/applyconfiguration/internal"
+)
+
+// BackendTLSPolicyApplyConfiguration represents a declarative configuration of the BackendTLSPolicy type for use
+// with apply.
+type BackendTLSPolicyApplyConfiguration struct {
+	metav1.TypeMetaApplyConfiguration    `json:",inline"`
+	*metav1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
+	Spec                                 *BackendTLSPolicySpecApplyConfiguration `json:"spec,omitempty"`
+	Status                               *PolicyStatusApplyConfiguration         `json:"status,omitempty"`
+}
+
+// BackendTLSPolicy constructs a declarative configuration of the BackendTLSPolicy type for use with
+// apply.
+func BackendTLSPolicy(name, namespace string) *BackendTLSPolicyApplyConfiguration {
+	b := &BackendTLSPolicyApplyConfiguration{}
+	b.WithName(name)
+	b.WithNamespace(namespace)
+	b.WithKind("BackendTLSPolicy")
+	b.WithAPIVersion("gateway.networking.k8s.io/v1")
+	return b
+}
+
+// ExtractBackendTLSPolicy extracts the applied configuration owned by fieldManager from
+// backendTLSPolicy. If no managedFields are found in backendTLSPolicy for fieldManager, a
+// BackendTLSPolicyApplyConfiguration is returned with only the Name, Namespace (if applicable),
+// APIVersion and Kind populated. It is possible that no managed fields were found for because other
+// field managers have taken ownership of all the fields previously owned by fieldManager, or because
+// the fieldManager never owned fields any fields.
+// backendTLSPolicy must be a unmodified BackendTLSPolicy API object that was retrieved from the Kubernetes API.
+// ExtractBackendTLSPolicy provides a way to perform a extract/modify-in-place/apply workflow.
+// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously
+// applied if another fieldManager has updated or force applied any of the previously applied fields.
+// Experimental!
+func ExtractBackendTLSPolicy(backendTLSPolicy *apisv1.BackendTLSPolicy, fieldManager string) (*BackendTLSPolicyApplyConfiguration, error) {
+	return extractBackendTLSPolicy(backendTLSPolicy, fieldManager, "")
+}
+
+// ExtractBackendTLSPolicyStatus is the same as ExtractBackendTLSPolicy except
+// that it extracts the status subresource applied configuration.
+// Experimental!
+func ExtractBackendTLSPolicyStatus(backendTLSPolicy *apisv1.BackendTLSPolicy, fieldManager string) (*BackendTLSPolicyApplyConfiguration, error) {
+	return extractBackendTLSPolicy(backendTLSPolicy, fieldManager, "status")
+}
+
+func extractBackendTLSPolicy(backendTLSPolicy *apisv1.BackendTLSPolicy, fieldManager string, subresource string) (*BackendTLSPolicyApplyConfiguration, error) {
+	b := &BackendTLSPolicyApplyConfiguration{}
+	err := managedfields.ExtractInto(backendTLSPolicy, internal.Parser().Type("io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicy"), fieldManager, b, subresource)
+	if err != nil {
+		return nil, err
+	}
+	b.WithName(backendTLSPolicy.Name)
+	b.WithNamespace(backendTLSPolicy.Namespace)
+
+	b.WithKind("BackendTLSPolicy")
+	b.WithAPIVersion("gateway.networking.k8s.io/v1")
+	return b, nil
+}
+func (b BackendTLSPolicyApplyConfiguration) IsApplyConfiguration() {}
+
+// WithKind sets the Kind 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 Kind field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithKind(value string) *BackendTLSPolicyApplyConfiguration {
+	b.TypeMetaApplyConfiguration.Kind = &value
+	return b
+}
+
+// WithAPIVersion sets the APIVersion 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 APIVersion field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithAPIVersion(value string) *BackendTLSPolicyApplyConfiguration {
+	b.TypeMetaApplyConfiguration.APIVersion = &value
+	return b
+}
+
+// WithName sets the Name 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 Name field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithName(value string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Name = &value
+	return b
+}
+
+// WithGenerateName sets the GenerateName 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 GenerateName field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithGenerateName(value string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.GenerateName = &value
+	return b
+}
+
+// WithNamespace sets the Namespace 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 Namespace field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithNamespace(value string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Namespace = &value
+	return b
+}
+
+// WithUID sets the UID 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 UID field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithUID(value types.UID) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.UID = &value
+	return b
+}
+
+// WithResourceVersion sets the ResourceVersion 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 ResourceVersion field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithResourceVersion(value string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.ResourceVersion = &value
+	return b
+}
+
+// WithGeneration sets the Generation 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 Generation field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithGeneration(value int64) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.Generation = &value
+	return b
+}
+
+// WithCreationTimestamp sets the CreationTimestamp 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 CreationTimestamp field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithCreationTimestamp(value apismetav1.Time) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
+	return b
+}
+
+// WithDeletionTimestamp sets the DeletionTimestamp 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 DeletionTimestamp field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithDeletionTimestamp(value apismetav1.Time) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
+	return b
+}
+
+// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds 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 DeletionGracePeriodSeconds field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
+	return b
+}
+
+// WithLabels puts the entries into the Labels 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 Labels field,
+// overwriting an existing map entries in Labels field with the same key.
+func (b *BackendTLSPolicyApplyConfiguration) WithLabels(entries map[string]string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
+	}
+	for k, v := range entries {
+		b.ObjectMetaApplyConfiguration.Labels[k] = v
+	}
+	return b
+}
+
+// WithAnnotations puts the entries into the Annotations 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 Annotations field,
+// overwriting an existing map entries in Annotations field with the same key.
+func (b *BackendTLSPolicyApplyConfiguration) WithAnnotations(entries map[string]string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
+	}
+	for k, v := range entries {
+		b.ObjectMetaApplyConfiguration.Annotations[k] = v
+	}
+	return b
+}
+
+// WithOwnerReferences adds the given value to the OwnerReferences 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 OwnerReferences field.
+func (b *BackendTLSPolicyApplyConfiguration) WithOwnerReferences(values ...*metav1.OwnerReferenceApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithOwnerReferences")
+		}
+		b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
+	}
+	return b
+}
+
+// WithFinalizers adds the given value to the Finalizers 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 Finalizers field.
+func (b *BackendTLSPolicyApplyConfiguration) WithFinalizers(values ...string) *BackendTLSPolicyApplyConfiguration {
+	b.ensureObjectMetaApplyConfigurationExists()
+	for i := range values {
+		b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
+	}
+	return b
+}
+
+func (b *BackendTLSPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationExists() {
+	if b.ObjectMetaApplyConfiguration == nil {
+		b.ObjectMetaApplyConfiguration = &metav1.ObjectMetaApplyConfiguration{}
+	}
+}
+
+// WithSpec sets the Spec 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 Spec field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithSpec(value *BackendTLSPolicySpecApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
+	b.Spec = value
+	return b
+}
+
+// WithStatus sets the Status 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 Status field is set to the value of the last call.
+func (b *BackendTLSPolicyApplyConfiguration) WithStatus(value *PolicyStatusApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
+	b.Status = value
+	return b
+}
+
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *BackendTLSPolicyApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *BackendTLSPolicyApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
+// GetName retrieves the value of the Name field in the declarative configuration.
+func (b *BackendTLSPolicyApplyConfiguration) GetName() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Name
+}
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *BackendTLSPolicyApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/applyconfiguration/apis/v1/backendtlspolicyspec.go b/applyconfiguration/apis/v1/backendtlspolicyspec.go
new file mode 100644
index 00000000..b6d8d972
--- /dev/null
+++ b/applyconfiguration/apis/v1/backendtlspolicyspec.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"
+)
+
+// BackendTLSPolicySpecApplyConfiguration represents a declarative configuration of the BackendTLSPolicySpec type for use
+// with apply.
+type BackendTLSPolicySpecApplyConfiguration struct {
+	TargetRefs []LocalPolicyTargetReferenceWithSectionNameApplyConfiguration `json:"targetRefs,omitempty"`
+	Validation *BackendTLSPolicyValidationApplyConfiguration                 `json:"validation,omitempty"`
+	Options    map[apisv1.AnnotationKey]apisv1.AnnotationValue               `json:"options,omitempty"`
+}
+
+// BackendTLSPolicySpecApplyConfiguration constructs a declarative configuration of the BackendTLSPolicySpec type for use with
+// apply.
+func BackendTLSPolicySpec() *BackendTLSPolicySpecApplyConfiguration {
+	return &BackendTLSPolicySpecApplyConfiguration{}
+}
+
+// WithTargetRefs adds the given value to the TargetRefs 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 TargetRefs field.
+func (b *BackendTLSPolicySpecApplyConfiguration) WithTargetRefs(values ...*LocalPolicyTargetReferenceWithSectionNameApplyConfiguration) *BackendTLSPolicySpecApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithTargetRefs")
+		}
+		b.TargetRefs = append(b.TargetRefs, *values[i])
+	}
+	return b
+}
+
+// WithValidation sets the Validation field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Validation field is set to the value of the last call.
+func (b *BackendTLSPolicySpecApplyConfiguration) WithValidation(value *BackendTLSPolicyValidationApplyConfiguration) *BackendTLSPolicySpecApplyConfiguration {
+	b.Validation = 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 *BackendTLSPolicySpecApplyConfiguration) WithOptions(entries map[apisv1.AnnotationKey]apisv1.AnnotationValue) *BackendTLSPolicySpecApplyConfiguration {
+	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/backendtlspolicyvalidation.go b/applyconfiguration/apis/v1/backendtlspolicyvalidation.go
new file mode 100644
index 00000000..db18fc4e
--- /dev/null
+++ b/applyconfiguration/apis/v1/backendtlspolicyvalidation.go
@@ -0,0 +1,80 @@
+/*
+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"
+)
+
+// BackendTLSPolicyValidationApplyConfiguration represents a declarative configuration of the BackendTLSPolicyValidation type for use
+// with apply.
+type BackendTLSPolicyValidationApplyConfiguration struct {
+	CACertificateRefs       []LocalObjectReferenceApplyConfiguration `json:"caCertificateRefs,omitempty"`
+	WellKnownCACertificates *apisv1.WellKnownCACertificatesType      `json:"wellKnownCACertificates,omitempty"`
+	Hostname                *apisv1.PreciseHostname                  `json:"hostname,omitempty"`
+	SubjectAltNames         []SubjectAltNameApplyConfiguration       `json:"subjectAltNames,omitempty"`
+}
+
+// BackendTLSPolicyValidationApplyConfiguration constructs a declarative configuration of the BackendTLSPolicyValidation type for use with
+// apply.
+func BackendTLSPolicyValidation() *BackendTLSPolicyValidationApplyConfiguration {
+	return &BackendTLSPolicyValidationApplyConfiguration{}
+}
+
+// WithCACertificateRefs adds the given value to the CACertificateRefs 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 CACertificateRefs field.
+func (b *BackendTLSPolicyValidationApplyConfiguration) WithCACertificateRefs(values ...*LocalObjectReferenceApplyConfiguration) *BackendTLSPolicyValidationApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithCACertificateRefs")
+		}
+		b.CACertificateRefs = append(b.CACertificateRefs, *values[i])
+	}
+	return b
+}
+
+// WithWellKnownCACertificates sets the WellKnownCACertificates 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 WellKnownCACertificates field is set to the value of the last call.
+func (b *BackendTLSPolicyValidationApplyConfiguration) WithWellKnownCACertificates(value apisv1.WellKnownCACertificatesType) *BackendTLSPolicyValidationApplyConfiguration {
+	b.WellKnownCACertificates = &value
+	return b
+}
+
+// WithHostname sets the Hostname 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 Hostname field is set to the value of the last call.
+func (b *BackendTLSPolicyValidationApplyConfiguration) WithHostname(value apisv1.PreciseHostname) *BackendTLSPolicyValidationApplyConfiguration {
+	b.Hostname = &value
+	return b
+}
+
+// WithSubjectAltNames adds the given value to the SubjectAltNames 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 SubjectAltNames field.
+func (b *BackendTLSPolicyValidationApplyConfiguration) WithSubjectAltNames(values ...*SubjectAltNameApplyConfiguration) *BackendTLSPolicyValidationApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithSubjectAltNames")
+		}
+		b.SubjectAltNames = append(b.SubjectAltNames, *values[i])
+	}
+	return b
+}
diff --git a/applyconfiguration/apis/v1/localpolicytargetreference.go b/applyconfiguration/apis/v1/localpolicytargetreference.go
new file mode 100644
index 00000000..2265b318
--- /dev/null
+++ b/applyconfiguration/apis/v1/localpolicytargetreference.go
@@ -0,0 +1,61 @@
+/*
+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"
+)
+
+// LocalPolicyTargetReferenceApplyConfiguration represents a declarative configuration of the LocalPolicyTargetReference type for use
+// with apply.
+type LocalPolicyTargetReferenceApplyConfiguration struct {
+	Group *apisv1.Group      `json:"group,omitempty"`
+	Kind  *apisv1.Kind       `json:"kind,omitempty"`
+	Name  *apisv1.ObjectName `json:"name,omitempty"`
+}
+
+// LocalPolicyTargetReferenceApplyConfiguration constructs a declarative configuration of the LocalPolicyTargetReference type for use with
+// apply.
+func LocalPolicyTargetReference() *LocalPolicyTargetReferenceApplyConfiguration {
+	return &LocalPolicyTargetReferenceApplyConfiguration{}
+}
+
+// WithGroup sets the Group 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 Group field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceApplyConfiguration) WithGroup(value apisv1.Group) *LocalPolicyTargetReferenceApplyConfiguration {
+	b.Group = &value
+	return b
+}
+
+// WithKind sets the Kind 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 Kind field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceApplyConfiguration) WithKind(value apisv1.Kind) *LocalPolicyTargetReferenceApplyConfiguration {
+	b.Kind = &value
+	return b
+}
+
+// WithName sets the Name 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 Name field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceApplyConfiguration) WithName(value apisv1.ObjectName) *LocalPolicyTargetReferenceApplyConfiguration {
+	b.Name = &value
+	return b
+}
diff --git a/applyconfiguration/apis/v1/localpolicytargetreferencewithsectionname.go b/applyconfiguration/apis/v1/localpolicytargetreferencewithsectionname.go
new file mode 100644
index 00000000..a46cb5c9
--- /dev/null
+++ b/applyconfiguration/apis/v1/localpolicytargetreferencewithsectionname.go
@@ -0,0 +1,68 @@
+/*
+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"
+)
+
+// LocalPolicyTargetReferenceWithSectionNameApplyConfiguration represents a declarative configuration of the LocalPolicyTargetReferenceWithSectionName type for use
+// with apply.
+type LocalPolicyTargetReferenceWithSectionNameApplyConfiguration struct {
+	LocalPolicyTargetReferenceApplyConfiguration `json:",inline"`
+	SectionName                                  *apisv1.SectionName `json:"sectionName,omitempty"`
+}
+
+// LocalPolicyTargetReferenceWithSectionNameApplyConfiguration constructs a declarative configuration of the LocalPolicyTargetReferenceWithSectionName type for use with
+// apply.
+func LocalPolicyTargetReferenceWithSectionName() *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration {
+	return &LocalPolicyTargetReferenceWithSectionNameApplyConfiguration{}
+}
+
+// WithGroup sets the Group 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 Group field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration) WithGroup(value apisv1.Group) *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration {
+	b.LocalPolicyTargetReferenceApplyConfiguration.Group = &value
+	return b
+}
+
+// WithKind sets the Kind 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 Kind field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration) WithKind(value apisv1.Kind) *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration {
+	b.LocalPolicyTargetReferenceApplyConfiguration.Kind = &value
+	return b
+}
+
+// WithName sets the Name 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 Name field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration) WithName(value apisv1.ObjectName) *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration {
+	b.LocalPolicyTargetReferenceApplyConfiguration.Name = &value
+	return b
+}
+
+// WithSectionName sets the SectionName 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 SectionName field is set to the value of the last call.
+func (b *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration) WithSectionName(value apisv1.SectionName) *LocalPolicyTargetReferenceWithSectionNameApplyConfiguration {
+	b.SectionName = &value
+	return b
+}
diff --git a/applyconfiguration/apis/v1/policyancestorstatus.go b/applyconfiguration/apis/v1/policyancestorstatus.go
new file mode 100644
index 00000000..7eb9953f
--- /dev/null
+++ b/applyconfiguration/apis/v1/policyancestorstatus.go
@@ -0,0 +1,67 @@
+/*
+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 (
+	metav1 "k8s.io/client-go/applyconfigurations/meta/v1"
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+// PolicyAncestorStatusApplyConfiguration represents a declarative configuration of the PolicyAncestorStatus type for use
+// with apply.
+type PolicyAncestorStatusApplyConfiguration struct {
+	AncestorRef    *ParentReferenceApplyConfiguration   `json:"ancestorRef,omitempty"`
+	ControllerName *apisv1.GatewayController            `json:"controllerName,omitempty"`
+	Conditions     []metav1.ConditionApplyConfiguration `json:"conditions,omitempty"`
+}
+
+// PolicyAncestorStatusApplyConfiguration constructs a declarative configuration of the PolicyAncestorStatus type for use with
+// apply.
+func PolicyAncestorStatus() *PolicyAncestorStatusApplyConfiguration {
+	return &PolicyAncestorStatusApplyConfiguration{}
+}
+
+// WithAncestorRef sets the AncestorRef 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 AncestorRef field is set to the value of the last call.
+func (b *PolicyAncestorStatusApplyConfiguration) WithAncestorRef(value *ParentReferenceApplyConfiguration) *PolicyAncestorStatusApplyConfiguration {
+	b.AncestorRef = value
+	return b
+}
+
+// WithControllerName sets the ControllerName 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 ControllerName field is set to the value of the last call.
+func (b *PolicyAncestorStatusApplyConfiguration) WithControllerName(value apisv1.GatewayController) *PolicyAncestorStatusApplyConfiguration {
+	b.ControllerName = &value
+	return b
+}
+
+// WithConditions adds the given value to the Conditions 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 Conditions field.
+func (b *PolicyAncestorStatusApplyConfiguration) WithConditions(values ...*metav1.ConditionApplyConfiguration) *PolicyAncestorStatusApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithConditions")
+		}
+		b.Conditions = append(b.Conditions, *values[i])
+	}
+	return b
+}
diff --git a/applyconfiguration/apis/v1/policystatus.go b/applyconfiguration/apis/v1/policystatus.go
new file mode 100644
index 00000000..64de9b41
--- /dev/null
+++ b/applyconfiguration/apis/v1/policystatus.go
@@ -0,0 +1,44 @@
+/*
+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
+
+// PolicyStatusApplyConfiguration represents a declarative configuration of the PolicyStatus type for use
+// with apply.
+type PolicyStatusApplyConfiguration struct {
+	Ancestors []PolicyAncestorStatusApplyConfiguration `json:"ancestors,omitempty"`
+}
+
+// PolicyStatusApplyConfiguration constructs a declarative configuration of the PolicyStatus type for use with
+// apply.
+func PolicyStatus() *PolicyStatusApplyConfiguration {
+	return &PolicyStatusApplyConfiguration{}
+}
+
+// WithAncestors adds the given value to the Ancestors 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 Ancestors field.
+func (b *PolicyStatusApplyConfiguration) WithAncestors(values ...*PolicyAncestorStatusApplyConfiguration) *PolicyStatusApplyConfiguration {
+	for i := range values {
+		if values[i] == nil {
+			panic("nil value passed to WithAncestors")
+		}
+		b.Ancestors = append(b.Ancestors, *values[i])
+	}
+	return b
+}
diff --git a/applyconfiguration/apis/v1/subjectaltname.go b/applyconfiguration/apis/v1/subjectaltname.go
new file mode 100644
index 00000000..52278686
--- /dev/null
+++ b/applyconfiguration/apis/v1/subjectaltname.go
@@ -0,0 +1,61 @@
+/*
+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"
+)
+
+// SubjectAltNameApplyConfiguration represents a declarative configuration of the SubjectAltName type for use
+// with apply.
+type SubjectAltNameApplyConfiguration struct {
+	Type     *apisv1.SubjectAltNameType `json:"type,omitempty"`
+	Hostname *apisv1.Hostname           `json:"hostname,omitempty"`
+	URI      *apisv1.AbsoluteURI        `json:"uri,omitempty"`
+}
+
+// SubjectAltNameApplyConfiguration constructs a declarative configuration of the SubjectAltName type for use with
+// apply.
+func SubjectAltName() *SubjectAltNameApplyConfiguration {
+	return &SubjectAltNameApplyConfiguration{}
+}
+
+// WithType sets the Type 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 Type field is set to the value of the last call.
+func (b *SubjectAltNameApplyConfiguration) WithType(value apisv1.SubjectAltNameType) *SubjectAltNameApplyConfiguration {
+	b.Type = &value
+	return b
+}
+
+// WithHostname sets the Hostname 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 Hostname field is set to the value of the last call.
+func (b *SubjectAltNameApplyConfiguration) WithHostname(value apisv1.Hostname) *SubjectAltNameApplyConfiguration {
+	b.Hostname = &value
+	return b
+}
+
+// WithURI sets the URI 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 URI field is set to the value of the last call.
+func (b *SubjectAltNameApplyConfiguration) WithURI(value apisv1.AbsoluteURI) *SubjectAltNameApplyConfiguration {
+	b.URI = &value
+	return b
+}
diff --git a/applyconfiguration/apis/v1alpha2/policystatus.go b/applyconfiguration/apis/v1alpha2/policystatus.go
index b7b158b2..c2df85f6 100644
--- a/applyconfiguration/apis/v1alpha2/policystatus.go
+++ b/applyconfiguration/apis/v1alpha2/policystatus.go
@@ -18,10 +18,14 @@ limitations under the License.
 
 package v1alpha2
 
+import (
+	v1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
+)
+
 // PolicyStatusApplyConfiguration represents a declarative configuration of the PolicyStatus type for use
 // with apply.
 type PolicyStatusApplyConfiguration struct {
-	Ancestors []PolicyAncestorStatusApplyConfiguration `json:"ancestors,omitempty"`
+	Ancestors []v1.PolicyAncestorStatusApplyConfiguration `json:"ancestors,omitempty"`
 }
 
 // PolicyStatusApplyConfiguration constructs a declarative configuration of the PolicyStatus type for use with
@@ -33,7 +37,7 @@ func PolicyStatus() *PolicyStatusApplyConfiguration {
 // WithAncestors adds the given value to the Ancestors 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 Ancestors field.
-func (b *PolicyStatusApplyConfiguration) WithAncestors(values ...*PolicyAncestorStatusApplyConfiguration) *PolicyStatusApplyConfiguration {
+func (b *PolicyStatusApplyConfiguration) WithAncestors(values ...*v1.PolicyAncestorStatusApplyConfiguration) *PolicyStatusApplyConfiguration {
 	for i := range values {
 		if values[i] == nil {
 			panic("nil value passed to WithAncestors")
diff --git a/applyconfiguration/apis/v1alpha3/backendtlspolicy.go b/applyconfiguration/apis/v1alpha3/backendtlspolicy.go
index dc518021..9a8f8721 100644
--- a/applyconfiguration/apis/v1alpha3/backendtlspolicy.go
+++ b/applyconfiguration/apis/v1alpha3/backendtlspolicy.go
@@ -24,7 +24,7 @@ import (
 	managedfields "k8s.io/apimachinery/pkg/util/managedfields"
 	v1 "k8s.io/client-go/applyconfigurations/meta/v1"
 	apisv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
-	v1alpha2 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1alpha2"
+	apisv1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
 	internal "sigs.k8s.io/gateway-api/applyconfiguration/internal"
 )
 
@@ -33,8 +33,8 @@ import (
 type BackendTLSPolicyApplyConfiguration struct {
 	v1.TypeMetaApplyConfiguration    `json:",inline"`
 	*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
-	Spec                             *BackendTLSPolicySpecApplyConfiguration  `json:"spec,omitempty"`
-	Status                           *v1alpha2.PolicyStatusApplyConfiguration `json:"status,omitempty"`
+	Spec                             *apisv1.BackendTLSPolicySpecApplyConfiguration `json:"spec,omitempty"`
+	Status                           *apisv1.PolicyStatusApplyConfiguration         `json:"status,omitempty"`
 }
 
 // BackendTLSPolicy constructs a declarative configuration of the BackendTLSPolicy type for use with
@@ -246,7 +246,7 @@ func (b *BackendTLSPolicyApplyConfiguration) ensureObjectMetaApplyConfigurationE
 // WithSpec sets the Spec 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 Spec field is set to the value of the last call.
-func (b *BackendTLSPolicyApplyConfiguration) WithSpec(value *BackendTLSPolicySpecApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
+func (b *BackendTLSPolicyApplyConfiguration) WithSpec(value *apisv1.BackendTLSPolicySpecApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
 	b.Spec = value
 	return b
 }
@@ -254,7 +254,7 @@ func (b *BackendTLSPolicyApplyConfiguration) WithSpec(value *BackendTLSPolicySpe
 // WithStatus sets the Status 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 Status field is set to the value of the last call.
-func (b *BackendTLSPolicyApplyConfiguration) WithStatus(value *v1alpha2.PolicyStatusApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
+func (b *BackendTLSPolicyApplyConfiguration) WithStatus(value *apisv1.PolicyStatusApplyConfiguration) *BackendTLSPolicyApplyConfiguration {
 	b.Status = value
 	return b
 }
diff --git a/applyconfiguration/apis/v1alpha3/backendtlspolicyvalidation.go b/applyconfiguration/apis/v1alpha3/backendtlspolicyvalidation.go
index b0cf5bfa..50cd59b9 100644
--- a/applyconfiguration/apis/v1alpha3/backendtlspolicyvalidation.go
+++ b/applyconfiguration/apis/v1alpha3/backendtlspolicyvalidation.go
@@ -20,7 +20,6 @@ package v1alpha3
 
 import (
 	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
-	apisv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 	v1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
 )
 
@@ -28,7 +27,7 @@ import (
 // with apply.
 type BackendTLSPolicyValidationApplyConfiguration struct {
 	CACertificateRefs       []v1.LocalObjectReferenceApplyConfiguration `json:"caCertificateRefs,omitempty"`
-	WellKnownCACertificates *apisv1alpha3.WellKnownCACertificatesType   `json:"wellKnownCACertificates,omitempty"`
+	WellKnownCACertificates *apisv1.WellKnownCACertificatesType         `json:"wellKnownCACertificates,omitempty"`
 	Hostname                *apisv1.PreciseHostname                     `json:"hostname,omitempty"`
 	SubjectAltNames         []SubjectAltNameApplyConfiguration          `json:"subjectAltNames,omitempty"`
 }
@@ -55,7 +54,7 @@ func (b *BackendTLSPolicyValidationApplyConfiguration) WithCACertificateRefs(val
 // WithWellKnownCACertificates sets the WellKnownCACertificates 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 WellKnownCACertificates field is set to the value of the last call.
-func (b *BackendTLSPolicyValidationApplyConfiguration) WithWellKnownCACertificates(value apisv1alpha3.WellKnownCACertificatesType) *BackendTLSPolicyValidationApplyConfiguration {
+func (b *BackendTLSPolicyValidationApplyConfiguration) WithWellKnownCACertificates(value apisv1.WellKnownCACertificatesType) *BackendTLSPolicyValidationApplyConfiguration {
 	b.WellKnownCACertificates = &value
 	return b
 }
diff --git a/applyconfiguration/apis/v1alpha3/subjectaltname.go b/applyconfiguration/apis/v1alpha3/subjectaltname.go
index 42823831..a024a62e 100644
--- a/applyconfiguration/apis/v1alpha3/subjectaltname.go
+++ b/applyconfiguration/apis/v1alpha3/subjectaltname.go
@@ -20,15 +20,14 @@ package v1alpha3
 
 import (
 	v1 "sigs.k8s.io/gateway-api/apis/v1"
-	apisv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 )
 
 // SubjectAltNameApplyConfiguration represents a declarative configuration of the SubjectAltName type for use
 // with apply.
 type SubjectAltNameApplyConfiguration struct {
-	Type     *apisv1alpha3.SubjectAltNameType `json:"type,omitempty"`
-	Hostname *v1.Hostname                     `json:"hostname,omitempty"`
-	URI      *v1.AbsoluteURI                  `json:"uri,omitempty"`
+	Type     *v1.SubjectAltNameType `json:"type,omitempty"`
+	Hostname *v1.Hostname           `json:"hostname,omitempty"`
+	URI      *v1.AbsoluteURI        `json:"uri,omitempty"`
 }
 
 // SubjectAltNameApplyConfiguration constructs a declarative configuration of the SubjectAltName type for use with
@@ -40,7 +39,7 @@ func SubjectAltName() *SubjectAltNameApplyConfiguration {
 // WithType sets the Type 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 Type field is set to the value of the last call.
-func (b *SubjectAltNameApplyConfiguration) WithType(value apisv1alpha3.SubjectAltNameType) *SubjectAltNameApplyConfiguration {
+func (b *SubjectAltNameApplyConfiguration) WithType(value v1.SubjectAltNameType) *SubjectAltNameApplyConfiguration {
 	b.Type = &value
 	return b
 }
diff --git a/applyconfiguration/apisx/v1alpha1/backendtrafficpolicyspec.go b/applyconfiguration/apisx/v1alpha1/backendtrafficpolicyspec.go
index 205609b8..ec7a76b0 100644
--- a/applyconfiguration/apisx/v1alpha1/backendtrafficpolicyspec.go
+++ b/applyconfiguration/apisx/v1alpha1/backendtrafficpolicyspec.go
@@ -20,15 +20,14 @@ package v1alpha1
 
 import (
 	v1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
-	v1alpha2 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1alpha2"
 )
 
 // BackendTrafficPolicySpecApplyConfiguration represents a declarative configuration of the BackendTrafficPolicySpec type for use
 // with apply.
 type BackendTrafficPolicySpecApplyConfiguration struct {
-	TargetRefs         []v1alpha2.LocalPolicyTargetReferenceApplyConfiguration `json:"targetRefs,omitempty"`
-	RetryConstraint    *RetryConstraintApplyConfiguration                      `json:"retryConstraint,omitempty"`
-	SessionPersistence *v1.SessionPersistenceApplyConfiguration                `json:"sessionPersistence,omitempty"`
+	TargetRefs         []v1.LocalPolicyTargetReferenceApplyConfiguration `json:"targetRefs,omitempty"`
+	RetryConstraint    *RetryConstraintApplyConfiguration                `json:"retryConstraint,omitempty"`
+	SessionPersistence *v1.SessionPersistenceApplyConfiguration          `json:"sessionPersistence,omitempty"`
 }
 
 // BackendTrafficPolicySpecApplyConfiguration constructs a declarative configuration of the BackendTrafficPolicySpec type for use with
@@ -40,7 +39,7 @@ func BackendTrafficPolicySpec() *BackendTrafficPolicySpecApplyConfiguration {
 // WithTargetRefs adds the given value to the TargetRefs 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 TargetRefs field.
-func (b *BackendTrafficPolicySpecApplyConfiguration) WithTargetRefs(values ...*v1alpha2.LocalPolicyTargetReferenceApplyConfiguration) *BackendTrafficPolicySpecApplyConfiguration {
+func (b *BackendTrafficPolicySpecApplyConfiguration) WithTargetRefs(values ...*v1.LocalPolicyTargetReferenceApplyConfiguration) *BackendTrafficPolicySpecApplyConfiguration {
 	for i := range values {
 		if values[i] == nil {
 			panic("nil value passed to WithTargetRefs")
diff --git a/applyconfiguration/apisx/v1alpha1/xbackendtrafficpolicy.go b/applyconfiguration/apisx/v1alpha1/xbackendtrafficpolicy.go
index 99a39f03..6e9de039 100644
--- a/applyconfiguration/apisx/v1alpha1/xbackendtrafficpolicy.go
+++ b/applyconfiguration/apisx/v1alpha1/xbackendtrafficpolicy.go
@@ -24,7 +24,7 @@ import (
 	managedfields "k8s.io/apimachinery/pkg/util/managedfields"
 	v1 "k8s.io/client-go/applyconfigurations/meta/v1"
 	apisxv1alpha1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"
-	v1alpha2 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1alpha2"
+	apisv1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
 	internal "sigs.k8s.io/gateway-api/applyconfiguration/internal"
 )
 
@@ -34,7 +34,7 @@ type XBackendTrafficPolicyApplyConfiguration struct {
 	v1.TypeMetaApplyConfiguration    `json:",inline"`
 	*v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"`
 	Spec                             *BackendTrafficPolicySpecApplyConfiguration `json:"spec,omitempty"`
-	Status                           *v1alpha2.PolicyStatusApplyConfiguration    `json:"status,omitempty"`
+	Status                           *apisv1.PolicyStatusApplyConfiguration      `json:"status,omitempty"`
 }
 
 // XBackendTrafficPolicy constructs a declarative configuration of the XBackendTrafficPolicy type for use with
@@ -254,7 +254,7 @@ func (b *XBackendTrafficPolicyApplyConfiguration) WithSpec(value *BackendTraffic
 // WithStatus sets the Status 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 Status field is set to the value of the last call.
-func (b *XBackendTrafficPolicyApplyConfiguration) WithStatus(value *v1alpha2.PolicyStatusApplyConfiguration) *XBackendTrafficPolicyApplyConfiguration {
+func (b *XBackendTrafficPolicyApplyConfiguration) WithStatus(value *apisv1.PolicyStatusApplyConfiguration) *XBackendTrafficPolicyApplyConfiguration {
 	b.Status = value
 	return b
 }
diff --git a/applyconfiguration/internal/internal.go b/applyconfiguration/internal/internal.go
index eb813846..5fa65d15 100644
--- a/applyconfiguration/internal/internal.go
+++ b/applyconfiguration/internal/internal.go
@@ -282,6 +282,67 @@ var schemaYAML = typed.YAMLObject(`types:
     - name: weight
       type:
         scalar: numeric
+- name: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicy
+  map:
+    fields:
+    - name: apiVersion
+      type:
+        scalar: string
+    - name: kind
+      type:
+        scalar: string
+    - name: metadata
+      type:
+        namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta
+      default: {}
+    - name: spec
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicySpec
+      default: {}
+    - name: status
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.PolicyStatus
+      default: {}
+- name: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicySpec
+  map:
+    fields:
+    - name: options
+      type:
+        map:
+          elementType:
+            scalar: string
+    - name: targetRefs
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.LocalPolicyTargetReferenceWithSectionName
+          elementRelationship: atomic
+    - name: validation
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicyValidation
+      default: {}
+- name: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicyValidation
+  map:
+    fields:
+    - name: caCertificateRefs
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.LocalObjectReference
+          elementRelationship: atomic
+    - name: hostname
+      type:
+        scalar: string
+      default: ""
+    - name: subjectAltNames
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.SubjectAltName
+          elementRelationship: atomic
+    - name: wellKnownCACertificates
+      type:
+        scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1.CookieConfig
   map:
     fields:
@@ -1186,6 +1247,39 @@ var schemaYAML = typed.YAMLObject(`types:
       type:
         scalar: string
       default: ""
+- name: io.k8s.sigs.gateway-api.apis.v1.LocalPolicyTargetReference
+  map:
+    fields:
+    - name: group
+      type:
+        scalar: string
+      default: ""
+    - name: kind
+      type:
+        scalar: string
+      default: ""
+    - name: name
+      type:
+        scalar: string
+      default: ""
+- name: io.k8s.sigs.gateway-api.apis.v1.LocalPolicyTargetReferenceWithSectionName
+  map:
+    fields:
+    - name: group
+      type:
+        scalar: string
+      default: ""
+    - name: kind
+      type:
+        scalar: string
+      default: ""
+    - name: name
+      type:
+        scalar: string
+      default: ""
+    - name: sectionName
+      type:
+        scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1.ObjectReference
   map:
     fields:
@@ -1244,6 +1338,34 @@ var schemaYAML = typed.YAMLObject(`types:
     - name: sectionName
       type:
         scalar: string
+- name: io.k8s.sigs.gateway-api.apis.v1.PolicyAncestorStatus
+  map:
+    fields:
+    - name: ancestorRef
+      type:
+        namedType: io.k8s.sigs.gateway-api.apis.v1.ParentReference
+      default: {}
+    - name: conditions
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition
+          elementRelationship: associative
+          keys:
+          - type
+    - name: controllerName
+      type:
+        scalar: string
+      default: ""
+- name: io.k8s.sigs.gateway-api.apis.v1.PolicyStatus
+  map:
+    fields:
+    - name: ancestors
+      type:
+        list:
+          elementType:
+            namedType: io.k8s.sigs.gateway-api.apis.v1.PolicyAncestorStatus
+          elementRelationship: atomic
 - name: io.k8s.sigs.gateway-api.apis.v1.RouteGroupKind
   map:
     fields:
@@ -1316,6 +1438,19 @@ var schemaYAML = typed.YAMLObject(`types:
     - name: type
       type:
         scalar: string
+- name: io.k8s.sigs.gateway-api.apis.v1.SubjectAltName
+  map:
+    fields:
+    - name: hostname
+      type:
+        scalar: string
+    - name: type
+      type:
+        scalar: string
+      default: ""
+    - name: uri
+      type:
+        scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1.SupportedFeature
   map:
     fields:
@@ -1361,67 +1496,6 @@ var schemaYAML = typed.YAMLObject(`types:
       type:
         namedType: io.k8s.sigs.gateway-api.apis.v1.GRPCRouteStatus
       default: {}
-- name: io.k8s.sigs.gateway-api.apis.v1alpha2.LocalPolicyTargetReference
-  map:
-    fields:
-    - name: group
-      type:
-        scalar: string
-      default: ""
-    - name: kind
-      type:
-        scalar: string
-      default: ""
-    - name: name
-      type:
-        scalar: string
-      default: ""
-- name: io.k8s.sigs.gateway-api.apis.v1alpha2.LocalPolicyTargetReferenceWithSectionName
-  map:
-    fields:
-    - name: group
-      type:
-        scalar: string
-      default: ""
-    - name: kind
-      type:
-        scalar: string
-      default: ""
-    - name: name
-      type:
-        scalar: string
-      default: ""
-    - name: sectionName
-      type:
-        scalar: string
-- name: io.k8s.sigs.gateway-api.apis.v1alpha2.PolicyAncestorStatus
-  map:
-    fields:
-    - name: ancestorRef
-      type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1.ParentReference
-      default: {}
-    - name: conditions
-      type:
-        list:
-          elementType:
-            namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition
-          elementRelationship: associative
-          keys:
-          - type
-    - name: controllerName
-      type:
-        scalar: string
-      default: ""
-- name: io.k8s.sigs.gateway-api.apis.v1alpha2.PolicyStatus
-  map:
-    fields:
-    - name: ancestors
-      type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1alpha2.PolicyAncestorStatus
-          elementRelationship: atomic
 - name: io.k8s.sigs.gateway-api.apis.v1alpha2.ReferenceGrant
   map:
     fields:
@@ -1640,65 +1714,12 @@ var schemaYAML = typed.YAMLObject(`types:
       default: {}
     - name: spec
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1alpha3.BackendTLSPolicySpec
+        namedType: io.k8s.sigs.gateway-api.apis.v1.BackendTLSPolicySpec
       default: {}
     - name: status
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1alpha2.PolicyStatus
-      default: {}
-- name: io.k8s.sigs.gateway-api.apis.v1alpha3.BackendTLSPolicySpec
-  map:
-    fields:
-    - name: options
-      type:
-        map:
-          elementType:
-            scalar: string
-    - name: targetRefs
-      type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1alpha2.LocalPolicyTargetReferenceWithSectionName
-          elementRelationship: atomic
-    - name: validation
-      type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1alpha3.BackendTLSPolicyValidation
+        namedType: io.k8s.sigs.gateway-api.apis.v1.PolicyStatus
       default: {}
-- name: io.k8s.sigs.gateway-api.apis.v1alpha3.BackendTLSPolicyValidation
-  map:
-    fields:
-    - name: caCertificateRefs
-      type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1.LocalObjectReference
-          elementRelationship: atomic
-    - name: hostname
-      type:
-        scalar: string
-      default: ""
-    - name: subjectAltNames
-      type:
-        list:
-          elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1alpha3.SubjectAltName
-          elementRelationship: atomic
-    - name: wellKnownCACertificates
-      type:
-        scalar: string
-- name: io.k8s.sigs.gateway-api.apis.v1alpha3.SubjectAltName
-  map:
-    fields:
-    - name: hostname
-      type:
-        scalar: string
-    - name: type
-      type:
-        scalar: string
-      default: ""
-    - name: uri
-      type:
-        scalar: string
 - name: io.k8s.sigs.gateway-api.apis.v1alpha3.TLSRoute
   map:
     fields:
@@ -1881,7 +1902,7 @@ var schemaYAML = typed.YAMLObject(`types:
       type:
         list:
           elementType:
-            namedType: io.k8s.sigs.gateway-api.apis.v1alpha2.LocalPolicyTargetReference
+            namedType: io.k8s.sigs.gateway-api.apis.v1.LocalPolicyTargetReference
           elementRelationship: associative
           keys:
           - group
@@ -2067,7 +2088,7 @@ var schemaYAML = typed.YAMLObject(`types:
       default: {}
     - name: status
       type:
-        namedType: io.k8s.sigs.gateway-api.apis.v1alpha2.PolicyStatus
+        namedType: io.k8s.sigs.gateway-api.apis.v1.PolicyStatus
       default: {}
 - name: io.k8s.sigs.gateway-api.apisx.v1alpha1.XListenerSet
   map:
diff --git a/applyconfiguration/utils.go b/applyconfiguration/utils.go
index 31bed767..23a89a00 100644
--- a/applyconfiguration/utils.go
+++ b/applyconfiguration/utils.go
@@ -48,6 +48,12 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.BackendObjectReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("BackendRef"):
 		return &apisv1.BackendRefApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("BackendTLSPolicy"):
+		return &apisv1.BackendTLSPolicyApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("BackendTLSPolicySpec"):
+		return &apisv1.BackendTLSPolicySpecApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("BackendTLSPolicyValidation"):
+		return &apisv1.BackendTLSPolicyValidationApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("CommonRouteSpec"):
 		return &apisv1.CommonRouteSpecApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("CookieConfig"):
@@ -156,12 +162,20 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.LocalObjectReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("LocalParametersReference"):
 		return &apisv1.LocalParametersReferenceApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("LocalPolicyTargetReference"):
+		return &apisv1.LocalPolicyTargetReferenceApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("LocalPolicyTargetReferenceWithSectionName"):
+		return &apisv1.LocalPolicyTargetReferenceWithSectionNameApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("ObjectReference"):
 		return &apisv1.ObjectReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("ParametersReference"):
 		return &apisv1.ParametersReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("ParentReference"):
 		return &apisv1.ParentReferenceApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("PolicyAncestorStatus"):
+		return &apisv1.PolicyAncestorStatusApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("PolicyStatus"):
+		return &apisv1.PolicyStatusApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("RouteGroupKind"):
 		return &apisv1.RouteGroupKindApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("RouteNamespaces"):
@@ -174,6 +188,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &apisv1.SecretObjectReferenceApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("SessionPersistence"):
 		return &apisv1.SessionPersistenceApplyConfiguration{}
+	case v1.SchemeGroupVersion.WithKind("SubjectAltName"):
+		return &apisv1.SubjectAltNameApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("SupportedFeature"):
 		return &apisv1.SupportedFeatureApplyConfiguration{}
 	case v1.SchemeGroupVersion.WithKind("TLSConfig"):
@@ -184,14 +200,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		// Group=gateway.networking.k8s.io, Version=v1alpha2
 	case v1alpha2.SchemeGroupVersion.WithKind("GRPCRoute"):
 		return &apisv1alpha2.GRPCRouteApplyConfiguration{}
-	case v1alpha2.SchemeGroupVersion.WithKind("LocalPolicyTargetReference"):
-		return &apisv1alpha2.LocalPolicyTargetReferenceApplyConfiguration{}
-	case v1alpha2.SchemeGroupVersion.WithKind("LocalPolicyTargetReferenceWithSectionName"):
-		return &apisv1alpha2.LocalPolicyTargetReferenceWithSectionNameApplyConfiguration{}
-	case v1alpha2.SchemeGroupVersion.WithKind("PolicyAncestorStatus"):
-		return &apisv1alpha2.PolicyAncestorStatusApplyConfiguration{}
-	case v1alpha2.SchemeGroupVersion.WithKind("PolicyStatus"):
-		return &apisv1alpha2.PolicyStatusApplyConfiguration{}
 	case v1alpha2.SchemeGroupVersion.WithKind("ReferenceGrant"):
 		return &apisv1alpha2.ReferenceGrantApplyConfiguration{}
 	case v1alpha2.SchemeGroupVersion.WithKind("TCPRoute"):
@@ -222,12 +230,6 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		// Group=gateway.networking.k8s.io, Version=v1alpha3
 	case v1alpha3.SchemeGroupVersion.WithKind("BackendTLSPolicy"):
 		return &apisv1alpha3.BackendTLSPolicyApplyConfiguration{}
-	case v1alpha3.SchemeGroupVersion.WithKind("BackendTLSPolicySpec"):
-		return &apisv1alpha3.BackendTLSPolicySpecApplyConfiguration{}
-	case v1alpha3.SchemeGroupVersion.WithKind("BackendTLSPolicyValidation"):
-		return &apisv1alpha3.BackendTLSPolicyValidationApplyConfiguration{}
-	case v1alpha3.SchemeGroupVersion.WithKind("SubjectAltName"):
-		return &apisv1alpha3.SubjectAltNameApplyConfiguration{}
 	case v1alpha3.SchemeGroupVersion.WithKind("TLSRoute"):
 		return &apisv1alpha3.TLSRouteApplyConfiguration{}
 	case v1alpha3.SchemeGroupVersion.WithKind("TLSRouteSpec"):
diff --git a/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml b/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
index b110a95a..4cf00535 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
@@ -25,7 +25,7 @@ spec:
     - jsonPath: .metadata.creationTimestamp
       name: Age
       type: date
-    name: v1alpha3
+    name: v1
     schema:
       openAPIV3Schema:
         description: |-
@@ -685,6 +685,667 @@ spec:
     storage: true
     subresources:
       status: {}
+  - deprecated: true
+    deprecationWarning: The v1alpha3 version of BackendTLSPolicy has been deprecated
+      and will be removed in a future release of the API. Please upgrade to v1.
+    name: v1alpha3
+    schema:
+      openAPIV3Schema:
+        description: |-
+          BackendTLSPolicy provides a way to configure how a Gateway
+          connects to a Backend via TLS.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: Spec defines the desired state of BackendTLSPolicy.
+            properties:
+              options:
+                additionalProperties:
+                  description: |-
+                    AnnotationValue is the value of an annotation in Gateway API. This is used
+                    for validation of maps such as TLS options. This roughly matches Kubernetes
+                    annotation validation, although the length validation in that case is based
+                    on the entire size of the annotations struct.
+                  maxLength: 4096
+                  minLength: 0
+                  type: string
+                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.
+
+                  A 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.
+
+                  Support: Implementation-specific
+                maxProperties: 16
+                type: object
+              targetRefs:
+                description: |-
+                  TargetRefs identifies an API object to apply the policy to.
+                  Only Services have Extended support. Implementations MAY support
+                  additional objects, with Implementation Specific support.
+                  Note that this config applies to the entire referenced resource
+                  by default, but this default may change in the future to provide
+                  a more granular application of the policy.
+
+                  TargetRefs must be _distinct_. This means either that:
+
+                  * They select different targets. If this is the case, then targetRef
+                    entries are distinct. In terms of fields, this means that the
+                    multi-part key defined by `group`, `kind`, and `name` must
+                    be unique across all targetRef entries in the BackendTLSPolicy.
+                  * They select different sectionNames in the same target.
+
+                  When more than one BackendTLSPolicy selects the same target and
+                  sectionName, implementations MUST determine precedence using the
+                  following criteria, continuing on ties:
+
+                  * The older policy by creation timestamp takes precedence. For
+                    example, a policy with a creation timestamp of "2021-07-15
+                    01:02:03" MUST be given precedence over a policy with a
+                    creation timestamp of "2021-07-15 01:02:04".
+                  * The policy appearing first in alphabetical order by {name}.
+                    For example, a policy named `bar` is given precedence over a
+                    policy named `baz`.
+
+                  For any BackendTLSPolicy that does not take precedence, the
+                  implementation MUST ensure the `Accepted` Condition is set to
+                  `status: False`, with Reason `Conflicted`.
+
+                  Support: Extended for Kubernetes Service
+
+                  Support: Implementation-specific for any other resource
+                items:
+                  description: |-
+                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
+                    direct policy to. This should be used as part of Policy resources that can
+                    target single resources. For more information on how this policy attachment
+                    mode works, and a sample Policy resource, refer to the policy attachment
+                    documentation for Gateway API.
+
+                    Note: This should only be used for direct policy attachment when references
+                    to SectionName are actually needed. In all other cases,
+                    LocalPolicyTargetReference should be used.
+                  properties:
+                    group:
+                      description: Group is the group of the target resource.
+                      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 target resource.
+                      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 target resource.
+                      maxLength: 253
+                      minLength: 1
+                      type: string
+                    sectionName:
+                      description: |-
+                        SectionName is the name of a section within the target resource. When
+                        unspecified, this targetRef targets the entire resource. In the following
+                        resources, SectionName is interpreted as the following:
+
+                        * Gateway: Listener name
+                        * HTTPRoute: HTTPRouteRule name
+                        * Service: Port name
+
+                        If a SectionName is specified, but does not exist on the targeted object,
+                        the Policy must fail to attach, and the policy implementation should record
+                        a `ResolvedRefs` or similar Condition in the Policy's status.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                      type: string
+                  required:
+                  - group
+                  - kind
+                  - name
+                  type: object
+                maxItems: 16
+                minItems: 1
+                type: array
+                x-kubernetes-list-type: atomic
+                x-kubernetes-validations:
+                - message: sectionName must be specified when targetRefs includes
+                    2 or more references to the same target
+                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName
+                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))
+                    : true))'
+                - message: sectionName must be unique when targetRefs includes 2 or
+                    more references to the same target
+                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||
+                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName
+                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName
+                    == p2.sectionName))))
+              validation:
+                description: Validation contains backend TLS validation configuration.
+                properties:
+                  caCertificateRefs:
+                    description: |-
+                      CACertificateRefs contains one or more references to Kubernetes objects that
+                      contain a PEM-encoded TLS CA certificate bundle, which is used to
+                      validate a TLS handshake between the Gateway and backend Pod.
+
+                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
+                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
+                      not both. If CACertificateRefs is empty or unspecified, the configuration for
+                      WellKnownCACertificates MUST be honored instead if supported by the implementation.
+
+                      A CACertificateRef is invalid if:
+
+                      * It refers to a resource that cannot be resolved (e.g., the referenced resource
+                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key
+                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`
+                        and the Message of the Condition must indicate which reference is invalid and why.
+
+                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason
+                        must be set to `InvalidKind` and the Message of the Condition must explain which
+                        kind of resource is unknown or unsupported.
+
+                      * It refers to a resource in another namespace. This may change in future
+                        spec updates.
+
+                      Implementations MAY choose to perform further validation of the certificate
+                      content (e.g., checking expiry or enforcing specific formats). In such cases,
+                      an implementation-specific Reason and Message must be set for the invalid reference.
+
+                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on
+                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message
+                      that indicate the cause of the error. Connections using an invalid
+                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error
+                      response. If ALL CACertificateRefs are invalid, the implementation MUST also
+                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to
+                      `status: False`, with a Reason `NoValidCACertificate`.
+
+                      A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
+                      Implementations MAY choose to support attaching multiple certificates to
+                      a backend, but this behavior is implementation-specific.
+
+                      Support: Core - An optional single reference to a Kubernetes ConfigMap,
+                      with the CA certificate in a key named `ca.crt`.
+
+                      Support: Implementation-specific - More than one reference, other kinds
+                      of resources, or a single reference that includes multiple certificates.
+                    items:
+                      description: |-
+                        LocalObjectReference identifies an API object within the namespace of the
+                        referrer.
+                        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 unspecified or empty string, core API group is inferred.
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          description: Kind is kind of the referent. For example "HTTPRoute"
+                            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
+                      required:
+                      - group
+                      - kind
+                      - name
+                      type: object
+                    maxItems: 8
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  hostname:
+                    description: |-
+                      Hostname is used for two purposes in the connection between Gateways and
+                      backends:
+
+                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
+                      2. Hostname MUST be used for authentication and MUST match the certificate
+                         served by the matching backend, unless SubjectAltNames is specified.
+                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection
+                         but MUST NOT be used for authentication. If you want to use the value
+                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.
+
+                      Support: Core
+                    maxLength: 253
+                    minLength: 1
+                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                    type: string
+                  subjectAltNames:
+                    description: |-
+                      SubjectAltNames contains one or more Subject Alternative Names.
+                      When specified the certificate served from the backend MUST
+                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
+
+                      Support: Extended
+                    items:
+                      description: SubjectAltName represents Subject Alternative Name.
+                      properties:
+                        hostname:
+                          description: |-
+                            Hostname contains Subject Alternative Name specified in DNS name format.
+                            Required when Type is set to Hostname, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        type:
+                          description: |-
+                            Type determines the format of the Subject Alternative Name. Always required.
+
+                            Support: Core
+                          enum:
+                          - Hostname
+                          - URI
+                          type: string
+                        uri:
+                          description: |-
+                            URI contains Subject Alternative Name specified in a full URI format.
+                            It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
+                            Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
+                            Required when Type is set to URI, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?
+                          type: string
+                      required:
+                      - type
+                      type: object
+                      x-kubernetes-validations:
+                      - message: SubjectAltName element must contain Hostname, if
+                          Type is set to Hostname
+                        rule: '!(self.type == "Hostname" && (!has(self.hostname) ||
+                          self.hostname == ""))'
+                      - message: SubjectAltName element must not contain Hostname,
+                          if Type is not set to Hostname
+                        rule: '!(self.type != "Hostname" && has(self.hostname) &&
+                          self.hostname != "")'
+                      - message: SubjectAltName element must contain URI, if Type
+                          is set to URI
+                        rule: '!(self.type == "URI" && (!has(self.uri) || self.uri
+                          == ""))'
+                      - message: SubjectAltName element must not contain URI, if Type
+                          is not set to URI
+                        rule: '!(self.type != "URI" && has(self.uri) && self.uri !=
+                          "")'
+                    maxItems: 5
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  wellKnownCACertificates:
+                    description: |-
+                      WellKnownCACertificates specifies whether system CA certificates may be used in
+                      the TLS handshake between the gateway and backend pod.
+
+                      If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
+                      must be specified with at least one entry for a valid configuration. Only one of
+                      CACertificateRefs or WellKnownCACertificates may be specified, not both.
+                      If an implementation does not support the WellKnownCACertificates field, or
+                      the supplied value is not recognized, the implementation MUST ensure the
+                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with
+                      a Reason `Invalid`.
+
+                      Support: Implementation-specific
+                    enum:
+                    - System
+                    type: string
+                required:
+                - hostname
+                type: object
+                x-kubernetes-validations:
+                - message: must not contain both CACertificateRefs and WellKnownCACertificates
+                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")'
+                - message: must specify either CACertificateRefs or WellKnownCACertificates
+                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")
+            required:
+            - targetRefs
+            - validation
+            type: object
+          status:
+            description: Status defines the current state of BackendTLSPolicy.
+            properties:
+              ancestors:
+                description: |-
+                  Ancestors is a list of ancestor resources (usually Gateways) that are
+                  associated with the policy, and the status of the policy with respect to
+                  each ancestor. When this policy attaches to a parent, the controller that
+                  manages the parent and the ancestors MUST add an entry to this list when
+                  the controller first sees the policy and SHOULD update the entry as
+                  appropriate when the relevant ancestor is modified.
+
+                  Note that choosing the relevant ancestor is left to the Policy designers;
+                  an important part of Policy design is designing the right object level at
+                  which to namespace this status.
+
+                  Note also that implementations MUST ONLY populate ancestor status for
+                  the Ancestor resources they are responsible for. Implementations MUST
+                  use the ControllerName field to uniquely identify the entries in this list
+                  that they are responsible for.
+
+                  Note that to achieve this, the list of PolicyAncestorStatus structs
+                  MUST be treated as a map with a composite key, made up of the AncestorRef
+                  and ControllerName fields combined.
+
+                  A maximum of 16 ancestors will be represented in this list. An empty list
+                  means the Policy is not relevant for any ancestors.
+
+                  If this slice is full, implementations MUST NOT add further entries.
+                  Instead they MUST consider the policy unimplementable and signal that
+                  on any related resources such as the ancestor that would be referenced
+                  here. For example, if this list was full on BackendTLSPolicy, no
+                  additional Gateways would be able to reference the Service targeted by
+                  the BackendTLSPolicy.
+                items:
+                  description: |-
+                    PolicyAncestorStatus describes the status of a route with respect to an
+                    associated Ancestor.
+
+                    Ancestors refer to objects that are either the Target of a policy or above it
+                    in terms of object hierarchy. For example, if a policy targets a Service, the
+                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
+                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most
+                    useful object to place Policy status on, so we recommend that implementations
+                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
+                    have a _very_ good reason otherwise.
+
+                    In the context of policy attachment, the Ancestor is used to distinguish which
+                    resource results in a distinct application of this policy. For example, if a policy
+                    targets a Service, it may have a distinct result per attached Gateway.
+
+                    Policies targeting the same resource may have different effects depending on the
+                    ancestors of those resources. For example, different Gateways targeting the same
+                    Service may have different capabilities, especially if they have different underlying
+                    implementations.
+
+                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is
+                    used as a backend in a HTTPRoute that is itself attached to a Gateway.
+                    In this case, the relevant object for status is the Gateway, and that is the
+                    ancestor object referred to in this status.
+
+                    Note that a parent is also an ancestor, so for objects where the parent is the
+                    relevant object for status, this struct SHOULD still be used.
+
+                    This struct is intended to be used in a slice that's effectively a map,
+                    with a composite key made up of the AncestorRef and the ControllerName.
+                  properties:
+                    ancestorRef:
+                      description: |-
+                        AncestorRef corresponds with a ParentRef in the spec that this
+                        PolicyAncestorStatus struct describes the status of.
+                      properties:
+                        group:
+                          default: gateway.networking.k8s.io
+                          description: |-
+                            Group is the group of the referent.
+                            When unspecified, "gateway.networking.k8s.io" is inferred.
+                            To set the core API group (such as for a "Service" kind referent),
+                            Group must be explicitly set to "" (empty string).
+
+                            Support: Core
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          default: Gateway
+                          description: |-
+                            Kind is kind of the referent.
+
+                            There are two kinds of parent resources with "Core" support:
+
+                            * Gateway (Gateway conformance profile)
+                            * Service (Mesh conformance profile, ClusterIP Services only)
+
+                            Support for other resources is Implementation-Specific.
+                          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.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace is the namespace of the referent. When unspecified, this refers
+                            to the local namespace of the Route.
+
+                            Note that there are specific rules for ParentRefs which cross namespace
+                            boundaries. Cross-namespace references are only valid if they are explicitly
+                            allowed by something in the namespace they are referring to. For example:
+                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a
+                            generic way to enable any other kind of cross-namespace reference.
+
+
+                            ParentRefs from a Route to a Service in the same namespace are "producer"
+                            routes, which apply default routing rules to inbound connections from
+                            any namespace to the Service.
+
+                            ParentRefs from a Route to a Service in a different namespace are
+                            "consumer" routes, and these routing rules are only applied to outbound
+                            connections originating from the same namespace as the Route, for which
+                            the intended destination of the connections are a Service targeted as a
+                            ParentRef of the Route.
+
+
+                            Support: Core
+                          maxLength: 63
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                          type: string
+                        port:
+                          description: |-
+                            Port is the network port this Route targets. It can be interpreted
+                            differently based on the type of parent resource.
+
+                            When the parent resource is a Gateway, this targets all listeners
+                            listening on the specified port that also support this kind of Route(and
+                            select this Route). It's not recommended to set `Port` unless the
+                            networking behaviors specified in a Route must apply to a specific port
+                            as opposed to a listener(s) whose port(s) may be changed. When both Port
+                            and SectionName are specified, the name and port of the selected listener
+                            must match both specified values.
+
+
+                            When the parent resource is a Service, this targets a specific port in the
+                            Service spec. When both Port (experimental) and SectionName are specified,
+                            the name and port of the selected port must match both specified values.
+
+
+                            Implementations MAY choose to support other parent resources.
+                            Implementations supporting other types of parent resources MUST clearly
+                            document how/if Port is interpreted.
+
+                            For the purpose of status, an attachment is considered successful as
+                            long as the parent resource accepts it partially. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
+                            from the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route,
+                            the Route MUST be considered detached from the Gateway.
+
+                            Support: Extended
+                          format: int32
+                          maximum: 65535
+                          minimum: 1
+                          type: integer
+                        sectionName:
+                          description: |-
+                            SectionName is the name of a section within the target resource. In the
+                            following resources, SectionName is interpreted as the following:
+
+                            * Gateway: Listener name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+                            * Service: Port name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+
+                            Implementations MAY choose to support attaching Routes to other resources.
+                            If that is the case, they MUST clearly document how SectionName is
+                            interpreted.
+
+                            When unspecified (empty string), this will reference the entire resource.
+                            For the purpose of status, an attachment is considered successful if at
+                            least one section in the parent resource accepts it. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
+                            the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route, the
+                            Route MUST be considered detached from the Gateway.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    conditions:
+                      description: Conditions describes the status of the Policy with
+                        respect to the given Ancestor.
+                      items:
+                        description: Condition contains details for one aspect of
+                          the current state of this API Resource.
+                        properties:
+                          lastTransitionTime:
+                            description: |-
+                              lastTransitionTime is the last time the condition transitioned from one status to another.
+                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.
+                            format: date-time
+                            type: string
+                          message:
+                            description: |-
+                              message is a human readable message indicating details about the transition.
+                              This may be an empty string.
+                            maxLength: 32768
+                            type: string
+                          observedGeneration:
+                            description: |-
+                              observedGeneration represents the .metadata.generation that the condition was set based upon.
+                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+                              with respect to the current state of the instance.
+                            format: int64
+                            minimum: 0
+                            type: integer
+                          reason:
+                            description: |-
+                              reason contains a programmatic identifier indicating the reason for the condition's last transition.
+                              Producers of specific condition types may define expected values and meanings for this field,
+                              and whether the values are considered a guaranteed API.
+                              The value should be a CamelCase string.
+                              This field may not be empty.
+                            maxLength: 1024
+                            minLength: 1
+                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+                            type: string
+                          status:
+                            description: status of the condition, one of True, False,
+                              Unknown.
+                            enum:
+                            - "True"
+                            - "False"
+                            - Unknown
+                            type: string
+                          type:
+                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
+                            maxLength: 316
+                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+                            type: string
+                        required:
+                        - lastTransitionTime
+                        - message
+                        - reason
+                        - status
+                        - type
+                        type: object
+                      maxItems: 8
+                      minItems: 1
+                      type: array
+                      x-kubernetes-list-map-keys:
+                      - type
+                      x-kubernetes-list-type: map
+                    controllerName:
+                      description: |-
+                        ControllerName is a domain/path string that indicates the name of the
+                        controller that wrote this status. This corresponds with the
+                        controllerName field on GatewayClass.
+
+                        Example: "example.net/gateway-controller".
+
+                        The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+                        valid Kubernetes names
+                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+
+                        Controllers MUST populate this field when writing status. Controllers should ensure that
+                        entries to status populated with their ControllerName are cleaned up when they are no
+                        longer necessary.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                      type: string
+                  required:
+                  - ancestorRef
+                  - conditions
+                  - controllerName
+                  type: object
+                maxItems: 16
+                type: array
+                x-kubernetes-list-type: atomic
+            required:
+            - ancestors
+            type: object
+        required:
+        - spec
+        type: object
+    served: true
+    storage: false
 status:
   acceptedNames:
     kind: ""
diff --git a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
index 563669ba..dc78ec61 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
@@ -64,7 +64,7 @@ spec:
                   Addresses requested for this Gateway. This is optional and behavior can
                   depend on the implementation. If a value is set in the spec and the
                   requested address is invalid or unavailable, the implementation MUST
-                  indicate this in the associated entry in GatewayStatus.Addresses.
+                  indicate this in an associated entry in GatewayStatus.Conditions.
 
                   The Addresses field represents a request for the address(es) on the
                   "outside of the Gateway", that traffic bound for this Gateway will use.
@@ -119,20 +119,22 @@ spec:
                       type: string
                   type: object
                   x-kubernetes-validations:
-                  - message: Hostname value must only contain valid characters (matching
-                      ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
-                    rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""):
+                  - message: Hostname value must be empty or contain only valid characters
+                      (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
+                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$""")):
                       true'
                 maxItems: 16
                 type: array
                 x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
-                  rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
                 - message: Hostname values must be unique
-                  rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
               allowedListeners:
                 description: |-
                   AllowedListeners defines which ListenerSets can be attached to this Gateway.
@@ -1639,7 +1641,7 @@ spec:
                   Addresses requested for this Gateway. This is optional and behavior can
                   depend on the implementation. If a value is set in the spec and the
                   requested address is invalid or unavailable, the implementation MUST
-                  indicate this in the associated entry in GatewayStatus.Addresses.
+                  indicate this in an associated entry in GatewayStatus.Conditions.
 
                   The Addresses field represents a request for the address(es) on the
                   "outside of the Gateway", that traffic bound for this Gateway will use.
@@ -1694,20 +1696,22 @@ spec:
                       type: string
                   type: object
                   x-kubernetes-validations:
-                  - message: Hostname value must only contain valid characters (matching
-                      ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
-                    rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""):
+                  - message: Hostname value must be empty or contain only valid characters
+                      (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
+                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$""")):
                       true'
                 maxItems: 16
                 type: array
                 x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
-                  rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
                 - message: Hostname values must be unique
-                  rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
               allowedListeners:
                 description: |-
                   AllowedListeners defines which ListenerSets can be attached to this Gateway.
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 3f0cb0da..c21d60cb 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -4,3 +4,4 @@ resources:
 - standard/gateway.networking.k8s.io_grpcroutes.yaml
 - standard/gateway.networking.k8s.io_httproutes.yaml
 - standard/gateway.networking.k8s.io_referencegrants.yaml
+- standard/gateway.networking.k8s.io_backendtlspolicies.yaml
diff --git a/config/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml b/config/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml
new file mode 100644
index 00000000..f218dbd0
--- /dev/null
+++ b/config/crd/standard/gateway.networking.k8s.io_backendtlspolicies.yaml
@@ -0,0 +1,1318 @@
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/3328
+    gateway.networking.k8s.io/bundle-version: v1.3.0
+    gateway.networking.k8s.io/channel: standard
+  labels:
+    gateway.networking.k8s.io/policy: Direct
+  name: backendtlspolicies.gateway.networking.k8s.io
+spec:
+  group: gateway.networking.k8s.io
+  names:
+    categories:
+    - gateway-api
+    kind: BackendTLSPolicy
+    listKind: BackendTLSPolicyList
+    plural: backendtlspolicies
+    shortNames:
+    - btlspolicy
+    singular: backendtlspolicy
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1
+    schema:
+      openAPIV3Schema:
+        description: |-
+          BackendTLSPolicy provides a way to configure how a Gateway
+          connects to a Backend via TLS.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: Spec defines the desired state of BackendTLSPolicy.
+            properties:
+              options:
+                additionalProperties:
+                  description: |-
+                    AnnotationValue is the value of an annotation in Gateway API. This is used
+                    for validation of maps such as TLS options. This roughly matches Kubernetes
+                    annotation validation, although the length validation in that case is based
+                    on the entire size of the annotations struct.
+                  maxLength: 4096
+                  minLength: 0
+                  type: string
+                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.
+
+                  A 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.
+
+                  Support: Implementation-specific
+                maxProperties: 16
+                type: object
+              targetRefs:
+                description: |-
+                  TargetRefs identifies an API object to apply the policy to.
+                  Only Services have Extended support. Implementations MAY support
+                  additional objects, with Implementation Specific support.
+                  Note that this config applies to the entire referenced resource
+                  by default, but this default may change in the future to provide
+                  a more granular application of the policy.
+
+                  TargetRefs must be _distinct_. This means either that:
+
+                  * They select different targets. If this is the case, then targetRef
+                    entries are distinct. In terms of fields, this means that the
+                    multi-part key defined by `group`, `kind`, and `name` must
+                    be unique across all targetRef entries in the BackendTLSPolicy.
+                  * They select different sectionNames in the same target.
+
+                  When more than one BackendTLSPolicy selects the same target and
+                  sectionName, implementations MUST determine precedence using the
+                  following criteria, continuing on ties:
+
+                  * The older policy by creation timestamp takes precedence. For
+                    example, a policy with a creation timestamp of "2021-07-15
+                    01:02:03" MUST be given precedence over a policy with a
+                    creation timestamp of "2021-07-15 01:02:04".
+                  * The policy appearing first in alphabetical order by {name}.
+                    For example, a policy named `bar` is given precedence over a
+                    policy named `baz`.
+
+                  For any BackendTLSPolicy that does not take precedence, the
+                  implementation MUST ensure the `Accepted` Condition is set to
+                  `status: False`, with Reason `Conflicted`.
+
+                  Support: Extended for Kubernetes Service
+
+                  Support: Implementation-specific for any other resource
+                items:
+                  description: |-
+                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
+                    direct policy to. This should be used as part of Policy resources that can
+                    target single resources. For more information on how this policy attachment
+                    mode works, and a sample Policy resource, refer to the policy attachment
+                    documentation for Gateway API.
+
+                    Note: This should only be used for direct policy attachment when references
+                    to SectionName are actually needed. In all other cases,
+                    LocalPolicyTargetReference should be used.
+                  properties:
+                    group:
+                      description: Group is the group of the target resource.
+                      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 target resource.
+                      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 target resource.
+                      maxLength: 253
+                      minLength: 1
+                      type: string
+                    sectionName:
+                      description: |-
+                        SectionName is the name of a section within the target resource. When
+                        unspecified, this targetRef targets the entire resource. In the following
+                        resources, SectionName is interpreted as the following:
+
+                        * Gateway: Listener name
+                        * HTTPRoute: HTTPRouteRule name
+                        * Service: Port name
+
+                        If a SectionName is specified, but does not exist on the targeted object,
+                        the Policy must fail to attach, and the policy implementation should record
+                        a `ResolvedRefs` or similar Condition in the Policy's status.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                      type: string
+                  required:
+                  - group
+                  - kind
+                  - name
+                  type: object
+                maxItems: 16
+                minItems: 1
+                type: array
+                x-kubernetes-list-type: atomic
+                x-kubernetes-validations:
+                - message: sectionName must be specified when targetRefs includes
+                    2 or more references to the same target
+                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName
+                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))
+                    : true))'
+                - message: sectionName must be unique when targetRefs includes 2 or
+                    more references to the same target
+                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||
+                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName
+                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName
+                    == p2.sectionName))))
+              validation:
+                description: Validation contains backend TLS validation configuration.
+                properties:
+                  caCertificateRefs:
+                    description: |-
+                      CACertificateRefs contains one or more references to Kubernetes objects that
+                      contain a PEM-encoded TLS CA certificate bundle, which is used to
+                      validate a TLS handshake between the Gateway and backend Pod.
+
+                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
+                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
+                      not both. If CACertificateRefs is empty or unspecified, the configuration for
+                      WellKnownCACertificates MUST be honored instead if supported by the implementation.
+
+                      A CACertificateRef is invalid if:
+
+                      * It refers to a resource that cannot be resolved (e.g., the referenced resource
+                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key
+                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`
+                        and the Message of the Condition must indicate which reference is invalid and why.
+
+                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason
+                        must be set to `InvalidKind` and the Message of the Condition must explain which
+                        kind of resource is unknown or unsupported.
+
+                      * It refers to a resource in another namespace. This may change in future
+                        spec updates.
+
+                      Implementations MAY choose to perform further validation of the certificate
+                      content (e.g., checking expiry or enforcing specific formats). In such cases,
+                      an implementation-specific Reason and Message must be set for the invalid reference.
+
+                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on
+                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message
+                      that indicate the cause of the error. Connections using an invalid
+                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error
+                      response. If ALL CACertificateRefs are invalid, the implementation MUST also
+                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to
+                      `status: False`, with a Reason `NoValidCACertificate`.
+
+                      A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
+                      Implementations MAY choose to support attaching multiple certificates to
+                      a backend, but this behavior is implementation-specific.
+
+                      Support: Core - An optional single reference to a Kubernetes ConfigMap,
+                      with the CA certificate in a key named `ca.crt`.
+
+                      Support: Implementation-specific - More than one reference, other kinds
+                      of resources, or a single reference that includes multiple certificates.
+                    items:
+                      description: |-
+                        LocalObjectReference identifies an API object within the namespace of the
+                        referrer.
+                        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 unspecified or empty string, core API group is inferred.
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          description: Kind is kind of the referent. For example "HTTPRoute"
+                            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
+                      required:
+                      - group
+                      - kind
+                      - name
+                      type: object
+                    maxItems: 8
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  hostname:
+                    description: |-
+                      Hostname is used for two purposes in the connection between Gateways and
+                      backends:
+
+                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
+                      2. Hostname MUST be used for authentication and MUST match the certificate
+                         served by the matching backend, unless SubjectAltNames is specified.
+                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection
+                         but MUST NOT be used for authentication. If you want to use the value
+                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.
+
+                      Support: Core
+                    maxLength: 253
+                    minLength: 1
+                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                    type: string
+                  subjectAltNames:
+                    description: |-
+                      SubjectAltNames contains one or more Subject Alternative Names.
+                      When specified the certificate served from the backend MUST
+                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
+
+                      Support: Extended
+                    items:
+                      description: SubjectAltName represents Subject Alternative Name.
+                      properties:
+                        hostname:
+                          description: |-
+                            Hostname contains Subject Alternative Name specified in DNS name format.
+                            Required when Type is set to Hostname, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        type:
+                          description: |-
+                            Type determines the format of the Subject Alternative Name. Always required.
+
+                            Support: Core
+                          enum:
+                          - Hostname
+                          - URI
+                          type: string
+                        uri:
+                          description: |-
+                            URI contains Subject Alternative Name specified in a full URI format.
+                            It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
+                            Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
+                            Required when Type is set to URI, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?
+                          type: string
+                      required:
+                      - type
+                      type: object
+                      x-kubernetes-validations:
+                      - message: SubjectAltName element must contain Hostname, if
+                          Type is set to Hostname
+                        rule: '!(self.type == "Hostname" && (!has(self.hostname) ||
+                          self.hostname == ""))'
+                      - message: SubjectAltName element must not contain Hostname,
+                          if Type is not set to Hostname
+                        rule: '!(self.type != "Hostname" && has(self.hostname) &&
+                          self.hostname != "")'
+                      - message: SubjectAltName element must contain URI, if Type
+                          is set to URI
+                        rule: '!(self.type == "URI" && (!has(self.uri) || self.uri
+                          == ""))'
+                      - message: SubjectAltName element must not contain URI, if Type
+                          is not set to URI
+                        rule: '!(self.type != "URI" && has(self.uri) && self.uri !=
+                          "")'
+                    maxItems: 5
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  wellKnownCACertificates:
+                    description: |-
+                      WellKnownCACertificates specifies whether system CA certificates may be used in
+                      the TLS handshake between the gateway and backend pod.
+
+                      If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
+                      must be specified with at least one entry for a valid configuration. Only one of
+                      CACertificateRefs or WellKnownCACertificates may be specified, not both.
+                      If an implementation does not support the WellKnownCACertificates field, or
+                      the supplied value is not recognized, the implementation MUST ensure the
+                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with
+                      a Reason `Invalid`.
+
+                      Support: Implementation-specific
+                    enum:
+                    - System
+                    type: string
+                required:
+                - hostname
+                type: object
+                x-kubernetes-validations:
+                - message: must not contain both CACertificateRefs and WellKnownCACertificates
+                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")'
+                - message: must specify either CACertificateRefs or WellKnownCACertificates
+                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")
+            required:
+            - targetRefs
+            - validation
+            type: object
+          status:
+            description: Status defines the current state of BackendTLSPolicy.
+            properties:
+              ancestors:
+                description: |-
+                  Ancestors is a list of ancestor resources (usually Gateways) that are
+                  associated with the policy, and the status of the policy with respect to
+                  each ancestor. When this policy attaches to a parent, the controller that
+                  manages the parent and the ancestors MUST add an entry to this list when
+                  the controller first sees the policy and SHOULD update the entry as
+                  appropriate when the relevant ancestor is modified.
+
+                  Note that choosing the relevant ancestor is left to the Policy designers;
+                  an important part of Policy design is designing the right object level at
+                  which to namespace this status.
+
+                  Note also that implementations MUST ONLY populate ancestor status for
+                  the Ancestor resources they are responsible for. Implementations MUST
+                  use the ControllerName field to uniquely identify the entries in this list
+                  that they are responsible for.
+
+                  Note that to achieve this, the list of PolicyAncestorStatus structs
+                  MUST be treated as a map with a composite key, made up of the AncestorRef
+                  and ControllerName fields combined.
+
+                  A maximum of 16 ancestors will be represented in this list. An empty list
+                  means the Policy is not relevant for any ancestors.
+
+                  If this slice is full, implementations MUST NOT add further entries.
+                  Instead they MUST consider the policy unimplementable and signal that
+                  on any related resources such as the ancestor that would be referenced
+                  here. For example, if this list was full on BackendTLSPolicy, no
+                  additional Gateways would be able to reference the Service targeted by
+                  the BackendTLSPolicy.
+                items:
+                  description: |-
+                    PolicyAncestorStatus describes the status of a route with respect to an
+                    associated Ancestor.
+
+                    Ancestors refer to objects that are either the Target of a policy or above it
+                    in terms of object hierarchy. For example, if a policy targets a Service, the
+                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
+                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most
+                    useful object to place Policy status on, so we recommend that implementations
+                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
+                    have a _very_ good reason otherwise.
+
+                    In the context of policy attachment, the Ancestor is used to distinguish which
+                    resource results in a distinct application of this policy. For example, if a policy
+                    targets a Service, it may have a distinct result per attached Gateway.
+
+                    Policies targeting the same resource may have different effects depending on the
+                    ancestors of those resources. For example, different Gateways targeting the same
+                    Service may have different capabilities, especially if they have different underlying
+                    implementations.
+
+                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is
+                    used as a backend in a HTTPRoute that is itself attached to a Gateway.
+                    In this case, the relevant object for status is the Gateway, and that is the
+                    ancestor object referred to in this status.
+
+                    Note that a parent is also an ancestor, so for objects where the parent is the
+                    relevant object for status, this struct SHOULD still be used.
+
+                    This struct is intended to be used in a slice that's effectively a map,
+                    with a composite key made up of the AncestorRef and the ControllerName.
+                  properties:
+                    ancestorRef:
+                      description: |-
+                        AncestorRef corresponds with a ParentRef in the spec that this
+                        PolicyAncestorStatus struct describes the status of.
+                      properties:
+                        group:
+                          default: gateway.networking.k8s.io
+                          description: |-
+                            Group is the group of the referent.
+                            When unspecified, "gateway.networking.k8s.io" is inferred.
+                            To set the core API group (such as for a "Service" kind referent),
+                            Group must be explicitly set to "" (empty string).
+
+                            Support: Core
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          default: Gateway
+                          description: |-
+                            Kind is kind of the referent.
+
+                            There are two kinds of parent resources with "Core" support:
+
+                            * Gateway (Gateway conformance profile)
+                            * Service (Mesh conformance profile, ClusterIP Services only)
+
+                            Support for other resources is Implementation-Specific.
+                          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.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace is the namespace of the referent. When unspecified, this refers
+                            to the local namespace of the Route.
+
+                            Note that there are specific rules for ParentRefs which cross namespace
+                            boundaries. Cross-namespace references are only valid if they are explicitly
+                            allowed by something in the namespace they are referring to. For example:
+                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a
+                            generic way to enable any other kind of cross-namespace reference.
+
+                            Support: Core
+                          maxLength: 63
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                          type: string
+                        port:
+                          description: |-
+                            Port is the network port this Route targets. It can be interpreted
+                            differently based on the type of parent resource.
+
+                            When the parent resource is a Gateway, this targets all listeners
+                            listening on the specified port that also support this kind of Route(and
+                            select this Route). It's not recommended to set `Port` unless the
+                            networking behaviors specified in a Route must apply to a specific port
+                            as opposed to a listener(s) whose port(s) may be changed. When both Port
+                            and SectionName are specified, the name and port of the selected listener
+                            must match both specified values.
+
+                            Implementations MAY choose to support other parent resources.
+                            Implementations supporting other types of parent resources MUST clearly
+                            document how/if Port is interpreted.
+
+                            For the purpose of status, an attachment is considered successful as
+                            long as the parent resource accepts it partially. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
+                            from the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route,
+                            the Route MUST be considered detached from the Gateway.
+
+                            Support: Extended
+                          format: int32
+                          maximum: 65535
+                          minimum: 1
+                          type: integer
+                        sectionName:
+                          description: |-
+                            SectionName is the name of a section within the target resource. In the
+                            following resources, SectionName is interpreted as the following:
+
+                            * Gateway: Listener name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+                            * Service: Port name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+
+                            Implementations MAY choose to support attaching Routes to other resources.
+                            If that is the case, they MUST clearly document how SectionName is
+                            interpreted.
+
+                            When unspecified (empty string), this will reference the entire resource.
+                            For the purpose of status, an attachment is considered successful if at
+                            least one section in the parent resource accepts it. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
+                            the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route, the
+                            Route MUST be considered detached from the Gateway.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    conditions:
+                      description: Conditions describes the status of the Policy with
+                        respect to the given Ancestor.
+                      items:
+                        description: Condition contains details for one aspect of
+                          the current state of this API Resource.
+                        properties:
+                          lastTransitionTime:
+                            description: |-
+                              lastTransitionTime is the last time the condition transitioned from one status to another.
+                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.
+                            format: date-time
+                            type: string
+                          message:
+                            description: |-
+                              message is a human readable message indicating details about the transition.
+                              This may be an empty string.
+                            maxLength: 32768
+                            type: string
+                          observedGeneration:
+                            description: |-
+                              observedGeneration represents the .metadata.generation that the condition was set based upon.
+                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+                              with respect to the current state of the instance.
+                            format: int64
+                            minimum: 0
+                            type: integer
+                          reason:
+                            description: |-
+                              reason contains a programmatic identifier indicating the reason for the condition's last transition.
+                              Producers of specific condition types may define expected values and meanings for this field,
+                              and whether the values are considered a guaranteed API.
+                              The value should be a CamelCase string.
+                              This field may not be empty.
+                            maxLength: 1024
+                            minLength: 1
+                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+                            type: string
+                          status:
+                            description: status of the condition, one of True, False,
+                              Unknown.
+                            enum:
+                            - "True"
+                            - "False"
+                            - Unknown
+                            type: string
+                          type:
+                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
+                            maxLength: 316
+                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+                            type: string
+                        required:
+                        - lastTransitionTime
+                        - message
+                        - reason
+                        - status
+                        - type
+                        type: object
+                      maxItems: 8
+                      minItems: 1
+                      type: array
+                      x-kubernetes-list-map-keys:
+                      - type
+                      x-kubernetes-list-type: map
+                    controllerName:
+                      description: |-
+                        ControllerName is a domain/path string that indicates the name of the
+                        controller that wrote this status. This corresponds with the
+                        controllerName field on GatewayClass.
+
+                        Example: "example.net/gateway-controller".
+
+                        The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+                        valid Kubernetes names
+                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+
+                        Controllers MUST populate this field when writing status. Controllers should ensure that
+                        entries to status populated with their ControllerName are cleaned up when they are no
+                        longer necessary.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                      type: string
+                  required:
+                  - ancestorRef
+                  - conditions
+                  - controllerName
+                  type: object
+                maxItems: 16
+                type: array
+                x-kubernetes-list-type: atomic
+            required:
+            - ancestors
+            type: object
+        required:
+        - spec
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+  - deprecated: true
+    deprecationWarning: The v1alpha3 version of BackendTLSPolicy has been deprecated
+      and will be removed in a future release of the API. Please upgrade to v1.
+    name: v1alpha3
+    schema:
+      openAPIV3Schema:
+        description: |-
+          BackendTLSPolicy provides a way to configure how a Gateway
+          connects to a Backend via TLS.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: Spec defines the desired state of BackendTLSPolicy.
+            properties:
+              options:
+                additionalProperties:
+                  description: |-
+                    AnnotationValue is the value of an annotation in Gateway API. This is used
+                    for validation of maps such as TLS options. This roughly matches Kubernetes
+                    annotation validation, although the length validation in that case is based
+                    on the entire size of the annotations struct.
+                  maxLength: 4096
+                  minLength: 0
+                  type: string
+                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.
+
+                  A 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.
+
+                  Support: Implementation-specific
+                maxProperties: 16
+                type: object
+              targetRefs:
+                description: |-
+                  TargetRefs identifies an API object to apply the policy to.
+                  Only Services have Extended support. Implementations MAY support
+                  additional objects, with Implementation Specific support.
+                  Note that this config applies to the entire referenced resource
+                  by default, but this default may change in the future to provide
+                  a more granular application of the policy.
+
+                  TargetRefs must be _distinct_. This means either that:
+
+                  * They select different targets. If this is the case, then targetRef
+                    entries are distinct. In terms of fields, this means that the
+                    multi-part key defined by `group`, `kind`, and `name` must
+                    be unique across all targetRef entries in the BackendTLSPolicy.
+                  * They select different sectionNames in the same target.
+
+                  When more than one BackendTLSPolicy selects the same target and
+                  sectionName, implementations MUST determine precedence using the
+                  following criteria, continuing on ties:
+
+                  * The older policy by creation timestamp takes precedence. For
+                    example, a policy with a creation timestamp of "2021-07-15
+                    01:02:03" MUST be given precedence over a policy with a
+                    creation timestamp of "2021-07-15 01:02:04".
+                  * The policy appearing first in alphabetical order by {name}.
+                    For example, a policy named `bar` is given precedence over a
+                    policy named `baz`.
+
+                  For any BackendTLSPolicy that does not take precedence, the
+                  implementation MUST ensure the `Accepted` Condition is set to
+                  `status: False`, with Reason `Conflicted`.
+
+                  Support: Extended for Kubernetes Service
+
+                  Support: Implementation-specific for any other resource
+                items:
+                  description: |-
+                    LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a
+                    direct policy to. This should be used as part of Policy resources that can
+                    target single resources. For more information on how this policy attachment
+                    mode works, and a sample Policy resource, refer to the policy attachment
+                    documentation for Gateway API.
+
+                    Note: This should only be used for direct policy attachment when references
+                    to SectionName are actually needed. In all other cases,
+                    LocalPolicyTargetReference should be used.
+                  properties:
+                    group:
+                      description: Group is the group of the target resource.
+                      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 target resource.
+                      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 target resource.
+                      maxLength: 253
+                      minLength: 1
+                      type: string
+                    sectionName:
+                      description: |-
+                        SectionName is the name of a section within the target resource. When
+                        unspecified, this targetRef targets the entire resource. In the following
+                        resources, SectionName is interpreted as the following:
+
+                        * Gateway: Listener name
+                        * HTTPRoute: HTTPRouteRule name
+                        * Service: Port name
+
+                        If a SectionName is specified, but does not exist on the targeted object,
+                        the Policy must fail to attach, and the policy implementation should record
+                        a `ResolvedRefs` or similar Condition in the Policy's status.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                      type: string
+                  required:
+                  - group
+                  - kind
+                  - name
+                  type: object
+                maxItems: 16
+                minItems: 1
+                type: array
+                x-kubernetes-list-type: atomic
+                x-kubernetes-validations:
+                - message: sectionName must be specified when targetRefs includes
+                    2 or more references to the same target
+                  rule: 'self.all(p1, self.all(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName
+                    == '''') == (!has(p2.sectionName) || p2.sectionName == ''''))
+                    : true))'
+                - message: sectionName must be unique when targetRefs includes 2 or
+                    more references to the same target
+                  rule: self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind
+                    == p2.kind && p1.name == p2.name && (((!has(p1.sectionName) ||
+                    p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName
+                    == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName
+                    == p2.sectionName))))
+              validation:
+                description: Validation contains backend TLS validation configuration.
+                properties:
+                  caCertificateRefs:
+                    description: |-
+                      CACertificateRefs contains one or more references to Kubernetes objects that
+                      contain a PEM-encoded TLS CA certificate bundle, which is used to
+                      validate a TLS handshake between the Gateway and backend Pod.
+
+                      If CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be
+                      specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified,
+                      not both. If CACertificateRefs is empty or unspecified, the configuration for
+                      WellKnownCACertificates MUST be honored instead if supported by the implementation.
+
+                      A CACertificateRef is invalid if:
+
+                      * It refers to a resource that cannot be resolved (e.g., the referenced resource
+                        does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key
+                        named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`
+                        and the Message of the Condition must indicate which reference is invalid and why.
+
+                      * It refers to an unknown or unsupported kind of resource. In this case, the Reason
+                        must be set to `InvalidKind` and the Message of the Condition must explain which
+                        kind of resource is unknown or unsupported.
+
+                      * It refers to a resource in another namespace. This may change in future
+                        spec updates.
+
+                      Implementations MAY choose to perform further validation of the certificate
+                      content (e.g., checking expiry or enforcing specific formats). In such cases,
+                      an implementation-specific Reason and Message must be set for the invalid reference.
+
+                      In all cases, the implementation MUST ensure the `ResolvedRefs` Condition on
+                      the BackendTLSPolicy is set to `status: False`, with a Reason and Message
+                      that indicate the cause of the error. Connections using an invalid
+                      CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error
+                      response. If ALL CACertificateRefs are invalid, the implementation MUST also
+                      ensure the `Accepted` Condition on the BackendTLSPolicy is set to
+                      `status: False`, with a Reason `NoValidCACertificate`.
+
+                      A single CACertificateRef to a Kubernetes ConfigMap kind has "Core" support.
+                      Implementations MAY choose to support attaching multiple certificates to
+                      a backend, but this behavior is implementation-specific.
+
+                      Support: Core - An optional single reference to a Kubernetes ConfigMap,
+                      with the CA certificate in a key named `ca.crt`.
+
+                      Support: Implementation-specific - More than one reference, other kinds
+                      of resources, or a single reference that includes multiple certificates.
+                    items:
+                      description: |-
+                        LocalObjectReference identifies an API object within the namespace of the
+                        referrer.
+                        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 unspecified or empty string, core API group is inferred.
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          description: Kind is kind of the referent. For example "HTTPRoute"
+                            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
+                      required:
+                      - group
+                      - kind
+                      - name
+                      type: object
+                    maxItems: 8
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  hostname:
+                    description: |-
+                      Hostname is used for two purposes in the connection between Gateways and
+                      backends:
+
+                      1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066).
+                      2. Hostname MUST be used for authentication and MUST match the certificate
+                         served by the matching backend, unless SubjectAltNames is specified.
+                      3. If SubjectAltNames are specified, Hostname can be used for certificate selection
+                         but MUST NOT be used for authentication. If you want to use the value
+                         of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.
+
+                      Support: Core
+                    maxLength: 253
+                    minLength: 1
+                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                    type: string
+                  subjectAltNames:
+                    description: |-
+                      SubjectAltNames contains one or more Subject Alternative Names.
+                      When specified the certificate served from the backend MUST
+                      have at least one Subject Alternate Name matching one of the specified SubjectAltNames.
+
+                      Support: Extended
+                    items:
+                      description: SubjectAltName represents Subject Alternative Name.
+                      properties:
+                        hostname:
+                          description: |-
+                            Hostname contains Subject Alternative Name specified in DNS name format.
+                            Required when Type is set to Hostname, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        type:
+                          description: |-
+                            Type determines the format of the Subject Alternative Name. Always required.
+
+                            Support: Core
+                          enum:
+                          - Hostname
+                          - URI
+                          type: string
+                        uri:
+                          description: |-
+                            URI contains Subject Alternative Name specified in a full URI format.
+                            It MUST include both a scheme (e.g., "http" or "ftp") and a scheme-specific-part.
+                            Common values include SPIFFE IDs like "spiffe://mycluster.example.com/ns/myns/sa/svc1sa".
+                            Required when Type is set to URI, ignored otherwise.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^(([^:/?#]+):)(//([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?
+                          type: string
+                      required:
+                      - type
+                      type: object
+                      x-kubernetes-validations:
+                      - message: SubjectAltName element must contain Hostname, if
+                          Type is set to Hostname
+                        rule: '!(self.type == "Hostname" && (!has(self.hostname) ||
+                          self.hostname == ""))'
+                      - message: SubjectAltName element must not contain Hostname,
+                          if Type is not set to Hostname
+                        rule: '!(self.type != "Hostname" && has(self.hostname) &&
+                          self.hostname != "")'
+                      - message: SubjectAltName element must contain URI, if Type
+                          is set to URI
+                        rule: '!(self.type == "URI" && (!has(self.uri) || self.uri
+                          == ""))'
+                      - message: SubjectAltName element must not contain URI, if Type
+                          is not set to URI
+                        rule: '!(self.type != "URI" && has(self.uri) && self.uri !=
+                          "")'
+                    maxItems: 5
+                    type: array
+                    x-kubernetes-list-type: atomic
+                  wellKnownCACertificates:
+                    description: |-
+                      WellKnownCACertificates specifies whether system CA certificates may be used in
+                      the TLS handshake between the gateway and backend pod.
+
+                      If WellKnownCACertificates is unspecified or empty (""), then CACertificateRefs
+                      must be specified with at least one entry for a valid configuration. Only one of
+                      CACertificateRefs or WellKnownCACertificates may be specified, not both.
+                      If an implementation does not support the WellKnownCACertificates field, or
+                      the supplied value is not recognized, the implementation MUST ensure the
+                      `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with
+                      a Reason `Invalid`.
+
+                      Support: Implementation-specific
+                    enum:
+                    - System
+                    type: string
+                required:
+                - hostname
+                type: object
+                x-kubernetes-validations:
+                - message: must not contain both CACertificateRefs and WellKnownCACertificates
+                  rule: '!(has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 && has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")'
+                - message: must specify either CACertificateRefs or WellKnownCACertificates
+                  rule: (has(self.caCertificateRefs) && size(self.caCertificateRefs)
+                    > 0 || has(self.wellKnownCACertificates) && self.wellKnownCACertificates
+                    != "")
+            required:
+            - targetRefs
+            - validation
+            type: object
+          status:
+            description: Status defines the current state of BackendTLSPolicy.
+            properties:
+              ancestors:
+                description: |-
+                  Ancestors is a list of ancestor resources (usually Gateways) that are
+                  associated with the policy, and the status of the policy with respect to
+                  each ancestor. When this policy attaches to a parent, the controller that
+                  manages the parent and the ancestors MUST add an entry to this list when
+                  the controller first sees the policy and SHOULD update the entry as
+                  appropriate when the relevant ancestor is modified.
+
+                  Note that choosing the relevant ancestor is left to the Policy designers;
+                  an important part of Policy design is designing the right object level at
+                  which to namespace this status.
+
+                  Note also that implementations MUST ONLY populate ancestor status for
+                  the Ancestor resources they are responsible for. Implementations MUST
+                  use the ControllerName field to uniquely identify the entries in this list
+                  that they are responsible for.
+
+                  Note that to achieve this, the list of PolicyAncestorStatus structs
+                  MUST be treated as a map with a composite key, made up of the AncestorRef
+                  and ControllerName fields combined.
+
+                  A maximum of 16 ancestors will be represented in this list. An empty list
+                  means the Policy is not relevant for any ancestors.
+
+                  If this slice is full, implementations MUST NOT add further entries.
+                  Instead they MUST consider the policy unimplementable and signal that
+                  on any related resources such as the ancestor that would be referenced
+                  here. For example, if this list was full on BackendTLSPolicy, no
+                  additional Gateways would be able to reference the Service targeted by
+                  the BackendTLSPolicy.
+                items:
+                  description: |-
+                    PolicyAncestorStatus describes the status of a route with respect to an
+                    associated Ancestor.
+
+                    Ancestors refer to objects that are either the Target of a policy or above it
+                    in terms of object hierarchy. For example, if a policy targets a Service, the
+                    Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and
+                    the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most
+                    useful object to place Policy status on, so we recommend that implementations
+                    SHOULD use Gateway as the PolicyAncestorStatus object unless the designers
+                    have a _very_ good reason otherwise.
+
+                    In the context of policy attachment, the Ancestor is used to distinguish which
+                    resource results in a distinct application of this policy. For example, if a policy
+                    targets a Service, it may have a distinct result per attached Gateway.
+
+                    Policies targeting the same resource may have different effects depending on the
+                    ancestors of those resources. For example, different Gateways targeting the same
+                    Service may have different capabilities, especially if they have different underlying
+                    implementations.
+
+                    For example, in BackendTLSPolicy, the Policy attaches to a Service that is
+                    used as a backend in a HTTPRoute that is itself attached to a Gateway.
+                    In this case, the relevant object for status is the Gateway, and that is the
+                    ancestor object referred to in this status.
+
+                    Note that a parent is also an ancestor, so for objects where the parent is the
+                    relevant object for status, this struct SHOULD still be used.
+
+                    This struct is intended to be used in a slice that's effectively a map,
+                    with a composite key made up of the AncestorRef and the ControllerName.
+                  properties:
+                    ancestorRef:
+                      description: |-
+                        AncestorRef corresponds with a ParentRef in the spec that this
+                        PolicyAncestorStatus struct describes the status of.
+                      properties:
+                        group:
+                          default: gateway.networking.k8s.io
+                          description: |-
+                            Group is the group of the referent.
+                            When unspecified, "gateway.networking.k8s.io" is inferred.
+                            To set the core API group (such as for a "Service" kind referent),
+                            Group must be explicitly set to "" (empty string).
+
+                            Support: Core
+                          maxLength: 253
+                          pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                        kind:
+                          default: Gateway
+                          description: |-
+                            Kind is kind of the referent.
+
+                            There are two kinds of parent resources with "Core" support:
+
+                            * Gateway (Gateway conformance profile)
+                            * Service (Mesh conformance profile, ClusterIP Services only)
+
+                            Support for other resources is Implementation-Specific.
+                          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.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          type: string
+                        namespace:
+                          description: |-
+                            Namespace is the namespace of the referent. When unspecified, this refers
+                            to the local namespace of the Route.
+
+                            Note that there are specific rules for ParentRefs which cross namespace
+                            boundaries. Cross-namespace references are only valid if they are explicitly
+                            allowed by something in the namespace they are referring to. For example:
+                            Gateway has the AllowedRoutes field, and ReferenceGrant provides a
+                            generic way to enable any other kind of cross-namespace reference.
+
+                            Support: Core
+                          maxLength: 63
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
+                          type: string
+                        port:
+                          description: |-
+                            Port is the network port this Route targets. It can be interpreted
+                            differently based on the type of parent resource.
+
+                            When the parent resource is a Gateway, this targets all listeners
+                            listening on the specified port that also support this kind of Route(and
+                            select this Route). It's not recommended to set `Port` unless the
+                            networking behaviors specified in a Route must apply to a specific port
+                            as opposed to a listener(s) whose port(s) may be changed. When both Port
+                            and SectionName are specified, the name and port of the selected listener
+                            must match both specified values.
+
+                            Implementations MAY choose to support other parent resources.
+                            Implementations supporting other types of parent resources MUST clearly
+                            document how/if Port is interpreted.
+
+                            For the purpose of status, an attachment is considered successful as
+                            long as the parent resource accepts it partially. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
+                            from the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route,
+                            the Route MUST be considered detached from the Gateway.
+
+                            Support: Extended
+                          format: int32
+                          maximum: 65535
+                          minimum: 1
+                          type: integer
+                        sectionName:
+                          description: |-
+                            SectionName is the name of a section within the target resource. In the
+                            following resources, SectionName is interpreted as the following:
+
+                            * Gateway: Listener name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+                            * Service: Port name. When both Port (experimental) and SectionName
+                            are specified, the name and port of the selected listener must match
+                            both specified values.
+
+                            Implementations MAY choose to support attaching Routes to other resources.
+                            If that is the case, they MUST clearly document how SectionName is
+                            interpreted.
+
+                            When unspecified (empty string), this will reference the entire resource.
+                            For the purpose of status, an attachment is considered successful if at
+                            least one section in the parent resource accepts it. For example, Gateway
+                            listeners can restrict which Routes can attach to them by Route kind,
+                            namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
+                            the referencing Route, the Route MUST be considered successfully
+                            attached. If no Gateway listeners accept attachment from this Route, the
+                            Route MUST be considered detached from the Gateway.
+
+                            Support: Core
+                          maxLength: 253
+                          minLength: 1
+                          pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                          type: string
+                      required:
+                      - name
+                      type: object
+                    conditions:
+                      description: Conditions describes the status of the Policy with
+                        respect to the given Ancestor.
+                      items:
+                        description: Condition contains details for one aspect of
+                          the current state of this API Resource.
+                        properties:
+                          lastTransitionTime:
+                            description: |-
+                              lastTransitionTime is the last time the condition transitioned from one status to another.
+                              This should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.
+                            format: date-time
+                            type: string
+                          message:
+                            description: |-
+                              message is a human readable message indicating details about the transition.
+                              This may be an empty string.
+                            maxLength: 32768
+                            type: string
+                          observedGeneration:
+                            description: |-
+                              observedGeneration represents the .metadata.generation that the condition was set based upon.
+                              For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
+                              with respect to the current state of the instance.
+                            format: int64
+                            minimum: 0
+                            type: integer
+                          reason:
+                            description: |-
+                              reason contains a programmatic identifier indicating the reason for the condition's last transition.
+                              Producers of specific condition types may define expected values and meanings for this field,
+                              and whether the values are considered a guaranteed API.
+                              The value should be a CamelCase string.
+                              This field may not be empty.
+                            maxLength: 1024
+                            minLength: 1
+                            pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
+                            type: string
+                          status:
+                            description: status of the condition, one of True, False,
+                              Unknown.
+                            enum:
+                            - "True"
+                            - "False"
+                            - Unknown
+                            type: string
+                          type:
+                            description: type of condition in CamelCase or in foo.example.com/CamelCase.
+                            maxLength: 316
+                            pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
+                            type: string
+                        required:
+                        - lastTransitionTime
+                        - message
+                        - reason
+                        - status
+                        - type
+                        type: object
+                      maxItems: 8
+                      minItems: 1
+                      type: array
+                      x-kubernetes-list-map-keys:
+                      - type
+                      x-kubernetes-list-type: map
+                    controllerName:
+                      description: |-
+                        ControllerName is a domain/path string that indicates the name of the
+                        controller that wrote this status. This corresponds with the
+                        controllerName field on GatewayClass.
+
+                        Example: "example.net/gateway-controller".
+
+                        The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
+                        valid Kubernetes names
+                        (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
+
+                        Controllers MUST populate this field when writing status. Controllers should ensure that
+                        entries to status populated with their ControllerName are cleaned up when they are no
+                        longer necessary.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$
+                      type: string
+                  required:
+                  - ancestorRef
+                  - conditions
+                  - controllerName
+                  type: object
+                maxItems: 16
+                type: array
+                x-kubernetes-list-type: atomic
+            required:
+            - ancestors
+            type: object
+        required:
+        - spec
+        type: object
+    served: false
+    storage: false
+status:
+  acceptedNames:
+    kind: ""
+    plural: ""
+  conditions: null
+  storedVersions: null
diff --git a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
index 98914347..43ab793f 100644
--- a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
@@ -64,7 +64,7 @@ spec:
                   Addresses requested for this Gateway. This is optional and behavior can
                   depend on the implementation. If a value is set in the spec and the
                   requested address is invalid or unavailable, the implementation MUST
-                  indicate this in the associated entry in GatewayStatus.Addresses.
+                  indicate this in an associated entry in GatewayStatus.Conditions.
 
                   The Addresses field represents a request for the address(es) on the
                   "outside of the Gateway", that traffic bound for this Gateway will use.
@@ -119,20 +119,22 @@ spec:
                       type: string
                   type: object
                   x-kubernetes-validations:
-                  - message: Hostname value must only contain valid characters (matching
-                      ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
-                    rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""):
+                  - message: Hostname value must be empty or contain only valid characters
+                      (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
+                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$""")):
                       true'
                 maxItems: 16
                 type: array
                 x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
-                  rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
                 - message: Hostname values must be unique
-                  rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
               gatewayClassName:
                 description: |-
                   GatewayClassName used for this Gateway. This is the name of a
@@ -1175,7 +1177,7 @@ spec:
                   Addresses requested for this Gateway. This is optional and behavior can
                   depend on the implementation. If a value is set in the spec and the
                   requested address is invalid or unavailable, the implementation MUST
-                  indicate this in the associated entry in GatewayStatus.Addresses.
+                  indicate this in an associated entry in GatewayStatus.Conditions.
 
                   The Addresses field represents a request for the address(es) on the
                   "outside of the Gateway", that traffic bound for this Gateway will use.
@@ -1230,20 +1232,22 @@ spec:
                       type: string
                   type: object
                   x-kubernetes-validations:
-                  - message: Hostname value must only contain valid characters (matching
-                      ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
-                    rule: 'self.type == ''Hostname'' ? self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"""):
+                  - message: Hostname value must be empty or contain only valid characters
+                      (matching ^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$)
+                    rule: 'self.type == ''Hostname'' ? (!has(self.value) || self.value.matches(r"""^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$""")):
                       true'
                 maxItems: 16
                 type: array
                 x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
-                  rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''IPAddress'' && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
                 - message: Hostname values must be unique
-                  rule: 'self.all(a1, a1.type == ''Hostname'' ? self.exists_one(a2,
-                    a2.type == a1.type && a2.value == a1.value) : true )'
+                  rule: 'self.all(a1, a1.type == ''Hostname''  && has(a1.value) ?
+                    self.exists_one(a2, a2.type == a1.type && has(a2.value) && a2.value
+                    == a1.value) : true )'
               gatewayClassName:
                 description: |-
                   GatewayClassName used for this Gateway. This is the name of a
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index 3309c8f2..d37d16af 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -37,7 +37,6 @@ import (
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/apis/v1alpha2"
-	"sigs.k8s.io/gateway-api/apis/v1alpha3"
 	"sigs.k8s.io/gateway-api/conformance/utils/config"
 	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
 )
@@ -1000,7 +999,7 @@ func findPodConditionInList(t *testing.T, conditions []v1.PodCondition, condName
 func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeoutConfig config.TimeoutConfig, policyNN, gwNN types.NamespacedName, condition metav1.Condition) {
 	t.Helper()
 	waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeoutConfig.HTTPRouteMustHaveCondition, true, func(ctx context.Context) (bool, error) {
-		policy := &v1alpha3.BackendTLSPolicy{}
+		policy := &gatewayv1.BackendTLSPolicy{}
 		err := client.Get(ctx, policyNN, policy)
 		if err != nil {
 			return false, fmt.Errorf("error fetching BackendTLSPolicy %v err: %w", policyNN, err)
@@ -1029,7 +1028,7 @@ func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeo
 
 // BackendTLSPolicyMustHaveLatestConditions will fail the test if there are
 // conditions that were not updated
-func BackendTLSPolicyMustHaveLatestConditions(t *testing.T, r *v1alpha3.BackendTLSPolicy) {
+func BackendTLSPolicyMustHaveLatestConditions(t *testing.T, r *gatewayv1.BackendTLSPolicy) {
 	t.Helper()
 
 	for _, ancestor := range r.Status.Ancestors {
diff --git a/examples/experimental/v1alpha3/backendtlspolicy-ca-certs.yaml b/examples/standard/backendtlspolicy/backendtlspolicy-ca-certs.yaml
similarity index 86%
rename from examples/experimental/v1alpha3/backendtlspolicy-ca-certs.yaml
rename to examples/standard/backendtlspolicy/backendtlspolicy-ca-certs.yaml
index 574ac5a8..3cac8646 100644
--- a/examples/experimental/v1alpha3/backendtlspolicy-ca-certs.yaml
+++ b/examples/standard/backendtlspolicy/backendtlspolicy-ca-certs.yaml
@@ -1,6 +1,6 @@
 #$ Used in:
 #$ - site-src/guides/tls.md
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: tls-upstream-auth
diff --git a/examples/experimental/v1alpha3/backendtlspolicy-system-certs.yaml b/examples/standard/backendtlspolicy/backendtlspolicy-system-certs.yaml
similarity index 84%
rename from examples/experimental/v1alpha3/backendtlspolicy-system-certs.yaml
rename to examples/standard/backendtlspolicy/backendtlspolicy-system-certs.yaml
index 82dd5006..b5bf80b1 100644
--- a/examples/experimental/v1alpha3/backendtlspolicy-system-certs.yaml
+++ b/examples/standard/backendtlspolicy/backendtlspolicy-system-certs.yaml
@@ -1,6 +1,6 @@
 #$ Used in:
 #$ - site-src/guides/tls.md
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: tls-upstream-dev
diff --git a/pkg/client/clientset/versioned/typed/apis/v1/apis_client.go b/pkg/client/clientset/versioned/typed/apis/v1/apis_client.go
index 7ed0bc4d..c3a8ce11 100644
--- a/pkg/client/clientset/versioned/typed/apis/v1/apis_client.go
+++ b/pkg/client/clientset/versioned/typed/apis/v1/apis_client.go
@@ -28,6 +28,7 @@ import (
 
 type GatewayV1Interface interface {
 	RESTClient() rest.Interface
+	BackendTLSPoliciesGetter
 	GRPCRoutesGetter
 	GatewaysGetter
 	GatewayClassesGetter
@@ -39,6 +40,10 @@ type GatewayV1Client struct {
 	restClient rest.Interface
 }
 
+func (c *GatewayV1Client) BackendTLSPolicies(namespace string) BackendTLSPolicyInterface {
+	return newBackendTLSPolicies(c, namespace)
+}
+
 func (c *GatewayV1Client) GRPCRoutes(namespace string) GRPCRouteInterface {
 	return newGRPCRoutes(c, namespace)
 }
diff --git a/pkg/client/clientset/versioned/typed/apis/v1/backendtlspolicy.go b/pkg/client/clientset/versioned/typed/apis/v1/backendtlspolicy.go
new file mode 100644
index 00000000..8e5b2738
--- /dev/null
+++ b/pkg/client/clientset/versioned/typed/apis/v1/backendtlspolicy.go
@@ -0,0 +1,74 @@
+/*
+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 client-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	context "context"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	types "k8s.io/apimachinery/pkg/types"
+	watch "k8s.io/apimachinery/pkg/watch"
+	gentype "k8s.io/client-go/gentype"
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+	applyconfigurationapisv1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
+	scheme "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/scheme"
+)
+
+// BackendTLSPoliciesGetter has a method to return a BackendTLSPolicyInterface.
+// A group's client should implement this interface.
+type BackendTLSPoliciesGetter interface {
+	BackendTLSPolicies(namespace string) BackendTLSPolicyInterface
+}
+
+// BackendTLSPolicyInterface has methods to work with BackendTLSPolicy resources.
+type BackendTLSPolicyInterface interface {
+	Create(ctx context.Context, backendTLSPolicy *apisv1.BackendTLSPolicy, opts metav1.CreateOptions) (*apisv1.BackendTLSPolicy, error)
+	Update(ctx context.Context, backendTLSPolicy *apisv1.BackendTLSPolicy, opts metav1.UpdateOptions) (*apisv1.BackendTLSPolicy, error)
+	// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
+	UpdateStatus(ctx context.Context, backendTLSPolicy *apisv1.BackendTLSPolicy, opts metav1.UpdateOptions) (*apisv1.BackendTLSPolicy, error)
+	Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error
+	DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error
+	Get(ctx context.Context, name string, opts metav1.GetOptions) (*apisv1.BackendTLSPolicy, error)
+	List(ctx context.Context, opts metav1.ListOptions) (*apisv1.BackendTLSPolicyList, error)
+	Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
+	Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *apisv1.BackendTLSPolicy, err error)
+	Apply(ctx context.Context, backendTLSPolicy *applyconfigurationapisv1.BackendTLSPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *apisv1.BackendTLSPolicy, err error)
+	// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus().
+	ApplyStatus(ctx context.Context, backendTLSPolicy *applyconfigurationapisv1.BackendTLSPolicyApplyConfiguration, opts metav1.ApplyOptions) (result *apisv1.BackendTLSPolicy, err error)
+	BackendTLSPolicyExpansion
+}
+
+// backendTLSPolicies implements BackendTLSPolicyInterface
+type backendTLSPolicies struct {
+	*gentype.ClientWithListAndApply[*apisv1.BackendTLSPolicy, *apisv1.BackendTLSPolicyList, *applyconfigurationapisv1.BackendTLSPolicyApplyConfiguration]
+}
+
+// newBackendTLSPolicies returns a BackendTLSPolicies
+func newBackendTLSPolicies(c *GatewayV1Client, namespace string) *backendTLSPolicies {
+	return &backendTLSPolicies{
+		gentype.NewClientWithListAndApply[*apisv1.BackendTLSPolicy, *apisv1.BackendTLSPolicyList, *applyconfigurationapisv1.BackendTLSPolicyApplyConfiguration](
+			"backendtlspolicies",
+			c.RESTClient(),
+			scheme.ParameterCodec,
+			namespace,
+			func() *apisv1.BackendTLSPolicy { return &apisv1.BackendTLSPolicy{} },
+			func() *apisv1.BackendTLSPolicyList { return &apisv1.BackendTLSPolicyList{} },
+		),
+	}
+}
diff --git a/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_apis_client.go b/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_apis_client.go
index 0b68bad3..b4acb441 100644
--- a/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_apis_client.go
+++ b/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_apis_client.go
@@ -28,6 +28,10 @@ type FakeGatewayV1 struct {
 	*testing.Fake
 }
 
+func (c *FakeGatewayV1) BackendTLSPolicies(namespace string) v1.BackendTLSPolicyInterface {
+	return newFakeBackendTLSPolicies(c, namespace)
+}
+
 func (c *FakeGatewayV1) GRPCRoutes(namespace string) v1.GRPCRouteInterface {
 	return newFakeGRPCRoutes(c, namespace)
 }
diff --git a/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_backendtlspolicy.go b/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_backendtlspolicy.go
new file mode 100644
index 00000000..986ba484
--- /dev/null
+++ b/pkg/client/clientset/versioned/typed/apis/v1/fake/fake_backendtlspolicy.go
@@ -0,0 +1,51 @@
+/*
+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 client-gen. DO NOT EDIT.
+
+package fake
+
+import (
+	gentype "k8s.io/client-go/gentype"
+	v1 "sigs.k8s.io/gateway-api/apis/v1"
+	apisv1 "sigs.k8s.io/gateway-api/applyconfiguration/apis/v1"
+	typedapisv1 "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned/typed/apis/v1"
+)
+
+// fakeBackendTLSPolicies implements BackendTLSPolicyInterface
+type fakeBackendTLSPolicies struct {
+	*gentype.FakeClientWithListAndApply[*v1.BackendTLSPolicy, *v1.BackendTLSPolicyList, *apisv1.BackendTLSPolicyApplyConfiguration]
+	Fake *FakeGatewayV1
+}
+
+func newFakeBackendTLSPolicies(fake *FakeGatewayV1, namespace string) typedapisv1.BackendTLSPolicyInterface {
+	return &fakeBackendTLSPolicies{
+		gentype.NewFakeClientWithListAndApply[*v1.BackendTLSPolicy, *v1.BackendTLSPolicyList, *apisv1.BackendTLSPolicyApplyConfiguration](
+			fake.Fake,
+			namespace,
+			v1.SchemeGroupVersion.WithResource("backendtlspolicies"),
+			v1.SchemeGroupVersion.WithKind("BackendTLSPolicy"),
+			func() *v1.BackendTLSPolicy { return &v1.BackendTLSPolicy{} },
+			func() *v1.BackendTLSPolicyList { return &v1.BackendTLSPolicyList{} },
+			func(dst, src *v1.BackendTLSPolicyList) { dst.ListMeta = src.ListMeta },
+			func(list *v1.BackendTLSPolicyList) []*v1.BackendTLSPolicy { return gentype.ToPointerSlice(list.Items) },
+			func(list *v1.BackendTLSPolicyList, items []*v1.BackendTLSPolicy) {
+				list.Items = gentype.FromPointerSlice(items)
+			},
+		),
+		fake,
+	}
+}
diff --git a/pkg/client/clientset/versioned/typed/apis/v1/generated_expansion.go b/pkg/client/clientset/versioned/typed/apis/v1/generated_expansion.go
index 69d7f1f9..0ed9e12b 100644
--- a/pkg/client/clientset/versioned/typed/apis/v1/generated_expansion.go
+++ b/pkg/client/clientset/versioned/typed/apis/v1/generated_expansion.go
@@ -18,6 +18,8 @@ limitations under the License.
 
 package v1
 
+type BackendTLSPolicyExpansion interface{}
+
 type GRPCRouteExpansion interface{}
 
 type GatewayExpansion interface{}
diff --git a/pkg/client/informers/externalversions/apis/v1/backendtlspolicy.go b/pkg/client/informers/externalversions/apis/v1/backendtlspolicy.go
new file mode 100644
index 00000000..281489e4
--- /dev/null
+++ b/pkg/client/informers/externalversions/apis/v1/backendtlspolicy.go
@@ -0,0 +1,102 @@
+/*
+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 informer-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	context "context"
+	time "time"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	runtime "k8s.io/apimachinery/pkg/runtime"
+	watch "k8s.io/apimachinery/pkg/watch"
+	cache "k8s.io/client-go/tools/cache"
+	gatewayapiapisv1 "sigs.k8s.io/gateway-api/apis/v1"
+	versioned "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned"
+	internalinterfaces "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions/internalinterfaces"
+	apisv1 "sigs.k8s.io/gateway-api/pkg/client/listers/apis/v1"
+)
+
+// BackendTLSPolicyInformer provides access to a shared informer and lister for
+// BackendTLSPolicies.
+type BackendTLSPolicyInformer interface {
+	Informer() cache.SharedIndexInformer
+	Lister() apisv1.BackendTLSPolicyLister
+}
+
+type backendTLSPolicyInformer struct {
+	factory          internalinterfaces.SharedInformerFactory
+	tweakListOptions internalinterfaces.TweakListOptionsFunc
+	namespace        string
+}
+
+// NewBackendTLSPolicyInformer constructs a new informer for BackendTLSPolicy type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewBackendTLSPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
+	return NewFilteredBackendTLSPolicyInformer(client, namespace, resyncPeriod, indexers, nil)
+}
+
+// NewFilteredBackendTLSPolicyInformer constructs a new informer for BackendTLSPolicy type.
+// Always prefer using an informer factory to get a shared informer instead of getting an independent
+// one. This reduces memory footprint and number of connections to the server.
+func NewFilteredBackendTLSPolicyInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
+	return cache.NewSharedIndexInformer(
+		&cache.ListWatch{
+			ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.GatewayV1().BackendTLSPolicies(namespace).List(context.Background(), options)
+			},
+			WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.GatewayV1().BackendTLSPolicies(namespace).Watch(context.Background(), options)
+			},
+			ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.GatewayV1().BackendTLSPolicies(namespace).List(ctx, options)
+			},
+			WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) {
+				if tweakListOptions != nil {
+					tweakListOptions(&options)
+				}
+				return client.GatewayV1().BackendTLSPolicies(namespace).Watch(ctx, options)
+			},
+		},
+		&gatewayapiapisv1.BackendTLSPolicy{},
+		resyncPeriod,
+		indexers,
+	)
+}
+
+func (f *backendTLSPolicyInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
+	return NewFilteredBackendTLSPolicyInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
+}
+
+func (f *backendTLSPolicyInformer) Informer() cache.SharedIndexInformer {
+	return f.factory.InformerFor(&gatewayapiapisv1.BackendTLSPolicy{}, f.defaultInformer)
+}
+
+func (f *backendTLSPolicyInformer) Lister() apisv1.BackendTLSPolicyLister {
+	return apisv1.NewBackendTLSPolicyLister(f.Informer().GetIndexer())
+}
diff --git a/pkg/client/informers/externalversions/apis/v1/interface.go b/pkg/client/informers/externalversions/apis/v1/interface.go
index 18666f97..d0fd01c9 100644
--- a/pkg/client/informers/externalversions/apis/v1/interface.go
+++ b/pkg/client/informers/externalversions/apis/v1/interface.go
@@ -24,6 +24,8 @@ import (
 
 // Interface provides access to all the informers in this group version.
 type Interface interface {
+	// BackendTLSPolicies returns a BackendTLSPolicyInformer.
+	BackendTLSPolicies() BackendTLSPolicyInformer
 	// GRPCRoutes returns a GRPCRouteInformer.
 	GRPCRoutes() GRPCRouteInformer
 	// Gateways returns a GatewayInformer.
@@ -45,6 +47,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
 	return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
 }
 
+// BackendTLSPolicies returns a BackendTLSPolicyInformer.
+func (v *version) BackendTLSPolicies() BackendTLSPolicyInformer {
+	return &backendTLSPolicyInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
+}
+
 // GRPCRoutes returns a GRPCRouteInformer.
 func (v *version) GRPCRoutes() GRPCRouteInformer {
 	return &gRPCRouteInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go
index e3f00492..2f690b8f 100644
--- a/pkg/client/informers/externalversions/generic.go
+++ b/pkg/client/informers/externalversions/generic.go
@@ -57,6 +57,8 @@ func (f *genericInformer) Lister() cache.GenericLister {
 func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
 	switch resource {
 	// Group=gateway.networking.k8s.io, Version=v1
+	case v1.SchemeGroupVersion.WithResource("backendtlspolicies"):
+		return &genericInformer{resource: resource.GroupResource(), informer: f.Gateway().V1().BackendTLSPolicies().Informer()}, nil
 	case v1.SchemeGroupVersion.WithResource("grpcroutes"):
 		return &genericInformer{resource: resource.GroupResource(), informer: f.Gateway().V1().GRPCRoutes().Informer()}, nil
 	case v1.SchemeGroupVersion.WithResource("gateways"):
diff --git a/pkg/client/listers/apis/v1/backendtlspolicy.go b/pkg/client/listers/apis/v1/backendtlspolicy.go
new file mode 100644
index 00000000..a5dda655
--- /dev/null
+++ b/pkg/client/listers/apis/v1/backendtlspolicy.go
@@ -0,0 +1,70 @@
+/*
+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 lister-gen. DO NOT EDIT.
+
+package v1
+
+import (
+	labels "k8s.io/apimachinery/pkg/labels"
+	listers "k8s.io/client-go/listers"
+	cache "k8s.io/client-go/tools/cache"
+	apisv1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+// BackendTLSPolicyLister helps list BackendTLSPolicies.
+// All objects returned here must be treated as read-only.
+type BackendTLSPolicyLister interface {
+	// List lists all BackendTLSPolicies in the indexer.
+	// Objects returned here must be treated as read-only.
+	List(selector labels.Selector) (ret []*apisv1.BackendTLSPolicy, err error)
+	// BackendTLSPolicies returns an object that can list and get BackendTLSPolicies.
+	BackendTLSPolicies(namespace string) BackendTLSPolicyNamespaceLister
+	BackendTLSPolicyListerExpansion
+}
+
+// backendTLSPolicyLister implements the BackendTLSPolicyLister interface.
+type backendTLSPolicyLister struct {
+	listers.ResourceIndexer[*apisv1.BackendTLSPolicy]
+}
+
+// NewBackendTLSPolicyLister returns a new BackendTLSPolicyLister.
+func NewBackendTLSPolicyLister(indexer cache.Indexer) BackendTLSPolicyLister {
+	return &backendTLSPolicyLister{listers.New[*apisv1.BackendTLSPolicy](indexer, apisv1.Resource("backendtlspolicy"))}
+}
+
+// BackendTLSPolicies returns an object that can list and get BackendTLSPolicies.
+func (s *backendTLSPolicyLister) BackendTLSPolicies(namespace string) BackendTLSPolicyNamespaceLister {
+	return backendTLSPolicyNamespaceLister{listers.NewNamespaced[*apisv1.BackendTLSPolicy](s.ResourceIndexer, namespace)}
+}
+
+// BackendTLSPolicyNamespaceLister helps list and get BackendTLSPolicies.
+// All objects returned here must be treated as read-only.
+type BackendTLSPolicyNamespaceLister interface {
+	// List lists all BackendTLSPolicies in the indexer for a given namespace.
+	// Objects returned here must be treated as read-only.
+	List(selector labels.Selector) (ret []*apisv1.BackendTLSPolicy, err error)
+	// Get retrieves the BackendTLSPolicy from the indexer for a given namespace and name.
+	// Objects returned here must be treated as read-only.
+	Get(name string) (*apisv1.BackendTLSPolicy, error)
+	BackendTLSPolicyNamespaceListerExpansion
+}
+
+// backendTLSPolicyNamespaceLister implements the BackendTLSPolicyNamespaceLister
+// interface.
+type backendTLSPolicyNamespaceLister struct {
+	listers.ResourceIndexer[*apisv1.BackendTLSPolicy]
+}
diff --git a/pkg/client/listers/apis/v1/expansion_generated.go b/pkg/client/listers/apis/v1/expansion_generated.go
index 4324e255..1627fa33 100644
--- a/pkg/client/listers/apis/v1/expansion_generated.go
+++ b/pkg/client/listers/apis/v1/expansion_generated.go
@@ -18,6 +18,14 @@ limitations under the License.
 
 package v1
 
+// BackendTLSPolicyListerExpansion allows custom methods to be added to
+// BackendTLSPolicyLister.
+type BackendTLSPolicyListerExpansion interface{}
+
+// BackendTLSPolicyNamespaceListerExpansion allows custom methods to be added to
+// BackendTLSPolicyNamespaceLister.
+type BackendTLSPolicyNamespaceListerExpansion interface{}
+
 // GRPCRouteListerExpansion allows custom methods to be added to
 // GRPCRouteLister.
 type GRPCRouteListerExpansion interface{}
diff --git a/pkg/features/backendtlspolicy.go b/pkg/features/backendtlspolicy.go
index 12c6a24c..391e29c9 100644
--- a/pkg/features/backendtlspolicy.go
+++ b/pkg/features/backendtlspolicy.go
@@ -33,7 +33,7 @@ const (
 // TLSRouteFeature contains metadata for the TLSRoute feature.
 var BackendTLSPolicyFeature = Feature{
 	Name:    SupportBackendTLSPolicy,
-	Channel: FeatureChannelExperimental,
+	Channel: FeatureChannelStandard,
 }
 
 // BackendTLSPolicySanValidationFeature contains metadata for the BackendTLSPolicy
diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go
index bfa005be..b11d00af 100644
--- a/pkg/generated/openapi/zz_generated.openapi.go
+++ b/pkg/generated/openapi/zz_generated.openapi.go
@@ -86,6 +86,10 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"sigs.k8s.io/gateway-api/apis/v1.AllowedRoutes":                                   schema_sigsk8sio_gateway_api_apis_v1_AllowedRoutes(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.BackendObjectReference":                          schema_sigsk8sio_gateway_api_apis_v1_BackendObjectReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.BackendRef":                                      schema_sigsk8sio_gateway_api_apis_v1_BackendRef(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicy":                                schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicy(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicyList":                            schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicyList(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicySpec":                            schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicySpec(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicyValidation":                      schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicyValidation(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.CommonRouteSpec":                                 schema_sigsk8sio_gateway_api_apis_v1_CommonRouteSpec(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.CookieConfig":                                    schema_sigsk8sio_gateway_api_apis_v1_CookieConfig(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ForwardBodyConfig":                               schema_sigsk8sio_gateway_api_apis_v1_ForwardBodyConfig(ref),
@@ -144,15 +148,21 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"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.LocalPolicyTargetReference":                      schema_sigsk8sio_gateway_api_apis_v1_LocalPolicyTargetReference(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReferenceWithSectionName":       schema_sigsk8sio_gateway_api_apis_v1_LocalPolicyTargetReferenceWithSectionName(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.NamespacedPolicyTargetReference":                 schema_sigsk8sio_gateway_api_apis_v1_NamespacedPolicyTargetReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ObjectReference":                                 schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ParametersReference":                             schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.ParentReference":                                 schema_sigsk8sio_gateway_api_apis_v1_ParentReference(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.PolicyAncestorStatus":                            schema_sigsk8sio_gateway_api_apis_v1_PolicyAncestorStatus(ref),
+		"sigs.k8s.io/gateway-api/apis/v1.PolicyStatus":                                    schema_sigsk8sio_gateway_api_apis_v1_PolicyStatus(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.RouteGroupKind":                                  schema_sigsk8sio_gateway_api_apis_v1_RouteGroupKind(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.RouteNamespaces":                                 schema_sigsk8sio_gateway_api_apis_v1_RouteNamespaces(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.RouteParentStatus":                               schema_sigsk8sio_gateway_api_apis_v1_RouteParentStatus(ref),
 		"sigs.k8s.io/gateway-api/apis/v1.RouteStatus":                                     schema_sigsk8sio_gateway_api_apis_v1_RouteStatus(ref),
 		"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.SubjectAltName":                                  schema_sigsk8sio_gateway_api_apis_v1_SubjectAltName(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),
@@ -183,9 +193,6 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA
 		"sigs.k8s.io/gateway-api/apis/v1alpha2.UDPRouteStatus":                            schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteStatus(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicy":                          schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicy(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicyList":                      schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyList(ref),
-		"sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicySpec":                      schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicySpec(ref),
-		"sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicyValidation":                schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyValidation(ref),
-		"sigs.k8s.io/gateway-api/apis/v1alpha3.SubjectAltName":                            schema_sigsk8sio_gateway_api_apis_v1alpha3_SubjectAltName(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha3.TLSRoute":                                  schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRoute(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha3.TLSRouteList":                              schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRouteList(ref),
 		"sigs.k8s.io/gateway-api/apis/v1alpha3.TLSRouteSpec":                              schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRouteSpec(ref),
@@ -3019,6 +3026,237 @@ func schema_sigsk8sio_gateway_api_apis_v1_BackendRef(ref common.ReferenceCallbac
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicy(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "BackendTLSPolicy provides a way to configure how a Gateway connects to a Backend via TLS.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"kind": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"apiVersion": {
+						SchemaProps: spec.SchemaProps{
+							Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"metadata": {
+						SchemaProps: spec.SchemaProps{
+							Default: map[string]interface{}{},
+							Ref:     ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"),
+						},
+					},
+					"spec": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Spec defines the desired state of BackendTLSPolicy.",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicySpec"),
+						},
+					},
+					"status": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Status defines the current state of BackendTLSPolicy.",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.PolicyStatus"),
+						},
+					},
+				},
+				Required: []string{"spec"},
+			},
+		},
+		Dependencies: []string{
+			"k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicySpec", "sigs.k8s.io/gateway-api/apis/v1.PolicyStatus"},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicyList(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "BackendTLSPolicyList contains a list of BackendTLSPolicies",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"kind": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"apiVersion": {
+						SchemaProps: spec.SchemaProps{
+							Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"metadata": {
+						SchemaProps: spec.SchemaProps{
+							Default: map[string]interface{}{},
+							Ref:     ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"),
+						},
+					},
+					"items": {
+						SchemaProps: spec.SchemaProps{
+							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.BackendTLSPolicy"),
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"items"},
+			},
+		},
+		Dependencies: []string{
+			"k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta", "sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicy"},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicySpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "BackendTLSPolicySpec defines the desired state of BackendTLSPolicy.\n\nSupport: Extended",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"targetRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "TargetRefs identifies an API object to apply the policy to. Only Services have Extended support. Implementations MAY support additional objects, with Implementation Specific support. Note that this config applies to the entire referenced resource by default, but this default may change in the future to provide a more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, and `name` must\n  be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and sectionName, implementations MUST determine precedence using the following criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n  example, a policy with a creation timestamp of \"2021-07-15\n  01:02:03\" MUST be given precedence over a policy with a\n  creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {name}.\n  For example, a policy named `bar` is given precedence over a\n  policy named `baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the implementation MUST ensure the `Accepted` Condition is set to `status: False`, with Reason `Conflicted`.\n\nSupport: Extended for Kubernetes Service\n\nSupport: Implementation-specific for any other resource",
+							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.LocalPolicyTargetReferenceWithSectionName"),
+									},
+								},
+							},
+						},
+					},
+					"validation": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Validation contains backend TLS validation configuration.",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicyValidation"),
+						},
+					},
+					"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:  "",
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"targetRefs", "validation"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicyValidation", "sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReferenceWithSectionName"},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_BackendTLSPolicyValidation(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "BackendTLSPolicyValidation contains backend TLS validation configuration.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"caCertificateRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "CACertificateRefs contains one or more references to Kubernetes objects that contain a PEM-encoded TLS CA certificate bundle, which is used to validate a TLS handshake between the Gateway and backend Pod.\n\nIf CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If CACertificateRefs is empty or unspecified, the configuration for WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the referenced resource\n  does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n  named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n  and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this case, the Reason\n  must be set to `InvalidKind` and the Message of the Condition must explain which\n  kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace. This may change in future\n  spec updates.\n\nImplementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message must be set for the invalid reference.\n\nIn all cases, the implementation MUST ensure the `ResolvedRefs` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason and Message that indicate the cause of the error. Connections using an invalid CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error response. If ALL CACertificateRefs are invalid, the implementation MUST also ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `NoValidCACertificate`.\n\nA single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific.\n\nSupport: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates.",
+							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.LocalObjectReference"),
+									},
+								},
+							},
+						},
+					},
+					"wellKnownCACertificates": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "WellKnownCACertificates specifies whether system CA certificates may be used in the TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs must be specified with at least one entry for a valid configuration. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If an implementation does not support the WellKnownCACertificates field, or the supplied value is not recognized, the implementation MUST ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `Invalid`.\n\nSupport: Implementation-specific",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"hostname": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Hostname is used for two purposes in the connection between Gateways and backends:\n\n1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). 2. Hostname MUST be used for authentication and MUST match the certificate\n   served by the matching backend, unless SubjectAltNames is specified.\n3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n   but MUST NOT be used for authentication. If you want to use the value\n   of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\nSupport: Core",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"subjectAltNames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "SubjectAltNames contains one or more Subject Alternative Names. When specified the certificate served from the backend MUST have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\nSupport: Extended",
+							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.SubjectAltName"),
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"hostname"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.LocalObjectReference", "sigs.k8s.io/gateway-api/apis/v1.SubjectAltName"},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_CommonRouteSpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -4196,7 +4434,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 							},
 						},
 						SchemaProps: spec.SchemaProps{
-							Description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses.\n\nThe Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to.\n\nIf no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses.\n\nThe implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses.\n\nSupport: Extended\n\n<gateway:validateIPAddress>",
+							Description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in an associated entry in GatewayStatus.Conditions.\n\nThe Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to.\n\nIf no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses.\n\nThe implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses.\n\nSupport: Extended\n\n<gateway:validateIPAddress>",
 							Type:        []string{"array"},
 							Items: &spec.SchemaOrArray{
 								Schema: &spec.Schema{
@@ -5877,16 +6115,16 @@ func schema_sigsk8sio_gateway_api_apis_v1_LocalParametersReference(ref common.Re
 	}
 }
 
-func schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+func schema_sigsk8sio_gateway_api_apis_v1_LocalPolicyTargetReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid.\n\nReferences 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.",
+				Description: "LocalPolicyTargetReference identifies an API object to apply a direct or inherited policy to. This should be used as part of Policy resources that can target Gateway API resources. For more information on how this policy attachment model works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
-							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.",
+							Description: "Group is the group of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
@@ -5894,7 +6132,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref common.ReferenceCa
 					},
 					"kind": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
+							Description: "Kind is kind of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
@@ -5902,19 +6140,12 @@ func schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref common.ReferenceCa
 					},
 					"name": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Name is the name of the referent.",
+							Description: "Name is the name of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
 						},
 					},
-					"namespace": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Namespace is the namespace of the referenced object. When unspecified, the local namespace is inferred.\n\nNote 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.\n\nSupport: Core",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
 				},
 				Required: []string{"group", "kind", "name"},
 			},
@@ -5922,16 +6153,16 @@ func schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref common.ReferenceCa
 	}
 }
 
-func schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+func schema_sigsk8sio_gateway_api_apis_v1_LocalPolicyTargetReferenceWithSectionName(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "ParametersReference identifies an API object containing controller-specific configuration resource within the cluster.",
+				Description: "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a direct policy to. This should be used as part of Policy resources that can target single resources. For more information on how this policy attachment mode works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references to SectionName are actually needed. In all other cases, LocalPolicyTargetReference should be used.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Group is the group of the referent.",
+							Description: "Group is the group of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
@@ -5939,7 +6170,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref common.Referen
 					},
 					"kind": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Kind is kind of the referent.",
+							Description: "Kind is kind of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
@@ -5947,15 +6178,15 @@ func schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref common.Referen
 					},
 					"name": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Name is the name of the referent.",
+							Description: "Name is the name of the target resource.",
 							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
 						},
 					},
-					"namespace": {
+					"sectionName": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Namespace is the namespace of the referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource.",
+							Description: "SectionName is the name of a section within the target resource. When unspecified, this targetRef targets the entire resource. In the following resources, SectionName is interpreted as the following:\n\n* Gateway: Listener name * HTTPRoute: HTTPRouteRule name * Service: Port name\n\nIf a SectionName is specified, but does not exist on the targeted object, the Policy must fail to attach, and the policy implementation should record a `ResolvedRefs` or similar Condition in the Policy's status.",
 							Type:        []string{"string"},
 							Format:      "",
 						},
@@ -5967,28 +6198,163 @@ func schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref common.Referen
 	}
 }
 
-func schema_sigsk8sio_gateway_api_apis_v1_ParentReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+func schema_sigsk8sio_gateway_api_apis_v1_NamespacedPolicyTargetReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nThe API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid.",
+				Description: "NamespacedPolicyTargetReference identifies an API object to apply a direct or inherited policy to, potentially in a different namespace. This should only be used as part of Policy resources that need to be able to target resources in different namespaces. For more information on how this policy attachment model works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.",
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string).\n\nSupport: Core",
+							Description: "Group is the group of the target resource.",
+							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
 						},
 					},
 					"kind": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
+							Description: "Kind is kind of the target resource.",
+							Default:     "",
 							Type:        []string{"string"},
 							Format:      "",
 						},
 					},
-					"namespace": {
+					"name": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Name is the name of the target resource.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"namespace": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Namespace is the namespace of the referent. When unspecified, the local namespace is inferred. Even when policy targets a resource in a different namespace, it MUST only apply to traffic originating from the same namespace as the policy.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+				},
+				Required: []string{"group", "kind", "name"},
+			},
+		},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_ObjectReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "ObjectReference identifies an API object including its namespace.\n\nThe API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid.\n\nReferences 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.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"group": {
+						SchemaProps: spec.SchemaProps{
+							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.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"kind": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Kind is kind of the referent. For example \"ConfigMap\" or \"Service\".",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"name": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Name is the name of the referent.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"namespace": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Namespace is the namespace of the referenced object. When unspecified, the local namespace is inferred.\n\nNote 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.\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+				},
+				Required: []string{"group", "kind", "name"},
+			},
+		},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_ParametersReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "ParametersReference identifies an API object containing controller-specific configuration resource within the cluster.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"group": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Group is the group of the referent.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"kind": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Kind is kind of the referent.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"name": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Name is the name of the referent.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"namespace": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Namespace is the namespace of the referent. This field is required when referring to a Namespace-scoped resource and MUST be unset when referring to a Cluster-scoped resource.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+				},
+				Required: []string{"group", "kind", "name"},
+			},
+		},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_ParentReference(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "ParentReference identifies an API object (usually a Gateway) that can be considered a parent of this resource (usually a route). There are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nThe API object must be valid in the cluster; the Group and Kind must be registered in the cluster for this reference to be valid.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"group": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Group is the group of the referent. When unspecified, \"gateway.networking.k8s.io\" is inferred. To set the core API group (such as for a \"Service\" kind referent), Group must be explicitly set to \"\" (empty string).\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"kind": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Kind is kind of the referent.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nSupport for other resources is Implementation-Specific.",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"namespace": {
 						SchemaProps: spec.SchemaProps{
 							Description: "Namespace is the namespace of the referent. When unspecified, this refers to the local namespace of the Route.\n\nNote that there are specific rules for ParentRefs which cross namespace boundaries. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example: Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable any other kind of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\nSupport: Core",
 							Type:        []string{"string"},
@@ -6024,6 +6390,94 @@ func schema_sigsk8sio_gateway_api_apis_v1_ParentReference(ref common.ReferenceCa
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_PolicyAncestorStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "PolicyAncestorStatus describes the status of a route with respect to an associated Ancestor.\n\nAncestors refer to objects that are either the Target of a policy or above it in terms of object hierarchy. For example, if a policy targets a Service, the Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most useful object to place Policy status on, so we recommend that implementations SHOULD use Gateway as the PolicyAncestorStatus object unless the designers have a _very_ good reason otherwise.\n\nIn the context of policy attachment, the Ancestor is used to distinguish which resource results in a distinct application of this policy. For example, if a policy targets a Service, it may have a distinct result per attached Gateway.\n\nPolicies targeting the same resource may have different effects depending on the ancestors of those resources. For example, different Gateways targeting the same Service may have different capabilities, especially if they have different underlying implementations.\n\nFor example, in BackendTLSPolicy, the Policy attaches to a Service that is used as a backend in a HTTPRoute that is itself attached to a Gateway. In this case, the relevant object for status is the Gateway, and that is the ancestor object referred to in this status.\n\nNote that a parent is also an ancestor, so for objects where the parent is the relevant object for status, this struct SHOULD still be used.\n\nThis struct is intended to be used in a slice that's effectively a map, with a composite key made up of the AncestorRef and the ControllerName.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"ancestorRef": {
+						SchemaProps: spec.SchemaProps{
+							Description: "AncestorRef corresponds with a ParentRef in the spec that this PolicyAncestorStatus struct describes the status of.",
+							Default:     map[string]interface{}{},
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.ParentReference"),
+						},
+					},
+					"controllerName": {
+						SchemaProps: spec.SchemaProps{
+							Description: "ControllerName is a domain/path string that indicates the name of the controller that wrote this status. This corresponds with the controllerName field on GatewayClass.\n\nExample: \"example.net/gateway-controller\".\n\nThe format of this field is DOMAIN \"/\" PATH, where DOMAIN and PATH are valid Kubernetes names (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).\n\nControllers MUST populate this field when writing status. Controllers should ensure that entries to status populated with their ControllerName are cleaned up when they are no longer necessary.",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"conditions": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-map-keys": []interface{}{
+									"type",
+								},
+								"x-kubernetes-list-type": "map",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "Conditions describes the status of the Policy with respect to the given Ancestor.\n\n<gateway:util:excludeFromCRD>\n\nNotes for implementors:\n\nConditions are a listType `map`, which means that they function like a map with a key of the `type` field _in the k8s apiserver_.\n\nThis means that implementations must obey some rules when updating this section.\n\n* Implementations MUST perform a read-modify-write cycle on this field\n  before modifying it. That is, when modifying this field, implementations\n  must be confident they have fetched the most recent version of this field,\n  and ensure that changes they make are on that recent version.\n* Implementations MUST NOT remove or reorder Conditions that they are not\n  directly responsible for. For example, if an implementation sees a Condition\n  with type `special.io/SomeField`, it MUST NOT remove, change or update that\n  Condition.\n* Implementations MUST always _merge_ changes into Conditions of the same Type,\n  rather than creating more than one Condition of the same Type.\n* Implementations MUST always update the `observedGeneration` field of the\n  Condition to the `metadata.generation` of the Gateway at the time of update creation.\n* If the `observedGeneration` of a Condition is _greater than_ the value the\n  implementation knows about, then it MUST NOT perform the update on that Condition,\n  but must wait for a future reconciliation and status update. (The assumption is that\n  the implementation's copy of the object is stale and an update will be re-triggered\n  if relevant.)\n\n</gateway:util:excludeFromCRD>",
+							Type:        []string{"array"},
+							Items: &spec.SchemaOrArray{
+								Schema: &spec.Schema{
+									SchemaProps: spec.SchemaProps{
+										Default: map[string]interface{}{},
+										Ref:     ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"),
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"ancestorRef", "controllerName", "conditions"},
+			},
+		},
+		Dependencies: []string{
+			"k8s.io/apimachinery/pkg/apis/meta/v1.Condition", "sigs.k8s.io/gateway-api/apis/v1.ParentReference"},
+	}
+}
+
+func schema_sigsk8sio_gateway_api_apis_v1_PolicyStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "PolicyStatus defines the common attributes that all Policies should include within their status.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"ancestors": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
+						SchemaProps: spec.SchemaProps{
+							Description: "Ancestors is a list of ancestor resources (usually Gateways) that are associated with the policy, and the status of the policy with respect to each ancestor. When this policy attaches to a parent, the controller that manages the parent and the ancestors MUST add an entry to this list when the controller first sees the policy and SHOULD update the entry as appropriate when the relevant ancestor is modified.\n\nNote that choosing the relevant ancestor is left to the Policy designers; an important part of Policy design is designing the right object level at which to namespace this status.\n\nNote also that implementations MUST ONLY populate ancestor status for the Ancestor resources they are responsible for. Implementations MUST use the ControllerName field to uniquely identify the entries in this list that they are responsible for.\n\nNote that to achieve this, the list of PolicyAncestorStatus structs MUST be treated as a map with a composite key, made up of the AncestorRef and ControllerName fields combined.\n\nA maximum of 16 ancestors will be represented in this list. An empty list means the Policy is not relevant for any ancestors.\n\nIf this slice is full, implementations MUST NOT add further entries. Instead they MUST consider the policy unimplementable and signal that on any related resources such as the ancestor that would be referenced here. For example, if this list was full on BackendTLSPolicy, no additional Gateways would be able to reference the Service targeted by the BackendTLSPolicy.",
+							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.PolicyAncestorStatus"),
+									},
+								},
+							},
+						},
+					},
+				},
+				Required: []string{"ancestors"},
+			},
+		},
+		Dependencies: []string{
+			"sigs.k8s.io/gateway-api/apis/v1.PolicyAncestorStatus"},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_RouteGroupKind(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -6261,6 +6715,42 @@ func schema_sigsk8sio_gateway_api_apis_v1_SessionPersistence(ref common.Referenc
 	}
 }
 
+func schema_sigsk8sio_gateway_api_apis_v1_SubjectAltName(ref common.ReferenceCallback) common.OpenAPIDefinition {
+	return common.OpenAPIDefinition{
+		Schema: spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Description: "SubjectAltName represents Subject Alternative Name.",
+				Type:        []string{"object"},
+				Properties: map[string]spec.Schema{
+					"type": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Type determines the format of the Subject Alternative Name. Always required.\n\nSupport: Core",
+							Default:     "",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"hostname": {
+						SchemaProps: spec.SchemaProps{
+							Description: "Hostname contains Subject Alternative Name specified in DNS name format. Required when Type is set to Hostname, ignored otherwise.\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+					"uri": {
+						SchemaProps: spec.SchemaProps{
+							Description: "URI contains Subject Alternative Name specified in a full URI format. It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part. Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\". Required when Type is set to URI, ignored otherwise.\n\nSupport: Core",
+							Type:        []string{"string"},
+							Format:      "",
+						},
+					},
+				},
+				Required: []string{"type"},
+			},
+		},
+	}
+}
+
 func schema_sigsk8sio_gateway_api_apis_v1_SupportedFeature(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -6454,8 +6944,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_LocalPolicyTargetReference(ref c
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "LocalPolicyTargetReference identifies an API object to apply a direct or inherited policy to. This should be used as part of Policy resources that can target Gateway API resources. For more information on how this policy attachment model works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
@@ -6492,8 +6981,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_LocalPolicyTargetReferenceWithSe
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "LocalPolicyTargetReferenceWithSectionName identifies an API object to apply a direct policy to. This should be used as part of Policy resources that can target single resources. For more information on how this policy attachment mode works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.\n\nNote: This should only be used for direct policy attachment when references to SectionName are actually needed. In all other cases, LocalPolicyTargetReference should be used.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
@@ -6537,8 +7025,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_NamespacedPolicyTargetReference(
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "NamespacedPolicyTargetReference identifies an API object to apply a direct or inherited policy to, potentially in a different namespace. This should only be used as part of Policy resources that need to be able to target resources in different namespaces. For more information on how this policy attachment model works, and a sample Policy resource, refer to the policy attachment documentation for Gateway API.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"group": {
 						SchemaProps: spec.SchemaProps{
@@ -6582,8 +7069,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyAncestorStatus(ref common.
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "PolicyAncestorStatus describes the status of a route with respect to an associated Ancestor.\n\nAncestors refer to objects that are either the Target of a policy or above it in terms of object hierarchy. For example, if a policy targets a Service, the Policy's Ancestors are, in order, the Service, the HTTPRoute, the Gateway, and the GatewayClass. Almost always, in this hierarchy, the Gateway will be the most useful object to place Policy status on, so we recommend that implementations SHOULD use Gateway as the PolicyAncestorStatus object unless the designers have a _very_ good reason otherwise.\n\nIn the context of policy attachment, the Ancestor is used to distinguish which resource results in a distinct application of this policy. For example, if a policy targets a Service, it may have a distinct result per attached Gateway.\n\nPolicies targeting the same resource may have different effects depending on the ancestors of those resources. For example, different Gateways targeting the same Service may have different capabilities, especially if they have different underlying implementations.\n\nFor example, in BackendTLSPolicy, the Policy attaches to a Service that is used as a backend in a HTTPRoute that is itself attached to a Gateway. In this case, the relevant object for status is the Gateway, and that is the ancestor object referred to in this status.\n\nNote that a parent is also an ancestor, so for objects where the parent is the relevant object for status, this struct SHOULD still be used.\n\nThis struct is intended to be used in a slice that's effectively a map, with a composite key made up of the AncestorRef and the ControllerName.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"ancestorRef": {
 						SchemaProps: spec.SchemaProps{
@@ -6635,8 +7121,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyStatus(ref common.Referenc
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "PolicyStatus defines the common attributes that all Policies should include within their status.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"ancestors": {
 						VendorExtensible: spec.VendorExtensible{
@@ -6651,7 +7136,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyStatus(ref common.Referenc
 								Schema: &spec.Schema{
 									SchemaProps: spec.SchemaProps{
 										Default: map[string]interface{}{},
-										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyAncestorStatus"),
+										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1.PolicyAncestorStatus"),
 									},
 								},
 							},
@@ -6662,7 +7147,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyStatus(ref common.Referenc
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyAncestorStatus"},
+			"sigs.k8s.io/gateway-api/apis/v1.PolicyAncestorStatus"},
 	}
 }
 
@@ -7492,8 +7977,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicy(ref common.Refe
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "BackendTLSPolicy provides a way to configure how a Gateway connects to a Backend via TLS.",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"kind": {
 						SchemaProps: spec.SchemaProps{
@@ -7519,14 +8003,14 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicy(ref common.Refe
 						SchemaProps: spec.SchemaProps{
 							Description: "Spec defines the desired state of BackendTLSPolicy.",
 							Default:     map[string]interface{}{},
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicySpec"),
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicySpec"),
 						},
 					},
 					"status": {
 						SchemaProps: spec.SchemaProps{
 							Description: "Status defines the current state of BackendTLSPolicy.",
 							Default:     map[string]interface{}{},
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus"),
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.PolicyStatus"),
 						},
 					},
 				},
@@ -7534,7 +8018,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicy(ref common.Refe
 			},
 		},
 		Dependencies: []string{
-			"k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus", "sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicySpec"},
+			"k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "sigs.k8s.io/gateway-api/apis/v1.BackendTLSPolicySpec", "sigs.k8s.io/gateway-api/apis/v1.PolicyStatus"},
 	}
 }
 
@@ -7542,8 +8026,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyList(ref common.
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
 			SchemaProps: spec.SchemaProps{
-				Description: "BackendTLSPolicyList contains a list of BackendTLSPolicies",
-				Type:        []string{"object"},
+				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"kind": {
 						SchemaProps: spec.SchemaProps{
@@ -7587,174 +8070,6 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyList(ref common.
 	}
 }
 
-func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicySpec(ref common.ReferenceCallback) common.OpenAPIDefinition {
-	return common.OpenAPIDefinition{
-		Schema: spec.Schema{
-			SchemaProps: spec.SchemaProps{
-				Description: "BackendTLSPolicySpec defines the desired state of BackendTLSPolicy.\n\nSupport: Extended",
-				Type:        []string{"object"},
-				Properties: map[string]spec.Schema{
-					"targetRefs": {
-						VendorExtensible: spec.VendorExtensible{
-							Extensions: spec.Extensions{
-								"x-kubernetes-list-type": "atomic",
-							},
-						},
-						SchemaProps: spec.SchemaProps{
-							Description: "TargetRefs identifies an API object to apply the policy to. Only Services have Extended support. Implementations MAY support additional objects, with Implementation Specific support. Note that this config applies to the entire referenced resource by default, but this default may change in the future to provide a more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, and `name` must\n  be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nWhen more than one BackendTLSPolicy selects the same target and sectionName, implementations MUST determine precedence using the following criteria, continuing on ties:\n\n* The older policy by creation timestamp takes precedence. For\n  example, a policy with a creation timestamp of \"2021-07-15\n  01:02:03\" MUST be given precedence over a policy with a\n  creation timestamp of \"2021-07-15 01:02:04\".\n* The policy appearing first in alphabetical order by {name}.\n  For example, a policy named `bar` is given precedence over a\n  policy named `baz`.\n\nFor any BackendTLSPolicy that does not take precedence, the implementation MUST ensure the `Accepted` Condition is set to `status: False`, with Reason `Conflicted`.\n\nSupport: Extended for Kubernetes Service\n\nSupport: Implementation-specific for any other resource",
-							Type:        []string{"array"},
-							Items: &spec.SchemaOrArray{
-								Schema: &spec.Schema{
-									SchemaProps: spec.SchemaProps{
-										Default: map[string]interface{}{},
-										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReferenceWithSectionName"),
-									},
-								},
-							},
-						},
-					},
-					"validation": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Validation contains backend TLS validation configuration.",
-							Default:     map[string]interface{}{},
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicyValidation"),
-						},
-					},
-					"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:  "",
-									},
-								},
-							},
-						},
-					},
-				},
-				Required: []string{"targetRefs", "validation"},
-			},
-		},
-		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReferenceWithSectionName", "sigs.k8s.io/gateway-api/apis/v1alpha3.BackendTLSPolicyValidation"},
-	}
-}
-
-func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyValidation(ref common.ReferenceCallback) common.OpenAPIDefinition {
-	return common.OpenAPIDefinition{
-		Schema: spec.Schema{
-			SchemaProps: spec.SchemaProps{
-				Description: "BackendTLSPolicyValidation contains backend TLS validation configuration.",
-				Type:        []string{"object"},
-				Properties: map[string]spec.Schema{
-					"caCertificateRefs": {
-						VendorExtensible: spec.VendorExtensible{
-							Extensions: spec.Extensions{
-								"x-kubernetes-list-type": "atomic",
-							},
-						},
-						SchemaProps: spec.SchemaProps{
-							Description: "CACertificateRefs contains one or more references to Kubernetes objects that contain a PEM-encoded TLS CA certificate bundle, which is used to validate a TLS handshake between the Gateway and backend Pod.\n\nIf CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If CACertificateRefs is empty or unspecified, the configuration for WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\nA CACertificateRef is invalid if:\n\n* It refers to a resource that cannot be resolved (e.g., the referenced resource\n  does not exist) or is misconfigured (e.g., a ConfigMap does not contain a key\n  named `ca.crt`). In this case, the Reason must be set to `InvalidCACertificateRef`\n  and the Message of the Condition must indicate which reference is invalid and why.\n\n* It refers to an unknown or unsupported kind of resource. In this case, the Reason\n  must be set to `InvalidKind` and the Message of the Condition must explain which\n  kind of resource is unknown or unsupported.\n\n* It refers to a resource in another namespace. This may change in future\n  spec updates.\n\nImplementations MAY choose to perform further validation of the certificate content (e.g., checking expiry or enforcing specific formats). In such cases, an implementation-specific Reason and Message must be set for the invalid reference.\n\nIn all cases, the implementation MUST ensure the `ResolvedRefs` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason and Message that indicate the cause of the error. Connections using an invalid CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error response. If ALL CACertificateRefs are invalid, the implementation MUST also ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `NoValidCACertificate`.\n\nA single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific.\n\nSupport: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific - More than one reference, other kinds of resources, or a single reference that includes multiple certificates.",
-							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.LocalObjectReference"),
-									},
-								},
-							},
-						},
-					},
-					"wellKnownCACertificates": {
-						VendorExtensible: spec.VendorExtensible{
-							Extensions: spec.Extensions{
-								"x-kubernetes-list-type": "atomic",
-							},
-						},
-						SchemaProps: spec.SchemaProps{
-							Description: "WellKnownCACertificates specifies whether system CA certificates may be used in the TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs must be specified with at least one entry for a valid configuration. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If an implementation does not support the WellKnownCACertificates field, or the supplied value is not recognized, the implementation MUST ensure the `Accepted` Condition on the BackendTLSPolicy is set to `status: False`, with a Reason `Invalid`.\n\nSupport: Implementation-specific",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
-					"hostname": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Hostname is used for two purposes in the connection between Gateways and backends:\n\n1. Hostname MUST be used as the SNI to connect to the backend (RFC 6066). 2. Hostname MUST be used for authentication and MUST match the certificate\n   served by the matching backend, unless SubjectAltNames is specified.\n3. If SubjectAltNames are specified, Hostname can be used for certificate selection\n   but MUST NOT be used for authentication. If you want to use the value\n   of the Hostname field for authentication, you MUST add it to the SubjectAltNames list.\n\nSupport: Core",
-							Default:     "",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
-					"subjectAltNames": {
-						VendorExtensible: spec.VendorExtensible{
-							Extensions: spec.Extensions{
-								"x-kubernetes-list-type": "atomic",
-							},
-						},
-						SchemaProps: spec.SchemaProps{
-							Description: "SubjectAltNames contains one or more Subject Alternative Names. When specified the certificate served from the backend MUST have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\nSupport: Extended",
-							Type:        []string{"array"},
-							Items: &spec.SchemaOrArray{
-								Schema: &spec.Schema{
-									SchemaProps: spec.SchemaProps{
-										Default: map[string]interface{}{},
-										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1alpha3.SubjectAltName"),
-									},
-								},
-							},
-						},
-					},
-				},
-				Required: []string{"hostname"},
-			},
-		},
-		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.LocalObjectReference", "sigs.k8s.io/gateway-api/apis/v1alpha3.SubjectAltName"},
-	}
-}
-
-func schema_sigsk8sio_gateway_api_apis_v1alpha3_SubjectAltName(ref common.ReferenceCallback) common.OpenAPIDefinition {
-	return common.OpenAPIDefinition{
-		Schema: spec.Schema{
-			SchemaProps: spec.SchemaProps{
-				Description: "SubjectAltName represents Subject Alternative Name.",
-				Type:        []string{"object"},
-				Properties: map[string]spec.Schema{
-					"type": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Type determines the format of the Subject Alternative Name. Always required.\n\nSupport: Core",
-							Default:     "",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
-					"hostname": {
-						SchemaProps: spec.SchemaProps{
-							Description: "Hostname contains Subject Alternative Name specified in DNS name format. Required when Type is set to Hostname, ignored otherwise.\n\nSupport: Core",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
-					"uri": {
-						SchemaProps: spec.SchemaProps{
-							Description: "URI contains Subject Alternative Name specified in a full URI format. It MUST include both a scheme (e.g., \"http\" or \"ftp\") and a scheme-specific-part. Common values include SPIFFE IDs like \"spiffe://mycluster.example.com/ns/myns/sa/svc1sa\". Required when Type is set to URI, ignored otherwise.\n\nSupport: Core",
-							Type:        []string{"string"},
-							Format:      "",
-						},
-					},
-				},
-				Required: []string{"type"},
-			},
-		},
-	}
-}
-
 func schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRoute(ref common.ReferenceCallback) common.OpenAPIDefinition {
 	return common.OpenAPIDefinition{
 		Schema: spec.Schema{
@@ -8477,7 +8792,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_BackendTrafficPolicySpec(ref co
 								Schema: &spec.Schema{
 									SchemaProps: spec.SchemaProps{
 										Default: map[string]interface{}{},
-										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference"),
+										Ref:     ref("sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference"),
 									},
 								},
 							},
@@ -8500,7 +8815,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_BackendTrafficPolicySpec(ref co
 			},
 		},
 		Dependencies: []string{
-			"sigs.k8s.io/gateway-api/apis/v1.SessionPersistence", "sigs.k8s.io/gateway-api/apis/v1alpha2.LocalPolicyTargetReference", "sigs.k8s.io/gateway-api/apisx/v1alpha1.RetryConstraint"},
+			"sigs.k8s.io/gateway-api/apis/v1.LocalPolicyTargetReference", "sigs.k8s.io/gateway-api/apis/v1.SessionPersistence", "sigs.k8s.io/gateway-api/apisx/v1alpha1.RetryConstraint"},
 	}
 }
 
@@ -9002,7 +9317,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_XBackendTrafficPolicy(ref commo
 						SchemaProps: spec.SchemaProps{
 							Description: "Status defines the current state of BackendTrafficPolicy.",
 							Default:     map[string]interface{}{},
-							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus"),
+							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.PolicyStatus"),
 						},
 					},
 				},
@@ -9010,7 +9325,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_XBackendTrafficPolicy(ref commo
 			},
 		},
 		Dependencies: []string{
-			"k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "sigs.k8s.io/gateway-api/apis/v1alpha2.PolicyStatus", "sigs.k8s.io/gateway-api/apisx/v1alpha1.BackendTrafficPolicySpec"},
+			"k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta", "sigs.k8s.io/gateway-api/apis/v1.PolicyStatus", "sigs.k8s.io/gateway-api/apisx/v1alpha1.BackendTrafficPolicySpec"},
 	}
 }
 
diff --git a/pkg/generator/main.go b/pkg/generator/main.go
index 1149e1a9..0916864b 100644
--- a/pkg/generator/main.go
+++ b/pkg/generator/main.go
@@ -33,11 +33,12 @@ import (
 )
 
 var standardKinds = map[string]bool{
-	"GatewayClass":   true,
-	"Gateway":        true,
-	"GRPCRoute":      true,
-	"HTTPRoute":      true,
-	"ReferenceGrant": true,
+	"GatewayClass":     true,
+	"Gateway":          true,
+	"GRPCRoute":        true,
+	"HTTPRoute":        true,
+	"ReferenceGrant":   true,
+	"BackendTLSPolicy": true,
 }
 
 // This generation code is largely copied from
diff --git a/site-src/guides/tls.md b/site-src/guides/tls.md
index be3281ee..4741171a 100644
--- a/site-src/guides/tls.md
+++ b/site-src/guides/tls.md
@@ -145,7 +145,7 @@ TLS-encrypted upstream connection where Pods backing the `dev` Service are expec
 certificate for `dev.example.com`.
 
 ```yaml
-{% include 'experimental/v1alpha3/backendtlspolicy-system-certs.yaml' %}
+{% include 'standard/v1/backendtlspolicy-system-certs.yaml' %}
 ```
 
 #### Using Explicit CA Certificates
@@ -155,7 +155,7 @@ map `auth-cert` to connect with a TLS-encrypted upstream connection where Pods b
 are expected to serve a valid certificate for `auth.example.com`.
 
 ```yaml
-{% include 'experimental/v1alpha3/backendtlspolicy-ca-certs.yaml' %}
+{% include 'standard/v1/backendtlspolicy-ca-certs.yaml' %}
 ```
 
 ## Extensions



Test patch:
diff --git a/conformance/tests/backendtlspolicy-conflict-resolution.go b/conformance/tests/backendtlspolicy-conflict-resolution.go
index 6aac39c9..906d60c6 100644
--- a/conformance/tests/backendtlspolicy-conflict-resolution.go
+++ b/conformance/tests/backendtlspolicy-conflict-resolution.go
@@ -23,7 +23,6 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
-	"sigs.k8s.io/gateway-api/apis/v1alpha2"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -53,14 +52,14 @@ var BackendTLSPolicyConflictResolution = suite.ConformanceTest{
 		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
 
 		acceptedCond := metav1.Condition{
-			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Type:   string(gatewayv1.PolicyConditionAccepted),
 			Status: metav1.ConditionTrue,
-			Reason: string(v1alpha2.PolicyReasonAccepted),
+			Reason: string(gatewayv1.PolicyReasonAccepted),
 		}
 		conflictedCond := metav1.Condition{
-			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Type:   string(gatewayv1.PolicyConditionAccepted),
 			Status: metav1.ConditionFalse,
-			Reason: string(v1alpha2.PolicyReasonConflicted),
+			Reason: string(gatewayv1.PolicyReasonConflicted),
 		}
 
 		t.Run("Conflicting BackendTLSPolicies targeting the same Service without a section name", func(t *testing.T) {
diff --git a/conformance/tests/backendtlspolicy-conflict-resolution.yaml b/conformance/tests/backendtlspolicy-conflict-resolution.yaml
index 5d5e6583..b5817f62 100644
--- a/conformance/tests/backendtlspolicy-conflict-resolution.yaml
+++ b/conformance/tests/backendtlspolicy-conflict-resolution.yaml
@@ -115,7 +115,7 @@ spec:
         name: "tls-checks-ca-certificate"
     hostname: "other.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: conflicted-without-section-name-2
@@ -134,7 +134,7 @@ spec:
         name: "tls-checks-ca-certificate"
     hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: conflicted-with-section-name-1
@@ -154,7 +154,7 @@ spec:
         name: "tls-checks-ca-certificate"
     hostname: "other.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: conflicted-with-section-name-2
@@ -174,7 +174,7 @@ spec:
         name: "tls-checks-ca-certificate"
     hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: not-conflicted-with-section-name
@@ -194,7 +194,7 @@ spec:
         name: "tls-checks-ca-certificate"
     hostname: "other.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: not-conflicted-without-section-name
diff --git a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go
index 824d8dd1..54908a23 100644
--- a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go
+++ b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.go
@@ -23,8 +23,6 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
-	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
-	gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -61,9 +59,9 @@ var BackendTLSPolicyInvalidCACertificateRef = suite.ConformanceTest{
 			t.Run("BackendTLSPolicy_"+policyNN.Name, func(t *testing.T) {
 				t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a Accepted Condition with status False and Reason NoValidCACertificate", func(t *testing.T) {
 					acceptedCond := metav1.Condition{
-						Type:   string(gatewayv1alpha2.PolicyConditionAccepted),
+						Type:   string(gatewayv1.PolicyConditionAccepted),
 						Status: metav1.ConditionFalse,
-						Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonNoValidCACertificate),
+						Reason: string(gatewayv1.BackendTLSPolicyReasonNoValidCACertificate),
 					}
 
 					kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, acceptedCond)
@@ -71,9 +69,9 @@ var BackendTLSPolicyInvalidCACertificateRef = suite.ConformanceTest{
 
 				t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a ResolvedRefs Condition with status False and Reason InvalidCACertificateRef", func(t *testing.T) {
 					resolvedRefsCond := metav1.Condition{
-						Type:   string(gatewayv1alpha3.BackendTLSPolicyConditionResolvedRefs),
+						Type:   string(gatewayv1.BackendTLSPolicyConditionResolvedRefs),
 						Status: metav1.ConditionFalse,
-						Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonInvalidCACertificateRef),
+						Reason: string(gatewayv1.BackendTLSPolicyReasonInvalidCACertificateRef),
 					}
 
 					kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, resolvedRefsCond)
diff --git a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml
index 138812fd..fbb08c30 100644
--- a/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml
+++ b/conformance/tests/backendtlspolicy-invalid-ca-certificate-ref.yaml
@@ -55,7 +55,7 @@ spec:
       port: 443
       targetPort: 8443
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: nonexistent-ca-certificate-ref
@@ -72,7 +72,7 @@ spec:
         name: "nonexistent-ca-certificate"
     hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: malformed-ca-certificate-ref
diff --git a/conformance/tests/backendtlspolicy-invalid-kind.go b/conformance/tests/backendtlspolicy-invalid-kind.go
index 5a3bba59..35f30fd2 100644
--- a/conformance/tests/backendtlspolicy-invalid-kind.go
+++ b/conformance/tests/backendtlspolicy-invalid-kind.go
@@ -23,8 +23,6 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
-	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
-	gatewayv1alpha3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -58,9 +56,9 @@ var BackendTLSPolicyInvalidKind = suite.ConformanceTest{
 
 		t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a Accepted Condition with status False and Reason NoValidCACertificate", func(t *testing.T) {
 			acceptedCond := metav1.Condition{
-				Type:   string(gatewayv1alpha2.PolicyConditionAccepted),
+				Type:   string(gatewayv1.PolicyConditionAccepted),
 				Status: metav1.ConditionFalse,
-				Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonNoValidCACertificate),
+				Reason: string(gatewayv1.BackendTLSPolicyReasonNoValidCACertificate),
 			}
 
 			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, acceptedCond)
@@ -68,9 +66,9 @@ var BackendTLSPolicyInvalidKind = suite.ConformanceTest{
 
 		t.Run("BackendTLSPolicy with a single invalid CACertificateRef has a ResolvedRefs Condition with status False and Reason InvalidKind", func(t *testing.T) {
 			resolvedRefsCond := metav1.Condition{
-				Type:   string(gatewayv1alpha3.BackendTLSPolicyConditionResolvedRefs),
+				Type:   string(gatewayv1.BackendTLSPolicyConditionResolvedRefs),
 				Status: metav1.ConditionFalse,
-				Reason: string(gatewayv1alpha3.BackendTLSPolicyReasonInvalidKind),
+				Reason: string(gatewayv1.BackendTLSPolicyReasonInvalidKind),
 			}
 
 			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, resolvedRefsCond)
diff --git a/conformance/tests/backendtlspolicy-invalid-kind.yaml b/conformance/tests/backendtlspolicy-invalid-kind.yaml
index a7eaeb5d..858856c6 100644
--- a/conformance/tests/backendtlspolicy-invalid-kind.yaml
+++ b/conformance/tests/backendtlspolicy-invalid-kind.yaml
@@ -33,7 +33,7 @@ spec:
       port: 443
       targetPort: 8443
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: invalid-kind
diff --git a/conformance/tests/backendtlspolicy-observed-generation-bump.go b/conformance/tests/backendtlspolicy-observed-generation-bump.go
index a3cd4000..83c12378 100644
--- a/conformance/tests/backendtlspolicy-observed-generation-bump.go
+++ b/conformance/tests/backendtlspolicy-observed-generation-bump.go
@@ -21,12 +21,13 @@ import (
 	"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"
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
 	"sigs.k8s.io/gateway-api/pkg/features"
@@ -57,7 +58,7 @@ var BackendTLSPolicyObservedGenerationBump = suite.ConformanceTest{
 			namespaces := []string{"gateway-conformance-infra"}
 			kubernetes.NamespacesMustBeReady(t, suite.Client, suite.TimeoutConfig, namespaces)
 
-			original := &v1alpha3.BackendTLSPolicy{}
+			original := &gatewayv1.BackendTLSPolicy{}
 			err := suite.Client.Get(ctx, policyNN, original)
 			require.NoError(t, err, "error getting HTTPRoute")
 
@@ -70,12 +71,12 @@ var BackendTLSPolicyObservedGenerationBump = suite.ConformanceTest{
 			require.NoError(t, err, "error patching the BackendTLSPolicy")
 
 			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, policyNN, gwNN, metav1.Condition{
-				Type:   string(v1alpha2.PolicyConditionAccepted),
+				Type:   string(gatewayv1.PolicyConditionAccepted),
 				Status: metav1.ConditionTrue,
 				Reason: "", // any reason
 			})
 
-			updated := &v1alpha3.BackendTLSPolicy{}
+			updated := &gatewayv1.BackendTLSPolicy{}
 			err = suite.Client.Get(ctx, policyNN, updated)
 			require.NoError(t, err, "error getting BackendTLSPolicy")
 
diff --git a/conformance/tests/backendtlspolicy-observed-generation-bump.yaml b/conformance/tests/backendtlspolicy-observed-generation-bump.yaml
index c21bd45b..e7d4d40c 100644
--- a/conformance/tests/backendtlspolicy-observed-generation-bump.yaml
+++ b/conformance/tests/backendtlspolicy-observed-generation-bump.yaml
@@ -25,7 +25,7 @@ spec:
       port: 443
       targetPort: 8443
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: observed-generation-bump
diff --git a/conformance/tests/backendtlspolicy-san.go b/conformance/tests/backendtlspolicy-san.go
index bbcb334d..2bc91acc 100644
--- a/conformance/tests/backendtlspolicy-san.go
+++ b/conformance/tests/backendtlspolicy-san.go
@@ -23,7 +23,6 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
-	"sigs.k8s.io/gateway-api/apis/v1alpha2"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -54,9 +53,9 @@ var BackendTLSPolicySANValidation = suite.ConformanceTest{
 		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
 
 		policyCond := metav1.Condition{
-			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Type:   string(gatewayv1.PolicyConditionAccepted),
 			Status: metav1.ConditionTrue,
-			Reason: string(v1alpha2.PolicyReasonAccepted),
+			Reason: string(gatewayv1.PolicyReasonAccepted),
 		}
 
 		serverStr := "abc.example.com"
diff --git a/conformance/tests/backendtlspolicy-san.yaml b/conformance/tests/backendtlspolicy-san.yaml
index 7bf7a26d..6bab519d 100644
--- a/conformance/tests/backendtlspolicy-san.yaml
+++ b/conformance/tests/backendtlspolicy-san.yaml
@@ -154,7 +154,7 @@ spec:
     port: 443
     targetPort: 8443
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: san-dns
@@ -177,7 +177,7 @@ spec:
     - type: "Hostname"
       hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: san-dns-mismatch
@@ -200,7 +200,7 @@ spec:
     - type: "Hostname"
       hostname: "dce.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: san-uri
@@ -223,7 +223,7 @@ spec:
     - type: "URI"
       uri: "spiffe://abc.example.com/test-identity"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: san-uri-mismatch
@@ -246,7 +246,7 @@ spec:
     - type: "URI"
       uri: "spiffe://def.example.com/test-identity"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: multiple-sans
@@ -271,7 +271,7 @@ spec:
     - type: "Hostname"
       hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: multiple-mismatch-sans
diff --git a/conformance/tests/backendtlspolicy.go b/conformance/tests/backendtlspolicy.go
index 203f3f89..f4552d69 100644
--- a/conformance/tests/backendtlspolicy.go
+++ b/conformance/tests/backendtlspolicy.go
@@ -23,8 +23,6 @@ import (
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
-	"sigs.k8s.io/gateway-api/apis/v1alpha2"
-	"sigs.k8s.io/gateway-api/apis/v1alpha3"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -49,14 +47,14 @@ var BackendTLSPolicy = suite.ConformanceTest{
 		ns := "gateway-conformance-infra"
 
 		acceptedCond := metav1.Condition{
-			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Type:   string(gatewayv1.PolicyConditionAccepted),
 			Status: metav1.ConditionTrue,
-			Reason: string(v1alpha2.PolicyReasonAccepted),
+			Reason: string(gatewayv1.PolicyReasonAccepted),
 		}
 		resolvedRefsCond := metav1.Condition{
-			Type:   string(v1alpha3.BackendTLSPolicyConditionResolvedRefs),
+			Type:   string(gatewayv1.BackendTLSPolicyConditionResolvedRefs),
 			Status: metav1.ConditionTrue,
-			Reason: string(v1alpha3.BackendTLSPolicyReasonResolvedRefs),
+			Reason: string(gatewayv1.BackendTLSPolicyReasonResolvedRefs),
 		}
 
 		t.Run("Re-encrypt HTTPS request sent to Service with valid BackendTLSPolicy should succeed", func(t *testing.T) {
@@ -138,7 +136,7 @@ var BackendTLSPolicy = suite.ConformanceTest{
 				})
 		})
 
-		// Verify that request sent to Service targeted by BackendTLSPolicy with mismatched cert should failed.
+		// Verify that request sent to Service targeted by BackendTLSPolicy with mismatched cert should fail.
 		t.Run("HTTP request send to Service targeted by BackendTLSPolicy with mismatched cert should return HTTP error", func(t *testing.T) {
 			invalidCertPolicyNN := types.NamespacedName{Name: "cert-mismatch", Namespace: ns}
 			kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidCertPolicyNN, gwNN, acceptedCond)
diff --git a/conformance/tests/backendtlspolicy.yaml b/conformance/tests/backendtlspolicy.yaml
index db9a017c..80f634df 100644
--- a/conformance/tests/backendtlspolicy.yaml
+++ b/conformance/tests/backendtlspolicy.yaml
@@ -104,7 +104,7 @@ spec:
     port: 443
     targetPort: 8443
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: normative-test
@@ -124,7 +124,7 @@ spec:
       name: "tls-checks-ca-certificate"
     hostname: "abc.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: host-mismatch
@@ -144,7 +144,7 @@ spec:
       name: "tls-checks-ca-certificate"
     hostname: "mismatch.example.com"
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
+apiVersion: gateway.networking.k8s.io/v1
 kind: BackendTLSPolicy
 metadata:
   name: cert-mismatch
diff --git a/conformance/tests/gateway-static-addresses.go b/conformance/tests/gateway-static-addresses.go
index fcee1b3f..89654c9e 100644
--- a/conformance/tests/gateway-static-addresses.go
+++ b/conformance/tests/gateway-static-addresses.go
@@ -135,8 +135,8 @@ var GatewayStaticAddresses = suite.ConformanceTest{
 		kubernetes.GatewayStatusMustHaveListeners(t, s.Client, s.TimeoutConfig, gwNN, finalExpectedListenerState)
 		require.Len(t, currentGW.Spec.Addresses, 1, "expected only 1 address left specified on Gateway")
 		statusAddresses := extractStatusAddresses(currentGW.Status.Addresses)
-		require.NotContains(t, statusAddresses, unusableAddress.Value, "should contain the unusable address")
-		require.NotContains(t, statusAddresses, invalidAddress.Value, "should contain the invalid address")
+		require.NotContains(t, statusAddresses, unusableAddress.Value, "should not contain the unusable address")
+		require.NotContains(t, statusAddresses, invalidAddress.Value, "should not contain the invalid address")
 		require.Contains(t, statusAddresses, usableAddress.Value, "should contain the usable address")
 		for _, addr := range currentGW.Status.Addresses {
 			if usableAddress.Value != addr.Value {
diff --git a/conformance/tests/cors-allow-credentials-behavior.go b/conformance/tests/httproute-cors-allow-credentials-behavior.go
similarity index 76%
rename from conformance/tests/cors-allow-credentials-behavior.go
rename to conformance/tests/httproute-cors-allow-credentials-behavior.go
index 391b3cee..c550dc0b 100644
--- a/conformance/tests/cors-allow-credentials-behavior.go
+++ b/conformance/tests/httproute-cors-allow-credentials-behavior.go
@@ -28,13 +28,13 @@ import (
 )
 
 func init() {
-	ConformanceTests = append(ConformanceTests, CORSAllowCredentialsBehavior)
+	ConformanceTests = append(ConformanceTests, HTTPRouteCORSAllowCredentialsBehavior)
 }
 
-var CORSAllowCredentialsBehavior = suite.ConformanceTest{
-	ShortName:   "CORSAllowCredentialsBehavior",
-	Description: "Validate ACA-Credentials responses",
-	Manifests:   []string{"tests/cors-allow-credentials-behavior.yaml"},
+var HTTPRouteCORSAllowCredentialsBehavior = suite.ConformanceTest{
+	ShortName:   "HTTPRouteCORSAllowCredentialsBehavior",
+	Description: "An HTTPRoute with CORS includes Access-Control-Allow-Credentials only when configured as 'true', and then only alongside a matching Access-Control-Allow-Origin.",
+	Manifests:   []string{"tests/httproute-cors-allow-credentials-behavior.yaml"},
 	Features: []features.FeatureName{
 		features.SupportGateway,
 		features.SupportHTTPRoute,
@@ -66,6 +66,22 @@ var CORSAllowCredentialsBehavior = suite.ConformanceTest{
 				},
 				Namespace: ns,
 			},
+			{
+				Request: http.Request{
+					Method: "GET",
+					Path:   "/cors-behavior-creds-true",
+					Headers: map[string]string{
+						"Origin":        "http://not-app.example",
+						"Cookie":        "sid=abc123",
+						"Authorization": "Bearer test",
+					},
+				},
+				Response: http.Response{
+					StatusCode:    200,
+					AbsentHeaders: []string{"Access-Control-Allow-Credentials"},
+				},
+				Namespace: ns,
+			},
 			{
 				Request: http.Request{
 					Method: "GET",
diff --git a/conformance/tests/cors-allow-credentials-behavior.yaml b/conformance/tests/httproute-cors-allow-credentials-behavior.yaml
similarity index 86%
rename from conformance/tests/cors-allow-credentials-behavior.yaml
rename to conformance/tests/httproute-cors-allow-credentials-behavior.yaml
index 13992e28..e4b5a390 100644
--- a/conformance/tests/cors-allow-credentials-behavior.yaml
+++ b/conformance/tests/httproute-cors-allow-credentials-behavior.yaml
@@ -16,6 +16,8 @@ spec:
       port: 8080
     filters:
     - cors:
+        allowOrigins:
+        - https://app.example
         allowCredentials: false
       type: CORS
   - matches:
@@ -27,6 +29,8 @@ spec:
       port: 8080
     filters:
     - cors:
+        allowOrigins:
+        - https://app.example
         allowCredentials: true
       type: CORS
 
diff --git a/pkg/test/cel/backendtlspolicy_test.go b/pkg/test/cel/backendtlspolicy_test.go
index d035ef6f..2be7fa5b 100644
--- a/pkg/test/cel/backendtlspolicy_test.go
+++ b/pkg/test/cel/backendtlspolicy_test.go
@@ -1,6 +1,3 @@
-//go:build experimental
-// +build experimental
-
 /*
 Copyright 2023 The Kubernetes Authors.
 
@@ -26,31 +23,31 @@ import (
 	"time"
 
 	corev1 "k8s.io/api/core/v1"
+
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	gatewayv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
-	gatewayv1a3 "sigs.k8s.io/gateway-api/apis/v1alpha3"
-	v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
+
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 )
 
 func TestBackendTLSPolicyTargetRefs(t *testing.T) {
 	tests := []struct {
 		name       string
 		wantErrors []string
-		targetRefs []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName
+		targetRefs []gatewayv1.LocalPolicyTargetReferenceWithSectionName
 	}{
 		{
 			name:       "invalid because duplicate target refs without section name",
 			wantErrors: []string{"sectionName must be unique when targetRefs includes 2 or more references to the same target"},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
 			}},
@@ -58,60 +55,60 @@ func TestBackendTLSPolicyTargetRefs(t *testing.T) {
 		{
 			name:       "invalid because duplicate target refs with only one section name",
 			wantErrors: []string{"sectionName must be specified when targetRefs includes 2 or more references to the same target"},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example2",
 				},
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 		{
 			name:       "invalid because duplicate target refs with duplicate section names",
 			wantErrors: []string{"sectionName must be unique when targetRefs includes 2 or more references to the same target"},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("bar")),
+				SectionName: ptrTo(gatewayv1.SectionName("bar")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 		{
 			name:       "valid single targetRef without sectionName",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
 			}},
@@ -119,117 +116,117 @@ func TestBackendTLSPolicyTargetRefs(t *testing.T) {
 		{
 			name:       "valid single targetRef with sectionName",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 		{
 			name:       "valid because duplicate target refs with different section names",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("bar")),
+				SectionName: ptrTo(gatewayv1.SectionName("bar")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("jin")),
+				SectionName: ptrTo(gatewayv1.SectionName("jin")),
 			}},
 		},
 		{
 			name:       "valid because duplicate target refs with different names",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example2",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example3",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 		{
 			name:       "valid because duplicate target refs with different kinds",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("NotService"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("NotService"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 		{
 			name:       "valid because duplicate target refs with different groups",
 			wantErrors: []string{},
-			targetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{{
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group(corev1.GroupName),
-					Kind:  gatewayv1a2.Kind("Service"),
+			targetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{{
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group(corev1.GroupName),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}, {
-				LocalPolicyTargetReference: gatewayv1a2.LocalPolicyTargetReference{
-					Group: gatewayv1a2.Group("svc.other.io"),
-					Kind:  gatewayv1a2.Kind("Service"),
+				LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
+					Group: gatewayv1.Group("svc.other.io"),
+					Kind:  gatewayv1.Kind("Service"),
 					Name:  "example",
 				},
-				SectionName: ptrTo(gatewayv1a2.SectionName("foo")),
+				SectionName: ptrTo(gatewayv1.SectionName("foo")),
 			}},
 		},
 	}
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			policy := &gatewayv1a3.BackendTLSPolicy{
+			policy := &gatewayv1.BackendTLSPolicy{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      fmt.Sprintf("foo-%v", time.Now().UnixNano()),
 					Namespace: metav1.NamespaceDefault,
 				},
-				Spec: gatewayv1a3.BackendTLSPolicySpec{
+				Spec: gatewayv1.BackendTLSPolicySpec{
 					TargetRefs: tc.targetRefs,
-					Validation: gatewayv1a3.BackendTLSPolicyValidation{
-						WellKnownCACertificates: ptrTo(gatewayv1a3.WellKnownCACertificatesType("System")),
+					Validation: gatewayv1.BackendTLSPolicyValidation{
+						WellKnownCACertificates: ptrTo(gatewayv1.WellKnownCACertificatesType("System")),
 						Hostname:                "foo.example.com",
 					},
 				},
@@ -243,20 +240,20 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 	tests := []struct {
 		name             string
 		wantErrors       []string
-		policyValidation gatewayv1a3.BackendTLSPolicyValidation
+		policyValidation gatewayv1.BackendTLSPolicyValidation
 	}{
 		{
 			name: "valid BackendTLSPolicyValidation with WellKnownCACertificates",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				WellKnownCACertificates: ptrTo(gatewayv1a3.WellKnownCACertificatesType("System")),
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				WellKnownCACertificates: ptrTo(gatewayv1.WellKnownCACertificatesType("System")),
 				Hostname:                "foo.example.com",
 			},
 			wantErrors: []string{},
 		},
 		{
 			name: "valid BackendTLSPolicyValidation with CACertificateRefs",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -269,20 +266,20 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name:             "invalid BackendTLSPolicyValidation with missing fields",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{},
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{},
 			wantErrors:       []string{"spec.validation.hostname in body should be at least 1 chars long", "must specify either CACertificateRefs or WellKnownCACertificates"},
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with both CACertificateRefs and WellKnownCACertificates",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
 						Name:  "name",
 					},
 				},
-				WellKnownCACertificates: ptrTo(gatewayv1a3.WellKnownCACertificatesType("System")),
+				WellKnownCACertificates: ptrTo(gatewayv1.WellKnownCACertificatesType("System")),
 				Hostname:                "foo.example.com",
 			},
 
@@ -290,16 +287,16 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with Unsupported value for WellKnownCACertificates",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				WellKnownCACertificates: ptrTo(gatewayv1a3.WellKnownCACertificatesType("bar")),
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				WellKnownCACertificates: ptrTo(gatewayv1.WellKnownCACertificatesType("bar")),
 				Hostname:                "foo.example.com",
 			},
 			wantErrors: []string{"supported values: \"System\""},
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with empty Hostname field",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -312,8 +309,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "valid BackendTLSPolicyValidation with SubjectAltName type Hostname",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -321,7 +318,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type:     "Hostname",
 						Hostname: "foo.example.com",
@@ -332,8 +329,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "valid BackendTLSPolicyValidation with SubjectAltName type URI",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -341,7 +338,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type: "URI",
 						URI:  "spiffe://mycluster.example",
@@ -352,8 +349,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with SubjectAltName type Hostname and empty Hostname field",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -361,7 +358,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type:     "Hostname",
 						Hostname: "",
@@ -372,8 +369,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with SubjectAltName type URI and non-empty Hostname field",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -381,7 +378,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type:     "URI",
 						Hostname: "foo.example.com",
@@ -392,8 +389,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with SubjectAltName type URI and empty URI field",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -401,7 +398,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type: "URI",
 						URI:  "",
@@ -412,8 +409,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with SubjectAltName type Hostname and non-empty URI field",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -421,7 +418,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type: "Hostname",
 						URI:  "test",
@@ -432,8 +429,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation with SubjectAltName type Hostname and both Hostname and URI specified",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -441,7 +438,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type:     "Hostname",
 						Hostname: "foo.example.com",
@@ -453,8 +450,8 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 		},
 		{
 			name: "invalid BackendTLSPolicyValidation incorrect URI SAN",
-			policyValidation: gatewayv1a3.BackendTLSPolicyValidation{
-				CACertificateRefs: []v1beta1.LocalObjectReference{
+			policyValidation: gatewayv1.BackendTLSPolicyValidation{
+				CACertificateRefs: []gatewayv1.LocalObjectReference{
 					{
 						Group: "group",
 						Kind:  "kind",
@@ -462,7 +459,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 					},
 				},
 				Hostname: "foo.example.com",
-				SubjectAltNames: []gatewayv1a3.SubjectAltName{
+				SubjectAltNames: []gatewayv1.SubjectAltName{
 					{
 						Type: "URI",
 						URI:  "foo.example.com",
@@ -475,21 +472,21 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			policy := &gatewayv1a3.BackendTLSPolicy{
+			policy := &gatewayv1.BackendTLSPolicy{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      fmt.Sprintf("foo-%v", time.Now().UnixNano()),
 					Namespace: metav1.NamespaceDefault,
 				},
-				Spec: gatewayv1a3.BackendTLSPolicySpec{
-					TargetRefs: []gatewayv1a2.LocalPolicyTargetReferenceWithSectionName{
+				Spec: gatewayv1.BackendTLSPolicySpec{
+					TargetRefs: []gatewayv1.LocalPolicyTargetReferenceWithSectionName{
 						{
-							gatewayv1a2.LocalPolicyTargetReference{
+							LocalPolicyTargetReference: gatewayv1.LocalPolicyTargetReference{
 								Group: "group",
 								Kind:  "kind",
 								Name:  "name",
 							},
 							// SectionName cannot contain capital letters.
-							ptrTo(gatewayv1a2.SectionName("section")),
+							SectionName: ptrTo(gatewayv1.SectionName("section")),
 						},
 					},
 					Validation: tc.policyValidation,
@@ -500,7 +497,7 @@ func TestBackendTLSPolicyValidation(t *testing.T) {
 	}
 }
 
-func validateBackendTLSPolicy(t *testing.T, policy *gatewayv1a3.BackendTLSPolicy, wantErrors []string) {
+func validateBackendTLSPolicy(t *testing.T, policy *gatewayv1.BackendTLSPolicy, wantErrors []string) {
 	t.Helper()
 
 	ctx := context.Background()
diff --git a/pkg/test/cel/gateway_test.go b/pkg/test/cel/gateway_test.go
index ba85b50f..0bff6093 100644
--- a/pkg/test/cel/gateway_test.go
+++ b/pkg/test/cel/gateway_test.go
@@ -584,6 +584,54 @@ func TestValidateGateway(t *testing.T) {
 			},
 			wantErrors: []string{"IPAddress values must be unique", "Hostname values must be unique"},
 		},
+		{
+			desc: "optional ip address or hostname values",
+			mutate: func(gw *gatewayv1.Gateway) {
+				gw.Spec.Addresses = []gatewayv1.GatewaySpecAddress{
+					{
+						Type: ptrTo(gatewayv1.IPAddressType),
+					},
+					{
+						Type: ptrTo(gatewayv1.HostnameAddressType),
+					},
+				}
+			},
+		},
+		{
+			desc: "multiple optional ip address or hostname values alongside defined values",
+			mutate: func(gw *gatewayv1.Gateway) {
+				gw.Spec.Addresses = []gatewayv1.GatewaySpecAddress{
+					{
+						Type: ptrTo(gatewayv1.HostnameAddressType),
+					},
+					{
+						Type: ptrTo(gatewayv1.IPAddressType),
+					},
+					{
+						Type:  ptrTo(gatewayv1.IPAddressType),
+						Value: "1.2.3.4",
+					},
+					{
+						Type:  ptrTo(gatewayv1.HostnameAddressType),
+						Value: "foo.bar",
+					},
+					{
+						Type: ptrTo(gatewayv1.IPAddressType),
+					},
+					{
+						Type: ptrTo(gatewayv1.HostnameAddressType),
+					},
+					{
+						Type:  ptrTo(gatewayv1.IPAddressType),
+						Value: "2.3.4.5",
+					},
+					{
+						Type:  ptrTo(gatewayv1.HostnameAddressType),
+						Value: "bar.bar",
+					},
+				}
+			},
+		},
 	}
 
 	for _, tc := range testCases {