From 6d01319020c45516e0c1d822fe7475994cda45d1 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Wed, 28 May 2025 13:30:47 -0700 Subject: [PATCH 01/11] add draft authz gep e/w --- geps/gep-3779/index.md | 85 +++++++++++++++++++++++++++++++++++++ geps/gep-3779/metadata.yaml | 19 +++++++++ 2 files changed, 104 insertions(+) create mode 100644 geps/gep-3779/index.md create mode 100644 geps/gep-3779/metadata.yaml diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md new file mode 100644 index 0000000000..2032c1b9cf --- /dev/null +++ b/geps/gep-3779/index.md @@ -0,0 +1,85 @@ +# GEP-3779: Identity Based Authz for East-West Traffic + +* Issue: [#3779](https://github.com/kubernetes-sigs/gateway-api/issues/3779) +* Status: Provisional + +(See [status definitions](../overview.md#gep-states).) + + +## TLDR + +Provide a method for configuring Gateway API Mesh implementations to enforce east-west identity-based Authorization controls. At the time of writing this we leave Authentication for specific implementation and outside of this proposal scope. + + +## Goals + +(Using the [Gateway API Personas](../../concepts/roles-and-personas.md)) + +* A way for Ana the Application Developer to configure a Gateway API for Mesh implementation to enforce authorization policy that **allows** or **denies** identity or multiple identities to talk with some set of the workloads she controls. + +* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce non-overridable cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. + +* A way for both Ana and Chihiro to restrict the scope of the policies they deploy to specific ports. + +## Stretch Goals + +* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce default, overridable, cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. + +## Non-Goals + +* Support identity based authorization for north-south traffic or define the composition with this API. + +## Deferred Goals + +* (Potentially) Support enforcement on attributes beyond identities and ports. + +## Introduction + +Authorization is positioned as one of core mesh values. Every mesh supports some kind of east/west authorization between the workloads it controls. + +Kubernetes core provides NetworkPolicies as one way to do it. Network Policies however falls short in many ways including: + +* Network policies leverage labels as identities. + * Labels are mutable at runtime. This opens a path for escalating privileges + * Most implementations of network policies translate labels to IPs, this involves an eventual consistency nature which can and has lea to over permissiveness in the past. + +* Scale. Network Policies are enforced using IPs (different selectors in the APIs get translated to IPs). This does not scale well with large clusters or beyond a single cluster + +An identity-based authorization API is essential because it provides a structured way to control authorization between identities within the cluster. + +### State of the World + +Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: + + + +#### Istio + + +#### Linkerd + + +#### Cilium + + + +## Outstanding Questions and Concerns (TODO) + + +## API + + + +## Conformance Details + + +#### Feature Names + + +### Conformance tests + + +## Alternatives + + +## References \ No newline at end of file diff --git a/geps/gep-3779/metadata.yaml b/geps/gep-3779/metadata.yaml new file mode 100644 index 0000000000..0d28d1cd31 --- /dev/null +++ b/geps/gep-3779/metadata.yaml @@ -0,0 +1,19 @@ +apiVersion: internal.gateway.networking.k8s.io/v1alpha1 +kind: GEPDetails +number: 3779 +name: Identity Based Authz for east-west traffic +status: Provisional +# Any authors who contribute to the GEP in any way should be listed here using +# their GitHub handle. +authors: + - liorlieberman + - aryan16 +# references is a list of hyperlinks to relevant external references. +# It's intended to be used for storing GitHub discussions, Google docs, etc. +references: {} +# featureNames is a list of the feature names introduced by the GEP, if there +# are any. This will allow us to track which feature was introduced by which GEP. +featureNames: {} +# changelog is a list of hyperlinks to PRs that make changes to the GEP, in +# ascending date order. +changelog: {} \ No newline at end of file From 95898f1a3969f21c7946de0f3ca63a94af2121b1 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Thu, 29 May 2025 13:20:54 -0700 Subject: [PATCH 02/11] add a table --- geps/gep-3779/index.md | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 2032c1b9cf..49978a5804 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -49,22 +49,33 @@ An identity-based authorization API is essential because it provides a structure ### State of the World -Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: - +| Aspect | Istio | Linkerd | Cilium | +| ----- | ----- | ----- | ----- | +| **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy`(`cilium.io/v2`) (superset of K8s NetworkPolicy) | +| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
| TODO(liorlieberman) | +| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | TODO(liorlieberman) | +| **Request Match criteria** | Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc., plus source identity (namespace, service account). Policies use logical OR over rules.

