...
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
12This GEP attempts to enable cross namespace forwarding from Routes and provide a
13way to simplify adding Route inclusion (Routes including other Routes) in the
14future. These are closely related concepts that can be solved with a new
15ReferenceGrant resource that enables app admins to describe where they trust
16references from.
17
18## Motivation/User Journeys/Background
19
20This GEP keeps same namespace references simple while enabling the following
21capabilities for cross namespace references:
22
231. Retaining full control of Gateway and Routes in an infra namespace, while
24 targeting apps in different namespaces.
251. Traffic splitting between Services in different namespaces.
261. 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
31Anytime we allow crossing a namespace boundary, we need to be very cautious.
32In the past, we've seen that forwarding traffic across namespace boundaries is
33a desired feature, but without the kinds of safeguards proposed here,
34[vulnerabilities](https://github.com/kubernetes/kubernetes/issues/103675) can
35emerge.
36
37To ensure that Gateway API is able to safely provide this functionality, we need
38to enforce a handshake mechanism that requires resources in both namespaces to
39agree to this reference. To accomplish that, a new ReferenceGrant resource
40should be introduced.
41
42
43
44With this model, Routes would be able to directly reference Routes and Services
45in other namespaces. These references would only be considered valid if a
46ReferenceGrant in the target namespace explicitly allowed it.
47
48The following example shows how a HTTPRoute in namespace foo could reference
49a Service in namespace bar. In this example a ReferenceGrant in the bar
50namespace explicitly allows references to Services from HTTPRoutes in the foo
51namespace.
52
53```yaml
54kind: HTTPRoute
55metadata:
56 name: foo
57 namespace: foo
58spec:
59 rules:
60 - matches:
61 - path: /bar
62 forwardTo:
63 backend:
64 - name: bar
65 namespace: bar
66---
67kind: ReferenceGrant
68metadata:
69 name: bar
70 namespace: bar
71spec:
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
82This proposed API is fairly straightforward, but comes with a few notable
83decisions:
84
851. Each ReferenceGrant only supports a single From and To section. Additional
86 trust relationships can be modeled with additional ReferenceGrant resources.
871. 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.
911. 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.
100type 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.
111type 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.
134type 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.
167type 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
204There are some situations where it MAY be acceptable to ignore ReferenceGrant
205in favor of some other security mechanism. This MAY only be done if other
206mechanisms like NetworkPolicy can effectively limit cross-namespace references
207by the implementation.
208
209An implementation choosing to make this exception MUST clearly document that
210ReferenceGrant is not honored by their implementations and detail which
211alternative safeguards are available. Note that this is unlikely to apply to
212ingress implementations of the API and will not apply to all mesh
213implementations.
214
215For an example of the risks involved in cross-namespace references, refer to
216[CVE-2021-25740](https://github.com/kubernetes/kubernetes/issues/103675).
217Implementations of this API need to be very careful to avoid confused deputy
218attacks. ReferenceGrant provides a safeguard for that. Exceptions MUST only
219be made by implementations that are absolutely certain that other equally
220effective safeguards are in place.
221
222## ForwardTo
223
224To enable cross-namespace forwarding, we'll need to add an optional `namespace`
225field to the ForwardTo BackendRef struct.
226
227```go
228type 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
246Instead of ReferenceGrant, it is possible to represent these relationships
247inline.
248
249
250```yaml
251kind: HTTPRoute
252metadata:
253 name: foo
254 namespace: foo
255spec:
256 rules:
257 - matches:
258 - path: /bar
259 forwardTo:
260 backend:
261 - name: bar
262 namespace: bar
263---
264kind: Service
265metadata:
266 name: baz
267 namespace: baz
268 annotations:
269 gateway.networking.k8s.io/accept-forwarding-from: bar
270```
271
272Although this requires less YAML for the simple case, it is less flexible.
273Annotations have real limitations and don't provide any room for RBAC
274differentiation. Although it's possible that we could eventually add a proper
275field to the Service API to represent this, it would be impossible to add this
276concept 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)
View as plain text