Authorization policies with ztunnel

Authorization policies with ztunnel

The ztunnel proxy can enforce authorization policy. Because these proxies only operate at Layer 4 (L4), only the L4 features of Istio’s authorization policies are supported.

A waypoint proxy can enforce both L4 and Layer 7 (L7) policy. There are considerations as to where you should apply L4 policy when you have waypoints deployed for a workload.

Kubernetes network policies also continue to work if your cluster has a CNI plugin that supports them, and can be used to provide defense-in-depth.

Policy enforcement using ztunnel

The ztunnel proxy can perform authorization policy enforcement when a workload is enrolled in secure overlay mode. The enforcement point is the receiving (server-side) ztunnel proxy in the path of a connection.

The policy enforcement point is the destination ztunnel.

The policy enforcement point is the destination ztunnel.

A basic L4 authorization policy looks like this:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: allow-curl-to-httpbin
 namespace: default
spec:
 selector:
   matchLabels:
     app: httpbin
 action: ALLOW
 rules:
 - from:
   - source:
       principals:
       - cluster.local/ns/ambient-demo/sa/curl

When there is no authorization policy provisioned, the default action is ALLOW. Once a policy is provisioned, pods targeted by the policy only permit traffic which is explicitly allowed. In the above example, pods with the label app: httpbin in the default namespace only permit traffic from sources with an identity principal of cluster.local/ns/ambient-demo/sa/curl. Traffic from all other sources will be denied.

You can check the status field of the policy object to confirm it has been attached:

status:
  conditions:
  - lastTransitionTime: "2024-12-13T08:22:40.876269340Z"
    message: attached to ztunnel
    reason: Accepted
    status: "True"
    type: ZtunnelAccepted

Targeting policies

The scope of an authorization policy is determined by the namespace in which the policy object resides, and an optional selector1. If the policy is in the Istio root namespace (traditionally istio-system), then it will target all namespaces. If it is in any other namespace, it will target only that namespace.

Allowed policy attributes

Authorization policy rules can contain source (from), operation (to), and condition (when) clauses.

The following attributes can be used in policies enforced by ztunnel:

Type Attribute Positive match Negative match
Source Peer identity principals notPrincipals
Source Namespace namespaces notNamespaces
Source IP block ipBlocks notIpBlocks
Operation Destination port ports notPorts
Condition Source IP source.ip n/a
Condition Source namespace source.namespace n/a
Condition Source identity source.principal n/a
Condition Remote IP destination.ip n/a
Condition Remote port destination.port n/a

Use of disallowed policy attributes

ztunnel operates at L4, and thus cannot use L7 attributes to enforce policies. If a policy with rules matching L7 attributes (i.e. those not listed in the table above) is targeted such that it will be enforced by a receiving ztunnel, it will fail safe:

  • DENY policies with L7 attributes will be enforced without their HTTP components.
  • ALLOW policies with L7 attributes will be empty, and never match.

In both cases, the result will be more restrictive than requested.

Take the example above, and add a check for a HTTP method (an L7 attribute):

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: allow-curl-to-httpbin
spec:
 selector:
   matchLabels:
     app: httpbin
 action: ALLOW
 rules:
 - from:
   - source:
       principals:
       - cluster.local/ns/ambient-demo/sa/curl
   to:
   - operation:
       methods: ["GET"]

Even if the identity of the client pod is correct, the presence of a L7 attribute causes the ztunnel to deny the connection:

command terminated with exit code 56

The status field on the object will show the policy was accepted, but that it has failed safe:

status:
  conditions:
  - lastTransitionTime: "2024-12-13T09:18:42.451009757Z"
    message: ztunnel does not support HTTP attributes (found: methods). In
      ambient mode you must use a waypoint proxy to enforce HTTP rules. Within an
      ALLOW policy, rules matching HTTP attributes are omitted. This will be more
      restrictive than requested.
    reason: UnsupportedValue
    status: "True"
    type: ZtunnelAccepted

Choosing enforcement points when waypoints are used

When a waypoint proxy is added to a workload, you now have two possible places where you can enforce L4 policy2.

Authorization policy with a waypoint proxy: two possible enforcement points.

Authorization policy with a waypoint proxy: two possible enforcement points.

When a system has more than one policy enforcement point, policies should always be applied to the earliest enforcement point that can handle them.

In most cases, once a waypoint is added, it becomes the ideal policy enforcement point.

When only using the secure overlay layer, traffic appears at the destination ztunnel with the identity of the source workload.

Without a waypoint, the server sees traffic with the identity of the client.

Without a waypoint, the server sees traffic with the identity of the client.

Waypoint proxies do not impersonate the identity of the source workload. Once you have introduced a waypoint to the traffic path, the destination ztunnel will see traffic with the waypoint’s identity, not the source identity.

With a waypoint, the server sees traffic with the identity of the waypoint.

With a waypoint, the server sees traffic with the identity of the waypoint.

This means that when you have a waypoint installed, the ideal place to enforce policy shifts. Even if you only wish to enforce policy against L4 attributes, if you are dependent on the source identity, you should attach your policy to your waypoint proxy. A second policy should be targeted at your workload to make its ztunnel enforce policies like “in-mesh traffic must come from my waypoint in order to reach my application”.

Peer authentication

Istio’s peer authentication policies, which configure mutual TLS (mTLS) modes, are supported by ztunnel.

The default policy for ambient mode is PERMISSIVE, which allows pods to accept both mTLS-encrypted traffic (from within the mesh) and plain text traffic (from without). Enabling STRICT mode means that pods will only accept mTLS-encrypted traffic.

As ztunnel and HBONE implies the use of mTLS, it is not possible to use the DISABLE mode in a policy. Such policies will be ignored.


  1. Policies attached to waypoints are targeted with the targetRef field. ↩︎

  2. L7 policy can only be enforced at the waypoint proxy. ↩︎