All match criterias are inline in the policy. See [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To) and [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when) | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | TODO(liorlieberamn) | +| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | TODO(liorlieberman)| +| **YAML Configuration** | Istio `AuthorizationPolicy` CRD. E.g., to **allow** a namespace or service-account to call a service: | | | -#### Istio +Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: -#### Linkerd +#### Istio +Link: [Istio authorization policy docs](https://istio.io/latest/docs/reference/config/security/authorization-policy/) +TODO -#### Cilium +#### Linkerd +Link: [Linkerd authorization policy docs](https://linkerd.io/2-edge/reference/authorization-policy/) +TODO -## Outstanding Questions and Concerns (TODO) +#### Cilium +TODO ## API From d6cc7331796a2dc42da6ff0b94de9305cc4b59cc Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Thu, 29 May 2025 13:22:25 -0700 Subject: [PATCH 03/11] fix --- geps/gep-3779/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 49978a5804..8b67ef10c0 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -57,7 +57,6 @@ An identity-based authorization API is essential because it provides a structure | **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | TODO(liorlieberman) | | **Request Match criteria** | Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc., plus source identity (namespace, service account). Policies use logical OR over rules.

All match criterias are inline in the policy. See [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To) and [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when) | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | TODO(liorlieberamn) | | **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | TODO(liorlieberman)| -| **YAML Configuration** | Istio `AuthorizationPolicy` CRD. E.g., to **allow** a namespace or service-account to call a service: | | | Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: From 78d0656d45f7050d9adea015ba09dc9a5d1fbdcf Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Fri, 30 May 2025 17:39:14 -0700 Subject: [PATCH 04/11] add cilium content --- geps/gep-3779/index.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 8b67ef10c0..fe8a336185 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -52,11 +52,11 @@ An identity-based authorization API is essential because it provides a structure | Aspect | Istio | Linkerd | Cilium | | ----- | ----- | ----- | ----- | -| **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy`(`cilium.io/v2`) (superset of K8s NetworkPolicy) | -| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
| TODO(liorlieberman) | -| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | TODO(liorlieberman) | -| **Request Match criteria** | Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc., plus source identity (namespace, service account). Policies use logical OR over rules.

All match criterias are inline in the policy. See [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To) and [https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when](https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when) | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | TODO(liorlieberamn) | -| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | TODO(liorlieberman)| +| **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy` (superset of K8s NetworkPolicy) | +| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
|Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity).

Policies only target abstractions like label selectors, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based).| +| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | For L3/4 Ingress Rules, CiliumNetworkPolicy enforcement - an eBPF-based datapath in the Linux kernel on the destination node. If L7 http rules are specified, the packet is redirected for a node-local envoy for further enforcement.

Cilium service mesh also offers a kind of AuthN where a Cilium agent on the src node, is talking to another agent on the destination node, using the pod’s spiffee identities.| +| **Request Match criteria** | Policies can target a group of pods using label selector, a Gateway/Service (this means targeting a waypoint proxy) or a GatewayClass - meaning all the gateways created from this class. Policies without a label selector in a namespace implies the whole namespace is targeted.

Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc.Policies use logical OR over rules.

All match criterias are inline in the policy. See https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To and https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | Policies can target groups of pods using label selector (`endpointSelector`), or by node-labels (`nodeSelector`). Cilium supports L7 via built-in HTTP parsing: rules can match HTTP methods, paths, Kafka, etc. For example, a CiliumNetworkPolicy can allow only specific HTTP methods/paths on a port. | +| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Operators must apply explicit deny rules or “default-deny” policies to block traffic.

`CiliumClusterwideNetworkPolicy` exists for admin enforcement.)| Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: @@ -74,7 +74,11 @@ TODO #### Cilium -TODO +##### CiliumIdentity +Cilium has the concept of CiliumIdentity. Pods are assigned identities derived from their Kubernetes labels (namespace, app labels, etc.). Cilium’s policy matches based on these label-derived identities. The CiliumIdentity implementation maps an integer to a group of IP addresses (the pod IPs associated with a group of pods). This “integer” and its mapping to pod IP addresses represents the core identity primitive in Cilium. + +More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/ + ## API From 7efee8312cabfc9f5e3e45bbf9319029718a25ce Mon Sep 17 00:00:00 2001 From: Aryan Gupta Date: Tue, 3 Jun 2025 07:53:47 +0000 Subject: [PATCH 05/11] add all mesh authz model --- geps/gep-3779/index.md | 149 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index fe8a336185..d8ac657e29 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -53,7 +53,7 @@ An identity-based authorization API is essential because it provides a structure | Aspect | Istio | Linkerd | Cilium | | ----- | ----- | ----- | ----- | | **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy` (superset of K8s NetworkPolicy) | -| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
|Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity).

