sigs.k8s.io/gateway-api@v1.0.0/geps/gep-1897.md (about)

     1  # GEP-1897: BackendTLSPolicy - Explicit Backend TLS Connection Configuration
     2  
     3  * Issue: [#1897](https://github.com/kubernetes-sigs/gateway-api/issues/1897)
     4  * Status: Experimental
     5  
     6  ## TLDR
     7  
     8  This document specifically addresses the topic of conveying HTTPS from the Gateway
     9  dataplane to the backend (backend TLS termination), and intends to satisfy the single
    10  use case “As a client implementation of Gateway API, I need to know how to connect to
    11  a backend pod that has its own certificate”. TLS configuration can be a nebulous topic,
    12  so in order to drive resolution this GEP focuses only on this single piece of functionality.
    13  
    14  Furthermore, for Gateway API to handle the case where the service or backend owner is doing their own TLS, _and_
    15  the service or backend owner wants to validate the clients connecting to it, two things need to happen:
    16  
    17  - The service or backend owner has to provide a method for the Gateway owner to retrieve a certificate.
    18  - Gateway API has to provide a way for the Gateway to configure and apply the validation options.
    19  
    20  ## Immediate Goals
    21  
    22  1. The solution must satisfy the following use case: the backend pod has its own
    23  certificate and the gateway implementation client needs to know how to connect to the
    24  backend pod. (Use case #4 in [Gateway API TLS Use Cases](#references))
    25  2. In terms of the Gateway API personas, only the application developer persona applies in this
    26  solution. The application developer should control the gateway to backend TLS settings,
    27  not the cluster operator, as requiring a cluster operator to manage certificate renewals
    28  and revocations would be extremely cumbersome.
    29  3. The solution should consider client certificate settings used in the TLS handshake **from
    30  Gateway to backend**, such as server name indication, trusted certificates,
    31  and CA certificates.
    32  
    33  ## Longer Term Goals
    34  
    35  These are worthy goals, but deserve a different GEP for proper attention.  This GEP is concerned entirely with the
    36  controlplane, i.e. the hop between gateway and backend.
    37  
    38  1. [TCPRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute) and
    39  [GRPCRoute](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute) use cases
    40  are not addressed here, because at this point in time these two route types are not graduated to beta.
    41  2. Mutual TLS (mTLS) use cases are intentionally out of scope for this GEP for two reasons.  First, the design of Gateway
    42  API is backend-attached and does not currently support mutual authentication, and also because this GEP does not
    43  address the case where connections to TLS are **implicitly configured** on behalf of the user, which is the norm for mTLS.
    44  This GEP is about the case where an application developer needs to **explicitly express** that they expect TLS when
    45  there is no automatic, implicit configuration available.
    46  3. Service mesh use cases are not addressed here because this GEP is specifically concerned with the connection between
    47  Gateways and Backends, not Service to Service.  Service mesh use cases should ignore the design components described in
    48  this proposal.
    49  
    50  ## Non-Goals
    51  
    52  These are worthy goals, but will not be covered by this GEP.
    53  
    54  1. Changes to the existing mechanisms for edge or passthrough TLS termination
    55  2. Providing a mechanism to decorate multiple route instances
    56  3. TLSRoute use cases
    57  4. UDPRoute use cases
    58  5. Controlling TLS versions or cipher suites used in TLS handshakes. (Use case #5 in [Gateway API TLS Use Cases](#references))
    59  6. Controlling certificates used by more than one workload (#6 in [Gateway API TLS Use Cases](#references))
    60  7. Client certificate settings used in TLS **from external clients to the
    61  Listener** (#7 in [Gateway API TLS Use Cases](#references))
    62  8. Providing a mechanism for the cluster operator to override gateway to backend TLS settings.
    63  
    64  ## Already Solved TLS Use Cases
    65  
    66  These are worthy goals that are already solved and thus will not be modified by the implementation.
    67  
    68  1. Termination of TLS for HTTP routing (#1 in [Gateway API TLS Use Cases](#references))
    69  2. HTTPS passthrough use cases (#2 in [Gateway API TLS Use Cases](#references))
    70  3. Termination of TLS for non-HTTP TCP streams (#3 in [Gateway API TLS Use Cases](#references))
    71  
    72  ## Overview - what do we want to do?
    73  
    74  Given that the current ingress solution specifies **edge** TLS termination (from the client to
    75  the gateway), and how to handle **passthrough** TLS (from the client to the backend pod), this
    76  proposed ingress solution specifies TLS origination to the **backend** (from the gateway to the
    77  backend pod).  As mentioned, this solution satisfies the use case in which the backend pod
    78  has its own certificate and the gateway client needs to know how to connect to the backend pod.
    79  
    80  ![image depicting TLS termination types](images/1897-TLStermtypes.png "TLS termination types")
    81  
    82  Gateway API is missing a mechanism for separately providing the details for the backend TLS handshake,
    83  including (but not limited to):
    84  
    85  * intent to use TLS on the backend hop
    86  * client certificate of the gateway
    87  * system certificates to use in the absence of client certificates
    88  
    89  ## Purpose - why do we want to do this?
    90  
    91  This proposal is _very_ tightly scoped because we have tried and failed to address this well-known
    92  gap in the API specification. The lack of support for this fundamental concept is holding back
    93  Gateway API adoption by users that require a solution to the use case. One of the recurring themes
    94  that has held up the prior art has been interest related to service mesh, and as such this proposal
    95  focuses explicitly on the ingress use case in the initial round.  Another reason for the tight scope
    96  is that we have been too focused on a generic representation of everything that TLS can do, which
    97  covers too much ground to address in a single GEP.
    98  
    99  ## The history of backend TLS
   100  
   101  Work on this topic has spanned over three years, as documented in our repositories and other references,
   102  and summarized below.
   103  
   104  In January 2020, in issue [TLS Termination Policy #52](https://github.com/kubernetes-sigs/gateway-api/issues/52),
   105  this use case was discussed.  The discussion ended after being diverted by
   106  [KEP: Adding AppProtocol to Services and Endpoints #1422](https://github.com/kubernetes/enhancements/pull/1422),
   107  which was implemented and later reverted.
   108  
   109  In February 2020, [HTTPRoute: Add Reencrypt #81](https://github.com/kubernetes-sigs/gateway-api/pull/81)
   110  added the dataplane feature as “reencrypt”, but it went stale and was closed in favor of the work done in the
   111  next paragraph, which unfortunately didn’t implement the backend TLS termination feature.
   112  
   113  In August 2020, it resurfaced with a [comment](https://github.com/kubernetes-sigs/gateway-api/pull/256/files#r472734392)
   114  on this pull request: [tls: introduce mode and sni to cert matching behavior](https://github.com/kubernetes-sigs/gateway-api/pull/256/files#top).
   115  The backend TLS termination feature was deferred at that time.  Other TLS discussion was documented in
   116  [[SIG-NETWORK] TLS config in service-apis](https://docs.google.com/document/d/15fkzMrhN_7tA-i2mHKwZpqcjN1o2Pe9Am9Qt828x1lo/edit#heading=h.wym7wehwll44)
   117  , a list of TLS features that had been collected in June 2020, itself based on spreadsheet
   118  [Service API: TLS related issues](https://docs.google.com/spreadsheets/d/18KE61Y6InCmoQHZcbrYYRZS5Cnt7n33s5dTxUlhHgIA/edit#gid=0).
   119  
   120  In December 2021, this was discussed as a beta blocker in issue
   121  [Docs mentions Reencrypt for HTTPRoute and TLSRoute is available #968](https://github.com/kubernetes-sigs/gateway-api/issues/968).
   122  
   123  A March 2022 issue documents another request for it: [Provide a way to configure TLS from a Gateway to Backends #1067](https://github.com/kubernetes-sigs/gateway-api/issues/1067)
   124  
   125  A June 2022 issue documents a documentation issue related to it:
   126  [Unclear how to specify upstream (webserver) HTTP protocol #1244](https://github.com/kubernetes-sigs/gateway-api/discussions/1244)
   127  
   128  A July 2022 discussion [Specify Re-encrypt TLS Termination (i.e., Upstream TLS) #1285](https://github.com/kubernetes-sigs/gateway-api/discussions/1285)
   129  collected most of the historical context preceding the backend TLS termination feature, with the intention of
   130  collecting evidence that this feature is still unresolved.  This was followed by
   131  [GEP: Describe Backend Properties #1282](https://github.com/kubernetes-sigs/gateway-api/issues/1282).
   132  
   133  In August 2022, [Add Provisional GEP-1282 document #1333](https://github.com/kubernetes-sigs/gateway-api/pull/1333)
   134  was created, and in October 2022, a GEP update with proposed implementation
   135  [GEP-1282 Backend Properties - Update implementation #1430](https://github.com/kubernetes-sigs/gateway-api/pull/1430)
   136  was followed by intense discussion and closed in favor of a downsize in scope.
   137  
   138  In January 2023 we closed GEP-1282 and began a new discussion on enumerating TLS use cases in
   139  [Gateway API TLS Use Cases](#references), for the purposes of a clear definition and separation of concerns.
   140  This GEP is the outcome of the TLS use case #4 in
   141  [Gateway API TLS Use Cases](#references) as mentioned in the Immediate Goals section above.
   142  
   143  ## API
   144  
   145  To allow the gateway client to know how to connect to the backend pod, when the backend pod has its own
   146  certificate, we implement a metaresource named `BackendTLSPolicy`, that was previously introduced with the name
   147  `TLSConnectionPolicy` as a hypothetical Direct Policy Attachment example in
   148  [GEP-713: Metaresources and PolicyAttachment](https://gateway-api.sigs.k8s.io/geps/gep-713/).
   149  Because naming is hard, a new name may be
   150  substituted without blocking acceptance of the content of the API change.
   151  
   152  The selection of the applicable Gateway API persona is important in the design of BackendTLSPolicy, because it provides
   153  a way to explicitly describe the _expectations_ of the connection to the application.  BackendTLSPolicy is configured
   154  by the application developer Gateway API persona to signal what the application developer _expects_ in connections to
   155  the application, from a TLS perspective.  Only the application developer can know what the application expects, so it is
   156  important that this configuration be managed by that persona.
   157  
   158  During the course of discussion of this proposal, we did consider allowing the cluster operator persona to have some access
   159  to Gateway cert validation, but as mentioned, BackendTLSPolicy is used primarily to signal what the application
   160  developer expects in the connection.  Granting this expectation to any other role would blur the lines between role
   161  responsibilities, which compromises the role-oriented design principle of Gateway API. As mentioned in Non-goal #8,
   162  providing a mechanism for the cluster operator gateway role to override gateway to backend TLS settings is not covered
   163  by this proposal, but should be addressed in a future update.  One idea is to use two types: ApplicationBackendTLSPolicy,
   164  and GatewayBackendTLSPolicy, where the application developer is responsible for the former, the cluster operator is
   165  responsible for the latter, and the cluster operator may configure whether certain settings may be overridden by
   166  application developers.
   167  
   168  The BackendTLSPolicy must contain these configuration items to allow the Gateway to operate successfully
   169  as a TLS Client:
   170  
   171  - An explicit signal that TLS should be used by this connection.
   172  - A hostname the Gateway should use to connect to the backend.
   173  - A reference to one or more certificates to use in the TLS handshake, signed by a CA or self-signed.
   174  - An indication that system certificates may be used.
   175  
   176  BackendTLSPolicy is defined as a Direct Policy Attachment without defaults or overrides, applied to a Service that
   177  accesses the backend in question, where the BackendTLSPolicy resides in the same namespace as the Service it is
   178  applied to.  The BackendTLSPolicy and the Service must reside in the same namespace in order to prevent the
   179  complications involved with sharing trust across namespace boundaries.  We chose the Service resource as a target,
   180  rather than the Route resource, so that we can reuse the same BackendTLSPolicy for all the different Routes that
   181  might point to this Service.
   182  For the use case where certificates are stored in their own namespace, users may create Secrets and use ReferenceGrants
   183  for a BackendTLSPolicy-to-Secret binding.  Implementations must respect a ReferenceGrant for cross-namespace Secret
   184  sharing to BackendTLSPolicy, even if they don't for other cross-namespace sharing.
   185  
   186  One of the areas of concern for this API is that we need to indicate how and when the API implementations should use the
   187  backend destination certificate authority.  This solution proposes, as introduced in
   188  [GEP-713](https://gateway-api.sigs.k8s.io/geps/gep-713/), that the implementation
   189  should watch the connections to a specified TargetRef (Service), and if the Service matches a BackendTLSPolicy, then
   190  assume the connection is TLS, and verify that the TargetRef’s certificate can be validated by the client (Gateway) using
   191  the provided certificates and hostname before the connection is made. On the question of how to signal
   192  that there was a failure in the certificate validation, this is left up to the implementation to return a response error
   193  that is appropriate, such as one of the HTTP error codes: 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), or
   194  other signal that makes the failure sufficiently clear to the requester without revealing too much about the transaction,
   195  based on established security requirements.
   196  
   197  All policy resources must include `TargetRef` with the fields specified
   198  [here](https://github.com/kubernetes-sigs/gateway-api/blob/a33a934af9ec6997b34fd9b00d2ecd13d143e48b/apis/v1alpha2/policy_types.go#L24-L41).
   199  In an upcoming [extension](https://github.com/kubernetes-sigs/gateway-api/issues/2147) to TargetRef, policy resources
   200  _may_ also choose to include `SectionName` and/or `Port` in the TargetRef following the same mechanics as `ParentRef`.
   201  
   202  BackendTLSPolicySpec contains the `TargetRef` and `TLS` fields.  The `TLS` field is a `BackendTLSPolicyConfig` and
   203  contains `CertRefs`, `StandardCerts`, and `Hostname`.
   204  The names of the fields were chosen to facilitate discussion, but may be substituted without blocking acceptance of the
   205  content of the API change.
   206  
   207  The `CertRefs` and `StandardCerts` fields are both optional, but one of them must be set for a valid TLS configuration.
   208  CertRefs is a slice of
   209  named config maps, each containing a single cert. We originally proposed to follow the convention established by the
   210  [CertificateRefs field on Gateway](https://github.com/kubernetes-sigs/gateway-api/blob/18e79909f7310aafc625ba7c862dfcc67b385250/apis/v1beta1/gateway_types.go#L340)
   211  , but the CertificateRef requires both a tls.key and tls.crt and a certificate reference only requires the tls.crt.
   212  StandardCerts is an optional enum that allows users to specify whether to use the set of CA certificates trusted by the
   213  Gateway (StandardCerts specified as "System"), or to use the existing CertRefs (StandardCerts specified as "").  The use
   214  
   215  and definition of system certificates is implementation-dependent, and the intent is that these certificates are obtained
   216  from the underlying operating system. CertRefs contains one or more references to Kubernetes objects that
   217  contain PEM-encoded TLS certificates, which are used to establish a TLS handshake between the gateway and backend pod.
   218  References to a resource in a different namespace are invalid.
   219  If CertRefs is unspecified, then StandardCerts must be set to "System" for a valid configuration.
   220  If StandardCerts is unspecified, then CertRefs must be specified with at least one entry for a valid configuration.
   221  If StandardCerts is set to "System" and there are no system trusted certificates or the implementation doesn't define system
   222  trusted certificates, then the associated TLS connection must fail.
   223  
   224  The `Hostname` field is required and is to be used to configure the SNI the Gateway should use to connect to the backend.
   225  Implementations must validate that at least one name in the certificate served by the backend matches this field.
   226  We originally proposed using a list of allowed Subject Alternative Names, but determined that this was [not needed in
   227  the first round](https://github.com/kubernetes-sigs/gateway-api/pull/2113#issuecomment-1696127092),
   228  but may be added in the future.
   229  
   230  We originally proposed allowing the configuration of expected TLS versions, but determined that this was [not needed in
   231  the first round](https://github.com/kubernetes-sigs/gateway-api/pull/2113#issuecomment-1696127092).
   232  
   233  Thus, the following additions would be made to the Gateway API:
   234  
   235  ```go
   236  import "sigs.k8s.io/gateway-api/apis/v1beta1"
   237  
   238  // BackendTLSPolicy provides a way to publish TLS configuration
   239  // that enables a gateway client to connect to a backend pod.
   240  type BackendTLSPolicy struct {
   241      metav1.TypeMeta   `json:",inline"`
   242      metav1.ObjectMeta `json:"metadata,omitempty"`
   243  
   244      // Spec defines the desired state of BackendTLSPolicy.
   245      Spec BackendTLSPolicySpec `json:"spec"`
   246  
   247      // Status defines the current state of BackendTLSPolicy.
   248      Status PolicyStatus `json:"status,omitempty"`
   249  }
   250  
   251  // BackendTLSPolicySpec defines the desired state of
   252  // BackendTLSPolicy.
   253  // Note: there is no Override or Default policy configuration.
   254  //
   255  // Support: Core
   256  type BackendTLSPolicySpec struct {
   257      // TargetRef identifies an API object to apply policy to.
   258      // Services are the only valid API target references.
   259      // Note that this config applies to the entire referenced resource
   260      // by default, but this default may change in the future to provide
   261      // a more granular application of the policy.
   262      TargetRef gatewayv1a2.PolicyTargetReference `json:"targetRef"`
   263  
   264      // TLS contains backend TLS policy configuration.
   265      TLS *BackendTLSPolicyConfig `json:”tls”`
   266  }
   267  
   268  // BackendTLSPolicyConfig contains backend TLS policy configuration.
   269  // +kubebuilder:validation:XValidation:message="must not contain both CertRefs and StandardCerts",rule="(has(self.certRefs) && size(self.certRefs > 0) && has(self.standardCerts) && self.standardCerts != "")"
   270  // +kubebuilder:validation:XValidation:message="must specify either CertRefs or StandardCerts",rule="!(has(self.certRefs) && size(self.certRefs > 0) || has(self.standardCerts) && self.standardCerts != "")"
   271  type BackendTLSPolicyConfig struct {
   272      // CertRefs contains one or more references to
   273      // Kubernetes objects that contain PEM-encoded TLS certificates,
   274      // which are used to establish a TLS handshake between the gateway
   275      // and backend pod.
   276      //
   277      // If CertRefs is empty or unspecified, then StandardCerts must
   278      // be specified.  Only one of CertRefs or StandardCerts may be
   279      // specified, not both.
   280      //
   281      // If CertRefs is empty or unspecified, then system trusted
   282      // certificates should be used. If there are none, or the
   283      // implementation doesn't define system trusted certificates,
   284      // then a TLS connection must fail.
   285      //
   286      // References to a resource in a different namespace are
   287      // invalid.
   288      //
   289      // A single CertRef to a Kubernetes ConfigMap kind has "Core"
   290      // support.  Implementations MAY choose to support attaching
   291      // multiple certificates to a backend, but this behavior is
   292      // implementation-specific.  Also implementation-specific is
   293      // a CertRef of other object kinds, e.g. Secret.
   294      // 
   295      // Support: Core - An optional single reference to a Kubernetes
   296      // ConfigMap.
   297      //
   298      // Support: Implementation-specific (No reference, more than one
   299      // reference, or resource types other than ConfigMaps.
   300      // Service mesh may ignore.)
   301      //
   302      // +kubebuilder:validation:MaxItems=8
   303      // +optional
   304      CertRefs []ConfigMapObjectReference `json:”certRefs,omitempty”`
   305  
   306      // StandardCerts specifies whether system CA certificates may
   307      // be used in the TLS handshake between the gateway and
   308      // backend pod.
   309      // 
   310      // If StandardCerts is unspecified or set to "", then CertRefs must
   311      // be specified with at least one entry for a valid configuration.
   312      // If StandardCerts is unspecified or set to "", then CertRefs must
   313      // be specified.  Only one of CertRefs or StandardCerts may be
   314      // specified, not both.
   315      //
   316      // StandardCerts must be set to "System" when CertRefs is unspecified.
   317      //
   318      // If StandardCerts is set to "System", then the system trusted
   319      // certificates should be used. If there are none, or the
   320      // implementation doesn't define system trusted certificates,
   321      // then a TLS connection must fail.
   322      //
   323      // Support: Core - An optional value to specify whether to use
   324      // system certificates or not.
   325      //
   326      // Support: Implementation-specific (In the absence of support
   327      // for usable system certs, may be ignored. Service mesh may ignore.)
   328      //
   329      // +optional
   330      StandardCerts *StandardCertType `json:"standardCerts,omitempty"`
   331  
   332      // Hostname is the Server Name Indication that the Gateway uses to
   333      // connect to the backend.  It represents the fully qualified domain
   334      // name of a network host, as defined by RFC1123 - except that numeric
   335      // IP addresses are not allowed. Each label of the FQDN must consist
   336      // of lower case alphanumeric characters or '-', and must start and
   337      // end with an alphanumeric character.  No other punctuation is allowed.
   338      // Wildcard domain names are specifically disallowed.
   339      //
   340      // It specifies the hostname that may authenticate, and must be in the
   341      // certificate served by the matching backend.
   342      //
   343      // Support: Core - A required value used by the Gateway to connect to
   344      // the backend when a BackendTLSPolicy is specified.
   345      Hostname v1beta1.PreciseHostname `json:"hostname"`
   346  }
   347  
   348  // StandardCertType is the type of CA certificate that will be used when
   349  // the TLS.certRefs is unspecified.
   350  // +kubebuilder:validation:Enum=System
   351  type StandardCertType string
   352  
   353  const (
   354      StandardCertSystem StandardCertType = "System"
   355  )
   356  
   357  // ConfigMapObjectReference identifies an API object including its namespace,
   358  // defaulting to ConfigMap.
   359  //
   360  // The API object must be valid in the cluster; the Group and Kind must
   361  // be registered in the cluster for this reference to be valid.
   362  //
   363  // References to objects with invalid Group and Kind are not valid, and must
   364  // be rejected by the implementation, with appropriate Conditions set
   365  // on the containing object.
   366  type ConfigMapObjectReference struct {
   367      // Group is the group of the referent.  For example, "gateway.networking.k8s.io".
   368      // When unspecified or empty string, core API group is inferred.
   369      //
   370      // +optional
   371      // +kubebuilder:default=""
   372      Group *Group `json:"group"`
   373  
   374      // Kind is the kind of the referent.  For example, "ConfigMap".
   375      //
   376      // +optional
   377      // +kubebuilder:default=ConfigMap
   378      Kind *Kind `json:"kind"`
   379  
   380      // Name is the metadata.name of the referenced config map.
   381      // +kubebuilder:validation:Required
   382      Name ObjectName `json"name"`
   383  
   384      // Namespace is the namespace of the referenced object. When unspecified, the local
   385      // namespace is inferred.
   386      //
   387      // Note that when a namespace different than the local namespace is specified,
   388      // a ReferenceGrant object is required in the referent namespace to allow that
   389      // namespace's owner to accept the reference. See the ReferenceGrant
   390      // documentation for details.
   391      //
   392      // Support: Core
   393      //
   394      // +optional
   395      Namespace *Namespace `json:"namespace,omitempty"`
   396  }
   397  
   398  // BackendTLSPolicyConditionType is the type of a condition used
   399  // as a signal by BackendTLSPolicy.  This type should be used with
   400  // the BackendTLSPolicyStatus.Conditions field.
   401  type BackendTLSPolicyConditionType string
   402  
   403  //  BackendTLSPolicyConditionReason is a reason that explains why a
   404  // particular BackendTLSPolicyConditionType was generated.
   405  type BackendTLSPolicyConditionReason string
   406  
   407  const (
   408      // This condition indicates that the BackendTLSPolicy has been
   409      // accepted as valid.
   410      // Possible reason for this condition to be True is:
   411      //
   412      // * “Accepted” 
   413      // 
   414      // Possible reasons for this condition to be False are:
   415      //
   416      // * “Invalid”
   417      // * “Pending”
   418      BackendTLSPolicyConditionAccepted BackendTLSPolicyConditionType = “Accepted”
   419  
   420      // This reason is used with the “Accepted” condition when the condition is true.
   421      BackendTLSPolicyReasonAccepted BackendTLSPolicyConditionReason = “Valid”
   422  
   423      // This reason is used with the “Accepted” condition when the BackendTLSPolicy is invalid,
   424      // e.g. use of a CertRef that crosses namespace boundaries.
   425      BackendTLSPolicyReasonInvalid BackendTLSPolicyConditionReason = “Invalid”
   426  
   427      // This reason is used with the “Accepted” condition when the BackendTLSPolicy is pending validation.
   428      BackendTLSPolicyReasonPending BackendTLSPolicyConditionReason = “Pending”
   429  )
   430  ```
   431  
   432  ## How a client behaves
   433  
   434  This table describes the effect that a BackendTLSPolicy has on a Route.  There are only two cases where the
   435  BackendTLSPolicy will signal a Route to connect to a backend using TLS, an HTTPRoute with a backend that is targeted
   436  by a BackendTLSPolicy, either with or without listener TLS configured.  (There are a few other cases where it may be
   437  possible, but is implementation dependent.)
   438  
   439  Every implementation that claims supports for BackendTLSPolicy should document for which Routes it is being implemented.
   440  
   441  | Route Type | Gateway Config             | Backend is targeted by a BackendTLSPolicy? | Connect to backend  with TLS? |
   442  |------------|----------------------------|-----------------------------------------------|-------------------------------|
   443  | HTTPRoute  | Listener tls               | Yes                                           | **Yes**                       |
   444  | HTTPRoute  | No listener tls            | Yes                                           | **Yes**                       |
   445  | HTTPRoute  | Listener tls               | No                                            | No                            |
   446  | HTTPRoute  | No listener tls            | No                                            | No                            |
   447  | TLSRoute   | Listener Mode: Passthrough | Yes                                           | No                            |
   448  | TLSRoute   | Listener Mode: Terminate   | Yes                                           | Implementation-dependent      |
   449  | TLSRoute   | Listener Mode: Passthrough | No                                            | No                            |
   450  | TLSRoute   | Listener Mode: Terminate   | No                                            | No                            |
   451  | TCPRoute   | Listener TLS               | Yes                                           | Implementation-dependent      |
   452  | TCPRoute   | No listener TLS            | Yes                                           | Implementation-dependent      |
   453  | TCPRoute   | Listener TLS               | No                                            | No                            |
   454  | TCPRoute   | No listener TLS            | No                                            | No                            |
   455  | UDPRoute   | Listener TLS               | Yes                                           | No                            |
   456  | UDPRoute   | No listener TLS            | Yes                                           | No                            |
   457  | UDPRoute   | Listener TLS               | No                                            | No                            |
   458  | UDPRoute   | No listener TLS            | No                                            | No                            |
   459  | GRPCRoute  | Listener TLS               | Yes                                           | Implementation-dependent      |
   460  | GRPCRoute  | No Listener TLS            | Yes                                           | Implementation-dependent      |
   461  | GRPCRoute  | Listener TLS               | No                                            | No                            |
   462  | GRPCRoute  | No Listener TLS            | No                                            | No                            |
   463  
   464  ## Request Flow
   465  
   466  Step 6 would be changed in the typical client/gateway API request flow for a gateway implemented using a
   467  reverse proxy. This is shown as **bolded** additions in step 6 below.
   468  
   469  1. A client makes a request to http://foo.example.com.
   470  2. DNS resolves the name to a Gateway address.
   471  3. The reverse proxy receives the request on a Listener and uses the Host header to match an HTTPRoute.
   472  4. Optionally, the reverse proxy can perform request header and/or path matching based on match rules of the HTTPRoute.
   473  5. Optionally, the reverse proxy can modify the request, i.e. add/remove headers, based on filter rules of the HTTPRoute.
   474  6. Lastly, the reverse proxy **optionally performs a TLS handshake** and forwards the request to one or more objects,
   475  i.e. Service, in the cluster based on backendRefs rules of the HTTPRoute **and TLSTargetRef of the BackendTLSPolicy**.
   476  
   477  ## Alternatives
   478  Most alternatives are enumerated in the section on the history of backend TLS above.  A couple of additional
   479  alternatives are also listed here.
   480  
   481  1. Expand BackendRef, which is already an expansion point.  At first, it seems logical that since listeners are handling
   482  the client-gateway certs, BackendRefs could handle the gateway-backend certs.  However, when multiple Routes to target
   483  the same Service, there would be unnecessary copying of the BackendRef every time the Service was targeted.  As well,
   484  there could be multiple bBackendRefs with multiple rules on a rRoute, each of which might need the gateway-backend cert
   485  configuration so it is not the appropriate pattern.
   486  2. Extend HTTPRoute to indicate TLS backend support. Extending HTTPRoute would interfere with deployed implementations
   487  too much to be a practical solution.
   488  3. Add a new type of Route for backend TLS.  This is impractical because we might want to enable backend TLS on other
   489  route types in the future, and because we might want to have both TLS listeners and backend TLS on a single route.
   490  
   491  ## Prior Art
   492  
   493  TLS from gateway to backend for ingress exists in several implementations, and was developed independently.
   494  
   495  ### Istio Gateway supports this with a DestinationRule:
   496  
   497  * A secret representing a certificate/key pair, where the certificate is valid for the route host
   498  * Set Gateway spec.servers[].port.protocol: HTTPS, spec.servers[].tls.mode=SIMPLE, spec.servers[].tls.credentialName
   499  * Set DestinationRule spec.trafficPolicy.tls.mode: SIMPLE
   500  
   501  Ref: [Istio / Understanding TLS Configuration](https://istio.io/latest/docs/ops/configuration/traffic-management/tls-configuration/#gateways)
   502  and [Istio / Destination Rule](https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings)
   503  
   504  ### OpenShift Route (comparable to GW API Gateway) supports this with the following route configuration items:
   505  
   506  * A certificate/key pair, where the certificate is valid for the route host
   507  * A separate destination CA certificate enables the Ingress Controller to trust the destination’s certificate
   508  * An optional, separate CA certificate that completes the certificate chain
   509  
   510  Ref: [Secured routes - Configuring Routes | Networking | OpenShift Container Platform 4.12](https://docs.openshift.com/container-platform/4.12/networking/routes/secured-routes.html#nw-ingress-creating-a-reencrypt-route-with-a-custom-certificate_secured-routes)
   511  
   512  ### Contour supports this from Envoy to the backend using:
   513  
   514  * An Envoy client certificate
   515  * A CA certificate and SubjectName which are both used to verify the backend endpoint’s identity
   516  * Kubernetes Service annotation: projectcontour.io/upstream-protocol.tls
   517  
   518  Ref: [Upstream TLS](https://projectcontour.io/docs/v1.21.1/config/upstream-tls/)
   519  
   520  ### GKE supports a way to encrypt traffic to the backend pods using:
   521  
   522  * `AppProtocol` on Service set to HTTPS
   523  * Load balancer does not verify the certificate used by backend pods
   524  
   525  Ref: [Secure a Gateway](https://cloud.google.com/kubernetes-engine/docs/how-to/secure-gateway#load-balancer-tls)
   526  
   527  ### Emissary supports encrypted traffic to services
   528  
   529  * In the `Mapping` definition, set https:// in the spec.service field
   530  * A spec.tls in the `Mapping` definition, with the name of a `TLSContext`
   531  * A `TLSContext` to provide a client certificate, set minimum TLS version support, SNI
   532  
   533  Ref: [TLS Origination](https://www.getambassador.io/docs/emissary/latest/topics/running/tls/origination)
   534  
   535  ### NGINX implementation through CRDs (Comparable to Route or Policy of Gateway API) supports both TLS and mTLS
   536  
   537  * In the Upstream section of a VirtualServer or VirtualServerRoute (equivalent to HTTPRoute) there is a simple toggle to enable TLS.  This does not validate the certificate of the backend and implicitly trusts the backend in order to form the SSL tunnel.  This is not about validating the certificate but obfuscating the traffic with TLS/SSL.
   538  * A Policy attachment can be provided when certification validation is required that is called egressMTLS (egress from the proxy to the upstream).  This can be tuned to perform various certificate validation tests.  It was created as a Policy becuase it implies some type of AuthN/AuthZ due to the additional checks.  This was also compatible with Open Service Mesh and NGINX Service Mesh and removed the need for a sidecar at the ingress controller.
   539  * A corresponding 'IngressMTLS' policy also exists for mTLS verification of client connections to the proxy.  The Policy object is used for anything that implies AuthN/AuthZ.
   540  
   541  Ref: [Upstream.TLS](https://docs.nginx.com/nginx-ingress-controller/configuration/virtualserver-and-virtualserverroute-resources/#upstreamtls)
   542  
   543  Ref: [EgressMTLS](https://docs.nginx.com/nginx-ingress-controller/configuration/policy-resource/#egressmtls)
   544  
   545  Ref: [IngressMTLS](https://docs.nginx.com/nginx-ingress-controller/configuration/policy-resource/#ingressmtls)
   546  
   547  ## Answered Questions
   548  
   549  Q. Bowei recommended that we mention the approach of cross-namespace referencing between Route and Service.
   550  Be explicit about using the standard rules with respect to attaching policies to resources.
   551  
   552  A. This is mentioned in the
   553  API section.
   554  
   555  Q. Costin recommended that Gateway SHOULD authenticate with either a JWT with audience or client cert
   556  or some other means - so gateway added headers can be trusted, amongst other things.
   557  
   558  A. This is out of scope for this
   559  proposal, which centers around application developer persona resources such as HTTPRoute and Service.
   560  
   561  Q. Costin mentioned we need to answer the question - is configuring the connection to a backend and TLS
   562  something the route author decides - or the backend owner?
   563  
   564  A. This is decided by the application developer persona,
   565  which would more likely, but not exclusively, be the backend owner.
   566  
   567  Q.Costin continued, same for SAN (Subject Alternative Name) certificates.
   568  The backend owner is the application developer, and the route owner will have to collaborate with the application
   569  developer to provide the appropriate configuration for TLS.  The implementation would need to take the certificate
   570  provided by the application and verify that it satisfies the requirements of the route-as-client, including SAN
   571  information.  Sometimes the backend owner and route owner are the same entity.
   572  
   573  A. This was most recently addressed by
   574  adding hostname for SNI and removing allowed SANs.
   575  
   576  ## Graduation Criteria
   577  
   578  This section is to record issues that were requested for discussion in the API section before this GEP graduates
   579  out of `Provisional` status.
   580  
   581  1. Rob Scott is interested in extending the TargetRef to optionally include port, since we are targeting the entirety
   582  of a Service. See the discussion in https://github.com/kubernetes-sigs/gateway-api/pull/2113/files#r1231594914,
   583  and follow up issue in https://github.com/kubernetes-sigs/gateway-api/issues/2147
   584  2. Michael Pleshakov asked about conflicts that could arise when multiple implementations are running in a cluster.
   585  This is a gap in our policy attachment model that needs to be addressed.  See the discussion in
   586  https://github.com/kubernetes-sigs/gateway-api/pull/2113/files#r1235750540. Graduating this GEP to implementable
   587  requires an update to the Policy GEP to define how status can be nested to support multiple implementations. This will
   588  likely look very similar to Route status.
   589  See [comment](https://github.com/kubernetes-sigs/gateway-api/pull/2113#issuecomment-1696127092).
   590  3. Rob Scott [wanted to note](https://github.com/kubernetes-sigs/gateway-api/pull/2113#issuecomment-1696127092) that
   591  when this graduates to the standard channel, implementations of HTTPRoute may also be
   592  required to watch the BackendTLSPolicy. If one of these policies is attached to a Service targeted by an HTTPRoute,
   593  the implementation would be required to fully implement the policy or mark the backend invalid.
   594  
   595  ## References
   596  
   597  [Gateway API TLS Use Cases](https://docs.google.com/document/d/17sctu2uMJtHmJTGtBi_awGB0YzoCLodtR6rUNmKMCs8/edit#heading=h.cxuq8vo8pcxm)
   598  
   599  [GEP-713: Metaresources and PolicyAttachment](https://gateway-api.sigs.k8s.io/geps/gep-713/)
   600  
   601  [Policy Attachment](https://gateway-api.sigs.k8s.io/reference/policy-attachment/#direct-policy-attachment)
   602  
   603  [Gateway API TLS](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tls/)
   604  
   605  [SIG-NET Gateway API: TLS to the K8s.Service/Backend](https://docs.google.com/document/d/1RTYh2brg_vLX9o3pTcrWxtZSsf8Y5NQvIG52lpFcZlo)
   606  
   607  [SAN vs SNI](https://serverfault.com/questions/807959/what-is-the-difference-between-san-and-sni-ssl-certificates)