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  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  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)