Policies only target abstractions like label selectors, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based).| +| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
|Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity).

Policies target abstractions like service accounts in the form of labels, pod labels, namespace label, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based).| | **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | For L3/4 Ingress Rules, CiliumNetworkPolicy enforcement - an eBPF-based datapath in the Linux kernel on the destination node. If L7 http rules are specified, the packet is redirected for a node-local envoy for further enforcement.

Cilium service mesh also offers a kind of AuthN where a Cilium agent on the src node, is talking to another agent on the destination node, using the pod’s spiffee identities.| | **Request Match criteria** | Policies can target a group of pods using label selector, a Gateway/Service (this means targeting a waypoint proxy) or a GatewayClass - meaning all the gateways created from this class. Policies without a label selector in a namespace implies the whole namespace is targeted.

Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc.Policies use logical OR over rules.

All match criterias are inline in the policy. See https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To and https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | Policies can target groups of pods using label selector (`endpointSelector`), or by node-labels (`nodeSelector`). Cilium supports L7 via built-in HTTP parsing: rules can match HTTP methods, paths, Kafka, etc. For example, a CiliumNetworkPolicy can allow only specific HTTP methods/paths on a port. | | **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Operators must apply explicit deny rules or “default-deny” policies to block traffic.

`CiliumClusterwideNetworkPolicy` exists for admin enforcement.)| @@ -64,13 +64,127 @@ Every mesh vendor has their own API of such authorization. Below we describe the #### Istio Link: [Istio authorization policy docs](https://istio.io/latest/docs/reference/config/security/authorization-policy/) -TODO +Istio's AuthorizationPolicy can enforce access control by specifying allowed identities using the `source.principals` field, which matches authenticated service account identities via mTLS. + +``` +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: allow-sleep + namespace: default +spec: + selector: + matchLabels: + app: httpbin # The policy applies to pods with this label + action: ALLOW + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/sleep"] +``` #### Linkerd Link: [Linkerd authorization policy docs](https://linkerd.io/2-edge/reference/authorization-policy/) -TODO +In Linkerd, identity-based authorization is enforced using AuthorizationPolicy and MeshTLSAuthentication, where MeshTLSAuthentication specifies allowed mTLS identities (e.g., sleep.default.serviceaccount.identity.linkerd.cluster.local), ensuring that only authenticated workloads can access a resource. + +Linkerd Policy can by applied to two different targets. + +##### Pod Labels with Server Resource + +``` +apiVersion: policy.linkerd.io/v1beta1 +kind: Server +metadata: + namespace: default + name: httpbin-server +spec: + podSelector: + matchLabels: + app: httpbin + port: 8080 + proxyProtocol: HTTP/2 + +---- +apiVersion: policy.linkerd.io/v1beta1 +kind: MeshTLSAuthentication +metadata: + name: sleep-authn + namespace: default +spec: + identities: + - sleep.default.serviceaccount.identity.linkerd.cluster.local +---- + +apiVersion: policy.linkerd.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: allow-sleep + namespace: default +spec: + targetRef: + group: policy.linkerd.io + kind: Server + name: httpbin-server + requiredAuthenticationRefs: + - name: sleep-authn + kind: MeshTLSAuthentication + group: policy.linkerd.io/v1beta1 + +--- +``` + +##### HTTPRoutes + +``` +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: httpbin-route + namespace: default +spec: + parentRefs: + - name: httpbin + kind: Service + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: httpbin + port: 80 + +----- + +apiVersion: policy.linkerd.io/v1beta1 +kind: MeshTLSAuthentication +metadata: + name: sleep-authn + namespace: default +spec: + identities: + - sleep.default.serviceaccount.identity.linkerd.cluster.local +----- + +apiVersion: policy.linkerd.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: allow-sleep-http + namespace: default +spec: + targetRef: + group: gateway.networking.k8s.io + kind: HTTPRoute + name: httpbin-route + requiredAuthenticationRefs: + - name: sleep-authn + kind: MeshTLSAuthentication + group: policy.linkerd.io/v1beta1 +--- +``` + #### Cilium @@ -79,6 +193,35 @@ Cilium has the concept of CiliumIdentity. Pods are assigned identities derived f More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/ +Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls + +[ServiceAccounts Based Identities](https://docs.cilium.io/en/latest/security/policy/kubernetes/#serviceaccounts) + +Following the CiliumNetworkPolicy for client identities. + +``` +apiVersion: "cilium.io/v2" +kind: CiliumNetworkPolicy +metadata: + name: "k8s-svc-account-policy" +spec: + endpointSelector: + matchLabels: + io.cilium.k8s.policy.serviceaccount: httpbin + ingress: + - fromEndpoints: + - matchLabels: + io.cilium.k8s.policy.serviceaccount: sleep + toPorts: + - ports: + - port: '80' + protocol: TCP + rules: + http: + - method: GET + path: "/" +``` + ## API From 28ef78042fee19ec92c390bd02fd431d35719562 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Wed, 4 Jun 2025 13:22:31 -0700 Subject: [PATCH 06/11] small nits --- geps/gep-3779/index.md | 43 +++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index d8ac657e29..809198ff72 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -59,12 +59,12 @@ An identity-based authorization API is essential because it provides a structure | **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Operators must apply explicit deny rules or “default-deny” policies to block traffic.

