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

     1  # GEP-709: Cross Namespace References from Routes
     2  
     3  * Issue: [#709](https://github.com/kubernetes-sigs/gateway-api/issues/709)
     4  * Status: Standard
     5  
     6  !!! note
     7      This resource was originally named "ReferencePolicy". It was renamed
     8      to "ReferenceGrant" to avoid any confusion with policy attachment.
     9  
    10  ## TLDR
    11  
    12  This GEP attempts to enable cross namespace forwarding from Routes and provide a
    13  way to simplify adding Route inclusion (Routes including other Routes) in the
    14  future. These are closely related concepts that can be solved with a new
    15  ReferenceGrant resource that enables app admins to describe where they trust
    16  references from.
    17  
    18  ## Motivation/User Journeys/Background
    19  
    20  This GEP keeps same namespace references simple while enabling the following
    21  capabilities for cross namespace references:
    22  
    23  1. Retaining full control of Gateway and Routes in an infra namespace, while
    24     targeting apps in different namespaces.
    25  1. Traffic splitting between Services in different namespaces.
    26  1. Mesh overrides to target Services in different namespaces. (For more info,
    27     see GEP [#713](https://github.com/kubernetes-sigs/gateway-api/issues/713))
    28  
    29  ## ReferenceGrant
    30  
    31  Anytime we allow crossing a namespace boundary, we need to be very cautious.
    32  In the past, we've seen that forwarding traffic across namespace boundaries is
    33  a desired feature, but without the kinds of safeguards proposed here,
    34  [vulnerabilities](https://github.com/kubernetes/kubernetes/issues/103675) can
    35  emerge.
    36  
    37  To ensure that Gateway API is able to safely provide this functionality, we need
    38  to enforce a handshake mechanism that requires resources in both namespaces to
    39  agree to this reference. To accomplish that, a new ReferenceGrant resource
    40  should be introduced.
    41  
    42  ![Reference Policy](images/709-referencegrant.png)
    43  
    44  With this model, Routes would be able to directly reference Routes and Services
    45  in other namespaces. These references would only be considered valid if a
    46  ReferenceGrant in the target namespace explicitly allowed it.
    47  
    48  The following example shows how a HTTPRoute in namespace foo could reference
    49  a Service in namespace bar. In this example a ReferenceGrant in the bar
    50  namespace explicitly allows references to Services from HTTPRoutes in the foo
    51  namespace.
    52  
    53  ```yaml
    54  kind: HTTPRoute
    55  metadata:
    56    name: foo
    57    namespace: foo
    58  spec:
    59    rules:
    60    - matches:
    61      - path: /bar
    62      forwardTo:
    63        backend:
    64        - name: bar
    65          namespace: bar
    66  ---
    67  kind: ReferenceGrant
    68  metadata:
    69    name: bar
    70    namespace: bar
    71  spec:
    72    from:
    73    - group: networking.gateway.k8s.io
    74      kind: HTTPRoute
    75      namespace: foo
    76    to:
    77    - group: core
    78      kind: Service
    79  ```
    80  
    81  ### API
    82  This proposed API is fairly straightforward, but comes with a few notable
    83  decisions:
    84  
    85  1. Each ReferenceGrant only supports a single From and To section. Additional
    86     trust relationships can be modeled with additional ReferenceGrant resources.
    87  1. Resource names are intentionally excluded from this policy for simplicity and
    88     because they rarely provide any meaningful protection. A user that is able
    89     to write to resources of a certain kind within a namespace can always rename
    90     resources or change the structure of the resources to match a given policy.
    91  1. A single Namespace is allowed per "From" struct. Although a selector would be
    92     more powerful it may encourage unnecessarily insecure configuration.
    93  
    94  ```go
    95  // ReferenceGrant identifies kinds of resources in other namespaces that are
    96  // trusted to reference the specified kinds of resources in the local namespace.
    97  // Each ReferenceGrant can be used to represent a unique trust relationship.
    98  // Additional ReferenceGrants can be used to add to the set of trusted
    99  // sources of inbound references for the namespace they are defined within.
   100  type ReferenceGrant struct {
   101      metav1.TypeMeta   `json:",inline"`
   102      metav1.ObjectMeta `json:"metadata,omitempty"`
   103  
   104      // Spec defines the desired state of ReferenceGrant.
   105      Spec ReferenceGrantSpec `json:"spec,omitempty"`
   106  }
   107  
   108  
   109  // ReferenceGrantSpec identifies a cross namespace relationship that is trusted
   110  // for Gateway API.
   111  type ReferenceGrantSpec struct {
   112      // From describes the trusted namespaces and kinds that can reference the
   113      // resources described in "To". Each entry in this list must be considered
   114      // to be an additional place that references can be valid from, or to put
   115      // this another way, entries must be combined using OR.
   116      //
   117      // Support: Core
   118      //
   119      // +kubebuilder:validation:MinItems=1
   120      From []ReferenceGrantFrom `json:"from"`
   121  
   122      // To describes the resources that may be referenced by the resources
   123      // described in "From". Each entry in this list must be considered to be an
   124      // additional place that references can be valid to, or to put this another
   125      // way, entries must be combined using OR.
   126      //
   127      // Support: Core
   128      //
   129      // +kubebuilder:validation:MinItems=1
   130      To []ReferenceGrantTo `json:"to"`
   131  }
   132  
   133  // ReferenceGrantFrom describes trusted namespaces and kinds.
   134  type ReferenceGrantFrom struct {
   135      // Group is the group of the referrent.
   136      //
   137      // Support: Core
   138      //
   139      // +kubebuilder:validation:MinLength=1
   140      // +kubebuilder:validation:MaxLength=253
   141      Group string `json:"group"`
   142  
   143      // Kind is the kind of the referrent. Although implementations may support
   144      // additional resources, the following Route types are part of the "Core"
   145      // support level for this field:
   146      //
   147      // * HTTPRoute
   148      // * TCPRoute
   149      // * TLSRoute
   150      // * UDPRoute
   151      //
   152      // +kubebuilder:validation:MinLength=1
   153      // +kubebuilder:validation:MaxLength=253
   154      Kind string `json:"kind"`
   155  
   156      // Namespace is the namespace of the referrent.
   157      //
   158      // Support: Core
   159      //
   160      // +kubebuilder:validation:MinLength=1
   161      // +kubebuilder:validation:MaxLength=253
   162      Namespace string `json:"namespace,omitempty"`
   163  }
   164  
   165  // ReferenceGrantTo describes what Kinds are allowed as targets of the
   166  // references.
   167  type ReferenceGrantTo struct {
   168      // Group is the group of the referrent.
   169      //
   170      // Support: Core
   171      //
   172      // +kubebuilder:validation:MinLength=1
   173      // +kubebuilder:validation:MaxLength=253
   174      Group string `json:"group"`
   175  
   176      // Kind is the kind of the referrent. Although implementations may support
   177      // additional resources, the following types are part of the "Core"
   178      // support level for this field:
   179      //
   180      // * Service
   181      // * HTTPRoute
   182      // * TCPRoute
   183      // * TLSRoute
   184      // * UDPRoute
   185      //
   186      // +kubebuilder:validation:MinLength=1
   187      // +kubebuilder:validation:MaxLength=253
   188      Kind string `json:"kind"`
   189  }
   190  ```
   191  
   192  
   193  ### Benefits
   194  
   195  * Conceptually similar to NetworkPolicy.
   196  * A separate resource enables admins to restrict who can allow cross namespace
   197    references.
   198  * Provides consistent way to control references to any resource from a Route.
   199  * Can be extended in the future for additional use cases.
   200  * A single ReferenceGrant resource can be used for a namespace in place of
   201    separate handshake config on each Service or Route resource.
   202  
   203  #### Exceptions
   204  There are some situations where it MAY be acceptable to ignore ReferenceGrant
   205  in favor of some other security mechanism. This MAY only be done if other
   206  mechanisms like NetworkPolicy can effectively limit cross-namespace references
   207  by the implementation.
   208  
   209  An implementation choosing to make this exception MUST clearly document that
   210  ReferenceGrant is not honored by their implementations and detail which
   211  alternative safeguards are available. Note that this is unlikely to apply to
   212  ingress implementations of the API and will not apply to all mesh
   213  implementations.
   214  
   215  For an example of the risks involved in cross-namespace references, refer to
   216  [CVE-2021-25740](https://github.com/kubernetes/kubernetes/issues/103675).
   217  Implementations of this API need to be very careful to avoid confused deputy
   218  attacks. ReferenceGrant provides a safeguard for that. Exceptions MUST only
   219  be made by implementations that are absolutely certain that other equally
   220  effective safeguards are in place.
   221  
   222  ## ForwardTo
   223  
   224  To enable cross-namespace forwarding, we'll need to add an optional `namespace`
   225  field to the ForwardTo BackendRef struct.
   226  
   227  ```go
   228  type BackendRef struct {
   229      // ...
   230  
   231      // Namespace is the namespace of the backend. When unspecified, the local
   232      // namespace is inferred.
   233      //
   234      // Support: Core
   235      //
   236      // +kubebuilder:validation:MinLength=1
   237      // +kubebuilder:validation:MaxLength=253
   238      // +optional
   239      Namespace *string `json:"namespace,omitempty"`
   240  }
   241  ```
   242  
   243  ## Alternatives
   244  
   245  ### Inline Config
   246  Instead of ReferenceGrant, it is possible to represent these relationships
   247  inline.
   248  ![Inline](images/709-inline.png)
   249  
   250  ```yaml
   251  kind: HTTPRoute
   252  metadata:
   253    name: foo
   254    namespace: foo
   255  spec:
   256    rules:
   257    - matches:
   258      - path: /bar
   259      forwardTo:
   260        backend:
   261        - name: bar
   262          namespace: bar
   263  ---
   264  kind: Service
   265  metadata:
   266    name: baz
   267    namespace: baz
   268    annotations:
   269      gateway.networking.k8s.io/accept-forwarding-from: bar
   270  ```
   271  
   272  Although this requires less YAML for the simple case, it is less flexible.
   273  Annotations have real limitations and don't provide any room for RBAC
   274  differentiation. Although it's possible that we could eventually add a proper
   275  field to the Service API to represent this, it would be impossible to add this
   276  concept to all potential backend types.
   277  
   278  ## Out of scope
   279  
   280  * Although closely related, this GEP does not attempt to improve the
   281    Gateway->Route relationship. That will instead be covered by a future GEP.
   282  * Although this GEP explores how ReferenceGrant could enable Route inclusion,
   283    the details of that feature will be left for a future GEP.
   284  
   285  ## References
   286  
   287  **GitHub Issues:**
   288  
   289  * [#411: Clarify how RouteGateways would work if we supported Route->Route
   290    delegation](https://github.com/kubernetes-sigs/gateway-api/issues/411)
   291  * [#582: Allow cross namespace
   292    references](https://github.com/kubernetes-sigs/gateway-api/issues/582)
   293  * [#634: Request Filtering Between Gateways and Namespaced
   294    Routes](https://github.com/kubernetes-sigs/gateway-api/issues/634)
   295  
   296  **Docs:**
   297  
   298  * [Gateway API Reference
   299    Policy](https://docs.google.com/document/d/18MoabVA-fr5XL9cYdf6cxclqRwFpOvHUXV_UYzSiooY/edit)
   300  * [Selection Policy
   301    Proposal](https://docs.google.com/document/d/1S9t4YiDBwe1X7q915zKO0meZ8O_UPa8bzBLWBY8_XdM/edit?usp=sharing)
   302  * [Route Inclusion
   303    Proposal](https://docs.google.com/document/d/1-0mgRRAY784OgGQ1_LCOshpLLbeAtIr4eXd0YVYK4RY/edit#heading=h.8cfxzle5tmqb)
   304  * [Cross Namespace Forwarding
   305    Proposal](https://docs.google.com/document/d/1_B1G9JcNw3skNYLtdK7lTTzOeyz5w2hpa84cKA_MGKk/edit)