You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: geps/gep-3779/index.md
+252-1Lines changed: 252 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -246,10 +246,261 @@ Cilium has the concept of CiliumIdentity. Pods are assigned identities derived f
246
246
More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/
247
247
248
248
249
-
250
249
## API
251
250
251
+
This GEP introduces a new policy resource, `AuthorizationPolicy`, for **identity-based** authorization. The policy defines a target, a single action (`ALLOW` or `DENY`), and a set of rules that include sources (the “who”) and an optional port attribute.
252
+
253
+
### **Policy Rules**
254
+
255
+
Each `AuthorizationPolicy` resource contains a list of rules. A request matches the policy if it matches **any** rule in the list (logical OR). Each rule defines multiple matching criteria; a request matches a rule only if it matches **all** criteria within that rule (logical AND).
256
+
257
+
A rule may specify:
258
+
259
+
***Sources:** The source identities to which the rule applies. A request’s identity must match one of the listed sources. Supported source kinds are:
260
+
***SPIFFE ID**
261
+
***Kubernetes ServiceAccount**
262
+
***Kubernetes Namespace**
263
+
***Attributes:** Conditions on the target workload, at the time of writing this, only port is supported. If no attributes are specified, the rule applies to all traffic toward the target.
264
+
265
+
### **ALLOW Policies**
266
+
267
+
* An **ALLOW** policy is permissive.
268
+
* A request is allowed if:
269
+
* It matches at least one rule in any ALLOW policy targeting the workload **and**
270
+
* It is not explicitly denied by any DENY policy.
271
+
* If no ALLOW policy exists for a workload, traffic is permitted by default, unless any DENY policy applies.
272
+
273
+
### **DENY Policies**
274
+
275
+
* A **DENY** policy is restrictive and takes precedence over ALLOW.
276
+
* If a request matches any rule in a DENY policy, it is immediately rejected, regardless of matching ALLOW rules elsewhere.
277
+
* DENY policies enable to define global blocks or exceptions (for example: “block all traffic from Namespace X”).
278
+
279
+
### **ALLOW vs. DENY Semantics**
280
+
281
+
***DENY always wins.** If both an ALLOW and a DENY policy match a request, the DENY policy blocks it.
282
+
* The presence of any authorization policy causes the system to default to **deny-by-default** for matching workloads.
283
+
* Another bullet to re-clarify the one above - the default behavior when no policies select a target workload is to allow all traffic. However, **as soon as at least one `AuthorizationPolicy` targets a workload, the model becomes implicitly deny-if-not-allowed**.
284
+
285
+
### **Target of Authorization**
286
+
287
+
The `targetRef` of the policy specifies the workload(s) to which the policy applies. Two options are available for `targetRef`:
288
+
289
+
#### **Option 1: Targeting a Service**
290
+
291
+
The `targetRef` can point to a Kubernetes `Service`.
292
+
293
+
**Benefits:**
294
+
295
+
***No API Extension Required:** Works with the current PolicyAttachment model in Gateway API without modification.
296
+
***Simplicity:** Intuitive for users familiar with Kubernetes networking concepts.
297
+
298
+
**Downsides and Open Questions:**
299
+
300
+
However, targeting a `Service` introduces several challenges:
301
+
302
+
1. Authorization cannot be enforced on workloads not exposed via a `Service` - excluding use cases of pods/jobs without a Service.
303
+
2. If a Pod belongs to multiple Services targeted by different authorization policies, precedence rules, may become unclear, leading to unpredictable or insecure outcomes. Even if such rules are explicitly defined, UX could potentially be confusing for users.
304
+
3. UX and implementation challenges - are implementations expected to enforce the policy only if the traffic arrived through the specific Service? Or just to take the service selectors and enforce the policy regardless of how the traffic got to the destination?
305
+
306
+
#### **Option 2: Targeting Pods via Label Selectors**
307
+
308
+
Alternatively, the `targetRef` can specify a set of pods using a `LabelSelector` for a more flexible and direct approach.
309
+
310
+
**Benefits:**
311
+
312
+
* Aligns with established practices. Mesh implementations (Istio, Linkerd, Cilium) already use label selectors as the primary mechanism for targeting workloads in their native authorization policies, creating a consistent user experience.
313
+
* Directly applies policy to pods, avoiding ambiguity present when targeting services. Ensures policies are enforced exactly where intended, regardless of how many services a pod might belong to.
314
+
* Policies can apply to any workload, including pods not exposed via a `Service`, providing a comprehensive authorization solution.
315
+
316
+
**Downsides and Open Questions:**
317
+
318
+
The main downside of `LabelSelector` is the huge increase to the complexity of policy discoverability. See below for more info.
319
+
320
+
**Requirement: Enhancing Policy Attachment:**
321
+
322
+
This option depends on enhancements to Gateway API’s policy attachment model to support `LabelSelector` as a valid `targetRef`. This capability was discussed and received consensus at KubeCon North America 2024 and was originally in scope for GEP-713 but deferred for a future PR to keep GEP-713 focused on stabilizing what we already have (See [https://github.com/kubernetes-sigs/gateway-api/pull/3609#discussion_r2053376938](https://github.com/kubernetes-sigs/gateway-api/pull/3609#discussion_r2053376938)).
323
+
324
+
##### **Experimental Pattern**
325
+
326
+
To mitigate some of the concerns, `LabelSelector` support in policy attachment is designated as an **experimental pattern**.
327
+
328
+
***Gateway API Community First:** Allows experimentation within Gateway API policies (like the one in this GEP).
329
+
* Implementations **should not** adopt `LabelSelector` targeting in their own custom policies attached to Gateway API resources until the pattern is sufficiently battle-tested and promoted to a standard feature. This staged approach mitigates risks of ecosystem fragmentation.
330
+
331
+
Here is how it is going to look like:
332
+
333
+
```go
334
+
335
+
// PolicyTargetReferenceWithLabelSelectors specifies a reference to a set of Kubernetes
336
+
// objects by Group and Kind, with an optional label selector to narrow down the matching
337
+
// objects.
338
+
//
339
+
// Currently, we only support label selectors when targeting Pods.
340
+
// This restriction is intentional to limit the complexity and potential
341
+
// ambiguity of supporting label selectors for arbitrary Kubernetes kinds.
342
+
// Unless there is a very strong justification in the future, we plan to keep this
343
+
// functionality limited to selecting Pods only.
344
+
//
345
+
// This is currently experimental in the Gateway API and should only be used
346
+
// for policies implemented within Gateway API. It is currently not intended for general-purpose
347
+
// use outside of Gateway API resources.
348
+
// +kubebuilder:validation:XValidation:rule="!(has(self.selector)) || (self.kind == 'Pod' && (self.group == '' || self.group == 'core'))",message="Selector may only be set when targeting Pods."
// Selector is the label selector of target objects of the specified kind.
357
+
Selector *metav1.LabelSelector`json:"selector"`
358
+
}
359
+
360
+
```
361
+
362
+
##### **Enhanced Discoverability with `gwctl`**
363
+
364
+
A key challenge with `LabelSelector` is the loss of discoverability. It’s easier to see which policies target a `Service` but difficult to determine which policies might affect a specific pod.
365
+
366
+
To address this, **investment in tooling is required.** Specifically, the `gwctl` CLI tool should be enhanced to provide insights such as:
367
+
368
+
```sh
369
+
TODO: complete gwctl commands
370
+
```
371
+
372
+
Without dedicated tooling, the `LabelSelector` approach could significantly degrade the user experience and observability.
373
+
374
+
### API Design
375
+
376
+
```go
377
+
378
+
typeAuthorizationPolicystruct {
379
+
metav1.TypeMeta`json:",inline"`
380
+
metav1.ObjectMeta`json:"metadata,omitempty"`
381
+
382
+
// Spec defines the desired state of AuthorizationPolicy.
Note: Existing AuthorizationAPIs recognized the need to support negation fields like `not{field}`. To avoid duplicating fields with negation, we plan to support richer match expressions for fields in `AuthorizationSource` such as `matchExpressions: { operator: In|NotIn, values: []}`.
0 commit comments