`CiliumClusterwideNetworkPolicy` exists for admin enforcement.)| -Every mesh vendor has their own API of such authorization. Below we describe the UX for different implementations: +Every mesh vendor has their own API of such authorization. Below we describe brief UX for different implementations: #### Istio -Link: [Istio authorization policy docs](https://istio.io/latest/docs/reference/config/security/authorization-policy/) +For the full spec and sematics of Istio AuthorizationPolicy: [Istio authorization policy docs](https://istio.io/latest/docs/reference/config/security/authorization-policy/) -Istio's AuthorizationPolicy can enforce access control by specifying allowed identities using the `source.principals` field, which matches authenticated service account identities via mTLS. +Istio's AuthorizationPolicy can enforce access control by specifying allowed istio-formatted identities using the `source.principals` field, which matches authenticated service account identities via mTLS. You can also use other source constructs which are described in the table above and in https://istio.io/latest/docs/reference/config/security/authorization-policy/#Source. ``` apiVersion: security.istio.io/v1beta1 @@ -83,11 +83,30 @@ spec: principals: ["cluster.local/ns/default/sa/sleep"] ``` +OR targeting a gateway for example. + +``` +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: allow-sleep + namespace: default +spec: + targetRefs: + - name: waypoint + kind: Gateway # note: supported target Refs are Gateway, GatewayClass, Service, and ServiceEntry + group: gateway.networking.k8s.io + action: ALLOW + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/sleep"] +``` #### Linkerd -Link: [Linkerd authorization policy docs](https://linkerd.io/2-edge/reference/authorization-policy/) +For the full spec and sematics of Linkerd AuthorizationPolicy: [Linkerd authorization policy docs](https://linkerd.io/2-edge/reference/authorization-policy/) -In Linkerd, identity-based authorization is enforced using AuthorizationPolicy and MeshTLSAuthentication, where MeshTLSAuthentication specifies allowed mTLS identities (e.g., sleep.default.serviceaccount.identity.linkerd.cluster.local), ensuring that only authenticated workloads can access a resource. +In Linkerd, identity-based authorization is enforced using AuthorizationPolicy and MeshTLSAuthentication, where MeshTLSAuthentication specifies allowed ServiceAccounts or mTLS identities (e.g., sleep.default.serviceaccount.identity.linkerd.cluster.local), ensuring that only authenticated workloads can access a resource. Linkerd Policy can by applied to two different targets. @@ -188,12 +207,7 @@ spec: #### Cilium -##### CiliumIdentity -Cilium has the concept of CiliumIdentity. Pods are assigned identities derived from their Kubernetes labels (namespace, app labels, etc.). Cilium’s policy matches based on these label-derived identities. The CiliumIdentity implementation maps an integer to a group of IP addresses (the pod IPs associated with a group of pods). This “integer” and its mapping to pod IP addresses represents the core identity primitive in Cilium. - -More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/ - -Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls +Beyond what's explained in the table above, Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls [ServiceAccounts Based Identities](https://docs.cilium.io/en/latest/security/policy/kubernetes/#serviceaccounts) @@ -223,6 +237,13 @@ spec: ``` +##### CiliumIdentity +Cilium has the concept of CiliumIdentity. Pods are assigned identities derived from their Kubernetes labels (namespace, app labels, etc.). Cilium’s policy matches based on these label-derived identities. The CiliumIdentity implementation maps an integer to a group of IP addresses (the pod IPs associated with a group of pods). This “integer” and its mapping to pod IP addresses represents the core identity primitive in Cilium. + +More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/ + + + ## API From a24456473d744b90d6304d6c638926a5aee779a6 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Wed, 4 Jun 2025 13:32:17 -0700 Subject: [PATCH 07/11] fix --- geps/gep-3779/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 809198ff72..1527ffd3ae 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -207,11 +207,11 @@ spec: #### Cilium -Beyond what's explained in the table above, Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls +For the full spec and sematics of CiliumNetworkPolicy: https://docs.cilium.io/en/stable/network/kubernetes/policy/#ciliumnetworkpolicy & https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/#cilium-s-ingress-config-and-ciliumnetworkpolicy -[ServiceAccounts Based Identities](https://docs.cilium.io/en/latest/security/policy/kubernetes/#serviceaccounts) +Beyond what's explained in the table above, Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls using [ServiceAccounts Based Identities](https://docs.cilium.io/en/latest/security/policy/kubernetes/#serviceaccounts) within CiliumNetworkPolicy; -Following the CiliumNetworkPolicy for client identities. +See below for example. ``` apiVersion: "cilium.io/v2" From f384d15d1c89d87b27c06123ce8f2c84db3e9413 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Wed, 4 Jun 2025 13:53:07 -0700 Subject: [PATCH 08/11] newline --- geps/gep-3779/metadata.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geps/gep-3779/metadata.yaml b/geps/gep-3779/metadata.yaml index 0d28d1cd31..3c5b9af7d2 100644 --- a/geps/gep-3779/metadata.yaml +++ b/geps/gep-3779/metadata.yaml @@ -16,4 +16,4 @@ references: {} featureNames: {} # changelog is a list of hyperlinks to PRs that make changes to the GEP, in # ascending date order. -changelog: {} \ No newline at end of file +changelog: {} From 9d892eebc15234adfb38ac4b37c932dd6a94de84 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Fri, 13 Jun 2025 06:58:34 -0700 Subject: [PATCH 09/11] Apply suggestions from code review Co-authored-by: Nick Young --- geps/gep-3779/index.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 1527ffd3ae..b4533f4457 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -53,10 +53,11 @@ An identity-based authorization API is essential because it provides a structure | Aspect | Istio | Linkerd | Cilium | | ----- | ----- | ----- | ----- | | **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy` (superset of K8s NetworkPolicy) | -| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
|Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity).

