12
12
- [ Potential for Variations Among Implementations] ( #potential-for-variations-among-implementations )
13
13
- [ Cross-Namespace References may Weaken Namespace Boundaries] ( #cross-namespace-references-may-weaken-namespace-boundaries )
14
14
- [ Design Details] ( #design-details )
15
+ - [ General Notes] ( #general-notes )
16
+ - [ <code >ReferenceGrant</code > is half of a handshake] ( #-is-half-of-a-handshake )
17
+ - [ <code >Resource</code > vs <code >Kind</code >] ( #-vs- )
18
+ - [ Revocation behavior] ( #revocation-behavior )
19
+ - [ Example Usage] ( #example-usage )
20
+ - [ Gateway API Gateway Referencing Secret] ( #gateway-api-gateway-referencing-secret )
21
+ - [ Gateway API HTTPRoute Referencing Service] ( #gateway-api-httproute-referencing-service )
22
+ - [ PersistentVolumeClaim using cross namespace data source] ( #persistentvolumeclaim-using-cross-namespace-data-source )
15
23
- [ API Spec] ( #api-spec )
24
+ - [ Outstanding questions and clarifications] ( #outstanding-questions-and-clarifications )
16
25
- [ Test Plan] ( #test-plan )
17
26
- [ Prerequisite testing updates] ( #prerequisite-testing-updates )
18
27
- [ Unit tests] ( #unit-tests )
@@ -68,17 +77,19 @@ sig-storage](https://kubernetes.io/blog/2023/01/02/cross-namespace-data-sources-
68
77
to enable cross-namespace data sources.
69
78
70
79
This KEP proposes moving ReferenceGrant from its current
71
- ` gateway.networking.k8s.io ` API group to a new ` grants. authorization.k8s.io` API
80
+ ` gateway.networking.k8s.io ` API group into the ` authorization.k8s.io ` API
72
81
group.
73
82
74
83
## Motivation
75
84
76
- Now that it's clear that ReferenceGrant is useful beyond just Gateway API, it
77
- would be good to formalize this model in a more neutral home, ideally sig-auth.
78
- At this point, each project that wants to enable cross-namespace references has
79
- to choose between introducing a dependency on Gateway API and creating a new
80
- resource that would largely duplicate ReferenceGrant. Both options would lead to
81
- confusion for Kubernetes users.
85
+ Any project that wants to enable cross-namespace references currently has to choose
86
+ between introducing a dependency on Gateway API's ReferenceGrant or creating a
87
+ new API that would be partially redundant (leading to confusion for users).
88
+
89
+ Recent interest between SIGs has made it clear that ReferenceGrant is wanted for use
90
+ cases other than Gateway API. We would like to move ReferenceGrant to a neutral home
91
+ (ideally, under sig-auth) in order to make it the canonical API for managing references
92
+ across namespaces.
82
93
83
94
### Goals
84
95
@@ -97,13 +108,11 @@ confusion for Kubernetes users.
97
108
## Proposal
98
109
99
110
Move the existing ReferenceGrant resource into a new
100
- ` grants. authorization.k8s.io` API group, defined within the Kubernetes code base
111
+ ` authorization.k8s.io ` API group, defined within the Kubernetes code base
101
112
as part of the 1.27 release.
102
113
103
- We will take this opportunity to clarify underspecified parts of the API, but
104
- will not add, change, or remove any fields as part of this transition.
105
- This resource will start with v1beta1 as the API version, matching the API version
106
- it already has within Gateway API.
114
+ We will take this opportunity to clarify and update the API after SIG-Auth
115
+ feedback. This resource will start with v1alpha1 as the API version.
107
116
108
117
109
118
### Risks and Mitigations
@@ -143,28 +152,225 @@ across namespaces. It's intended that _another object_ (that is, the From object
143
152
complete the handshake by creating a reference to the referent object (the To
144
153
object).
145
154
146
- #### ` Kind ` vs ` Resource `
155
+ #### ` Resource ` vs ` Kind `
147
156
148
157
When creating a metaresource (that is, a resource that targets other resources)
149
158
like ReferenceGrant, it's important to consider if the metaresource uses the more
150
159
common ` Kind ` or the more correct ` Resource ` .
151
160
152
- When designing the Gateway API in general, we considered this quite a bit (and
153
- @robscott even ended up making https://github.com/kubernetes/community/pull/5973
154
- to clarify the API conventions), but in the end decided to use Kind, to improve
155
- the user experience. That is, it's easier users to take the value from the ` kind `
156
- field at the top of the YAML they are already using, and put it straight into
157
- these fields, rather than needing to do a kind-resource lookup for every user's
158
- interaction with the API.
161
+ In the original Gateway API implementation, we chose to use ` Kind ` rather than
162
+ ` Resource ` , mainly to improve the user experience. That is, it's easier users
163
+ to take the value from the ` kind ` field at the top of the YAML they are already
164
+ using, and put it straight into these fields, rather than needing to do a
165
+ kind-resource lookup for every user's interaction with the API. @robscott even
166
+ ended up making https://github.com/kubernetes/community/pull/5973 to clarify
167
+ the API conventions.
168
+
169
+ However, in discussion on this KEP, it's clear that the more generic nature of
170
+ _ this_ API requires the additional specificity that ` Resource ` provides.
171
+
172
+ The Gateway API ReferenceGrant looked like this:
173
+ ``` yaml
174
+ apiVersion : gateway.networking.k8s.io/v1beta1
175
+ kind : ReferenceGrant
176
+ metadata :
177
+ name : allow-gateways
178
+ namespace : bar
179
+ spec :
180
+ from :
181
+ # Note that in Gateway API, Group is currently defaulted
182
+ # to this, which means you to explicitly set the group to
183
+ # the empty string for Core resources. We should definitely
184
+ # change this.
185
+ - group : " gateway.networking.kubernetes.io"
186
+ kind : Gateway
187
+ namespace : foo
188
+ to :
189
+ - group : " "
190
+ kind : Secret
191
+ ` ` `
192
+
193
+ The new version will look like this instead:
194
+ ` ` ` yaml
195
+ apiVersion : authorization.k8s.io/v1alpha1
196
+ kind : ReferenceGrant
197
+ metadata :
198
+ name : allow-gateways
199
+ namespace : bar
200
+ spec :
201
+ from :
202
+ # Assuming that we leave the default for Group to the empty
203
+ # string, so that Core objects don't need additional config.
204
+ - group : " gateway.networking.kubernetes.io"
205
+ resource : gateways
206
+ namespace : foo
207
+ to :
208
+ - resource : secrets
209
+
210
+ ```
159
211
160
- Secondly, as in the Ingress API, the target types must be clearly defined by
161
- each implementation, so there should be no opportunity for ambiguity.
212
+ The new version communicates the scope more clearly because ` resource ` is plural.
213
+
214
+ #### Revocation behavior
215
+
216
+ Unfortunately, there's no way to be specific about what happens when a
217
+ ReferenceGrant is deleted in every possible case - the revocation behavior is
218
+ dependent on what access is being granted (and revoked).
219
+
220
+ The general rules we've used in the past are:
221
+ * Deletion of a ReferenceGrant means the granted access is revoked
222
+ * ReferenceGrant controllers must remove any configuration generated by the granted
223
+ access as soon as possible (eventual consistence permitting)
224
+ * Implementations should err on the side of removing access rather than leaving
225
+ it lying around.
226
+
227
+ The examples below include information about what happens when the ReferenceGrant
228
+ is removed as data points.
229
+
230
+ ### Example Usage
231
+
232
+ #### Gateway API Gateway Referencing Secret
233
+
234
+ In this example (from the Gateway API docs), we have a Gateway in the
235
+ ` gateway-api-example-ns1 ` namespace, referencing a Secret in the
236
+ ` gateway-api-example-ns2 ` namespace. The following ReferenceGrant allows this:
237
+
238
+ ``` yaml
239
+ apiVersion : gateway.networking.k8s.io/v1beta1
240
+ kind : Gateway
241
+ metadata :
242
+ name : cross-namespace-tls-gateway
243
+ namespace : gateway-api-example-ns1
244
+ spec :
245
+ gatewayClassName : acme-lb
246
+ listeners :
247
+ - name : https
248
+ protocol : HTTPS
249
+ port : 443
250
+ hostname : " *.example.com"
251
+ tls :
252
+ certificateRefs :
253
+ # There's a Kind/Resource mismatch here, which sucks, but it is not
254
+ # easily fixable, since Gateway is already a beta, close to GA
255
+ # object.
256
+ - kind : Secret
257
+ group : " "
258
+ name : wildcard-example-com-cert
259
+ namespace : gateway-api-example-ns2
260
+ ---
261
+ apiVersion : authorization.k8s.io/v1alpha1
262
+ kind : ReferenceGrant
263
+ metadata :
264
+ name : allow-ns1-gateways-to-ref-secrets
265
+ namespace : gateway-api-example-ns2
266
+ spec :
267
+ from :
268
+ - group : gateway.networking.k8s.io
269
+ resource : gateways
270
+ namespace : gateway-api-example-ns1
271
+ to :
272
+ - resource : secrets
273
+ ` ` `
274
+
275
+ For Gateway TLS references, if this ReferenceGrant is deleted (revoking,
276
+ the grant), then the Listener will become invalid, and the configuration
277
+ will be removed as soon as possible (eventual consistency permitting).
278
+
279
+ #### Gateway API HTTPRoute Referencing Service
280
+
281
+ In this example, a HTTPRoute in the ` baz` namespace is directing traffic
282
+ to a Service backend in the `quux` namespace.
283
+
284
+ ` ` ` yaml
285
+ apiVersion: gateway.networking.k8s.io/v1beta1
286
+ kind: HTTPRoute
287
+ metadata:
288
+ name: quuxapp
289
+ namespace: baz
290
+ spec:
291
+ parentRefs:
292
+ - name: example-gateway
293
+ sectionName: https
294
+ hostnames:
295
+ - quux.example.com
296
+ rules:
297
+ - matches:
298
+ - path:
299
+ type: PathPrefix
300
+ value: /
301
+ backendRefs:
302
+ # BackendRefs are Services by default.
303
+ - name: quuxapp
304
+ namespace: quux
305
+ port: 80
306
+ ---
307
+ apiVersion: authorization.k8s.io/v1alpha1
308
+ kind: ReferenceGrant
309
+ metadata:
310
+ name: allow-baz-httproutes
311
+ namespace: quux
312
+ spec:
313
+ from:
314
+ - group: gateway.networking.k8s.io
315
+ resource: httproutes
316
+ namespace: baz
317
+ to:
318
+ - resource: services
319
+ ` ` `
162
320
163
- Lastly, this is only half of a handshake, so the From referent must also both
164
- support referencing the To referent, and must reference the one in the To field.
321
+ For HTTPRoute objects referencing a backend in another namespace, if the
322
+ ReferenceGrant is deleted, the backend will become invalid (since the target
323
+ can't be found). If there was more than one backend, then the valid parts of the
324
+ HTTPRoute's config would persist in the data plane.
325
+
326
+ But in this case, the cross-namespace reference is the _only_ backend, so the
327
+ removal of the ReferenceGrant will also result in the removal of the HTTPRoute's
328
+ config from the data plane.
329
+ # ### PersistentVolumeClaim using cross namespace data source
330
+
331
+ This example is taken from https://kubernetes.io/blog/2023/01/02/cross-namespace-data-sources-alpha/
332
+ and updated to use the proposed new spec.
333
+
334
+ It allows the PersistentVolumeClaim in the `dev` namespace to use a volume
335
+ snapshot from the `prod` namespace as its data source.
336
+
337
+ ` ` ` yaml
338
+ apiVersion: v1
339
+ kind: PersistentVolumeClaim
340
+ metadata:
341
+ name: example-pvc
342
+ namespace: dev
343
+ spec:
344
+ storageClassName: example
345
+ accessModes:
346
+ - ReadWriteOnce
347
+ resources:
348
+ requests:
349
+ storage: 1Gi
350
+ dataSourceRef:
351
+ apiGroup: snapshot.storage.k8s.io
352
+ kind: VolumeSnapshot
353
+ name: new-snapshot-demo
354
+ namespace: prod
355
+ volumeMode: Filesystem
356
+ ---
357
+ apiVersion: authorization.k8s.io/v1alpha1
358
+ kind: ReferenceGrant
359
+ metadata:
360
+ name: allow-prod-pvc
361
+ namespace: prod
362
+ spec:
363
+ from:
364
+ - resource: persistentvolumeclaims
365
+ namespace: dev
366
+ to:
367
+ - group: snapshot.storage.k8s.io
368
+ resource: volumesnapshots
369
+ name: new-snapshot-demo
370
+ ` ` `
165
371
166
- With all of that in mind, we felt that the benefits in terms of specificity
167
- outweighed the costs in terms of user pain to use the more correct ` Resource ` .
372
+ At time of writing, I'm not sure about the behavior here when the ReferenceGrant
373
+ is deleted .
168
374
169
375
# ## API Spec
170
376
@@ -216,10 +422,10 @@ type ReferenceGrantSpec struct {
216
422
// +kubebuilder:validation:MaxItems=16
217
423
From []ReferenceGrantFrom `json:"from"`
218
424
219
- // To describes the resources that may be referenced by the resources
220
- // described in "From". Each entry in this list MUST be considered to be an
221
- // additional place that references can be valid to, or to put this another
222
- // way, entries MUST be combined using OR.
425
+ // To describes the resources in this namespace that may be referenced by
426
+ // the resources described in "From". Each entry in this list MUST be
427
+ // considered to be an additional set of objects that references can be
428
+ // valid to, or to put this another way, entries MUST be combined using OR.
223
429
//
224
430
// +kubebuilder:validation:MinItems=1
225
431
// +kubebuilder:validation:MaxItems=16
@@ -232,8 +438,8 @@ type ReferenceGrantFrom struct {
232
438
// When empty, the Kubernetes core API group is inferred.
233
439
Group Group `json:"group"`
234
440
235
- // Kind is the kind of the referent.
236
- Kind string ` json:"kind "`
441
+ // Kind is the resource of the referent.
442
+ Resource string `json:"resource "`
237
443
238
444
// Namespace is the namespace of the referent.
239
445
Namespace string `json:"namespace"`
@@ -246,8 +452,8 @@ type ReferenceGrantTo struct {
246
452
// When empty, the Kubernetes core API group is inferred.
247
453
Group string `json:"group"`
248
454
249
- // Kind is the kind of the referent.
250
- Kind string ` json:"kind "`
455
+ // Kind is the resource of the referent.
456
+ Resource string `json:"resource "`
251
457
252
458
// Name is the name of the referent. When unspecified, this policy
253
459
// refers to all resources of the specified Group and Kind in the local
@@ -262,9 +468,8 @@ type ReferenceGrantTo struct {
262
468
263
469
This section lists some of the outstanding questions people have had about
264
470
ReferenceGrant, and other items that we'll be clarifying in the godoc and other
265
- documentation as part of the transition to the new API group, keeping in mind
266
- that we will not be adding any new features, fields, or behavior, just clarifying
267
- what's done already.
471
+ documentation as part of the transition to the new API group, along with any
472
+ other changes we need to make that aren't already reflected in this document.
268
473
269
474
Also note that we don't consider any of these blockers for the general _ idea_ of
270
475
moving ReferenceGrant to the new API group, just notes to save discussion time.
0 commit comments