Policies target abstractions like service accounts in the form of labels, pod labels, namespace label, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based).| -| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | For L3/4 Ingress Rules, CiliumNetworkPolicy enforcement - an eBPF-based datapath in the Linux kernel on the destination node. If L7 http rules are specified, the packet is redirected for a node-local envoy for further enforcement.

Cilium service mesh also offers a kind of AuthN where a Cilium agent on the src node, is talking to another agent on the destination node, using the pod’s spiffee identities.| -| **Request Match criteria** | Policies can target a group of pods using label selector, a Gateway/Service (this means targeting a waypoint proxy) or a GatewayClass - meaning all the gateways created from this class. Policies without a label selector in a namespace implies the whole namespace is targeted.

Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc.Policies use logical OR over rules.

All match criterias are inline in the policy. See https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To and https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | Policies can target groups of pods using label selector (`endpointSelector`), or by node-labels (`nodeSelector`). Cilium supports L7 via built-in HTTP parsing: rules can match HTTP methods, paths, Kafka, etc. For example, a CiliumNetworkPolicy can allow only specific HTTP methods/paths on a port. | -| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Operators must apply explicit deny rules or “default-deny” policies to block traffic.

`CiliumClusterwideNetworkPolicy` exists for admin enforcement.)| +| **Identity model** | Identities derived from mTLS peer certificates (bound to SA):
  • SPIFFE-like principal `/ns//sa/`.
  • ServiceAccount name
  • Namespaces

identity within JWT derived from `request.auth.principal`

IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`).

Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include:
  • ServiceAccounts
  • `MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts
  • `NetworkAuthentication` - represents sets of IPs or subnets.
|Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity).

Policies target abstractions like service accounts in the form of labels, pod labels, namespace label, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based). All policy targeting is coalesced by Cilium into one or more Cilium Identities for translation into the BPF datapath| +| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any.

Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks.

Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | For L3/4 Ingress Rules, CiliumNetworkPolicy enforcement - an eBPF-based datapath in the Linux kernel on the destination node. If L7 http rules are specified, the packet is redirected for a node-local envoy for further enforcement.

Cilium supports ALLOW and DENY semantics - all policies generate audit logs.

Cilium service mesh also offers a kind of AuthN where a Cilium agent on the src node validates a workloads SPIFFE identity by talking to another agent on the destination node, performing the initial TLS handshake to do authentication.| +| **Request Match criteria** | Policies can target a group of pods using label selector, a Gateway/Service (this means targeting a waypoint proxy) or a GatewayClass - meaning all the gateways created from this class. Policies without a label selector in a namespace implies the whole namespace is targeted.

Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc.Policies use logical OR over rules.

All match criterias are inline in the policy. See https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To and https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when | Policies can target:
  • A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.
  • A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)
  • A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.
Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website) | Policies can target groups of pods using label selector (`endpointSelector`), or by node-labels (`nodeSelector`). Cilium supports L7 via built-in HTTP parsing: rules can match HTTP methods, paths, etc. For example, a CiliumNetworkPolicy can allow only specific HTTP methods/paths on a port. | +| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system

AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies. | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are:
  • `all-unauthenticated:` allow all traffic. This is the default.
  • `all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).
  • `cluster-authenticated:` allow traffic from meshed clients in the same cluster.
  • `cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.
  • `deny:` all traffic are denied.
  • `audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.

Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Once at least one `CiliumNetworkPolicy` or `CiliumClusterwideNetworkPolicy` allows some traffic, all other traffic is implicitly denied. +

Operators must apply explicit deny rules or “default-deny” policies to block traffic in the absence of allow rules.

`CiliumClusterwideNetworkPolicy` exists for whole-cluster enforcement.)| Every mesh vendor has their own API of such authorization. Below we describe brief UX for different implementations: From c2dcf172b8de887165e4ca76e6004a0623e36611 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Mon, 16 Jun 2025 14:28:44 -0700 Subject: [PATCH 10/11] move cluster-admin non-overridable case to stretch goals --- geps/gep-3779/index.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index b4533f4457..3d3df25a3b 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -15,14 +15,14 @@ Provide a method for configuring Gateway API Mesh implementations to enforce eas (Using the [Gateway API Personas](../../concepts/roles-and-personas.md)) -* A way for Ana the Application Developer to configure a Gateway API for Mesh implementation to enforce authorization policy that **allows** or **denies** identity or multiple identities to talk with some set of the workloads she controls. - -* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce non-overridable cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. +* A way for Ana the Application Developer to configure a Gateway API for Mesh implementation to enforce authorization policy that **allows** or **denies** identity or multiple identities to talk with some set (could be namespace or more granualr) of the workloads she controls. * A way for both Ana and Chihiro to restrict the scope of the policies they deploy to specific ports. ## Stretch Goals +* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce non-overridable cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. + * A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce default, overridable, cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. ## Non-Goals @@ -33,6 +33,7 @@ Provide a method for configuring Gateway API Mesh implementations to enforce eas * (Potentially) Support enforcement on attributes beyond identities and ports. + ## Introduction Authorization is positioned as one of core mesh values. Every mesh supports some kind of east/west authorization between the workloads it controls. From 487896006444864c7c10ad3d97cec47cb583d322 Mon Sep 17 00:00:00 2001 From: Lior Lieberman Date: Tue, 17 Jun 2025 10:04:18 -0700 Subject: [PATCH 11/11] change stretch to tbd --- geps/gep-3779/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md index 3d3df25a3b..49464b16d6 100644 --- a/geps/gep-3779/index.md +++ b/geps/gep-3779/index.md @@ -19,7 +19,7 @@ Provide a method for configuring Gateway API Mesh implementations to enforce eas * A way for both Ana and Chihiro to restrict the scope of the policies they deploy to specific ports. -## Stretch Goals +## TBD Goals * A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce non-overridable cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster. @@ -48,6 +48,7 @@ Kubernetes core provides NetworkPolicies as one way to do it. Network Policies h An identity-based authorization API is essential because it provides a structured way to control authorization between identities within the cluster. + ### State of the World