Skip to content

Authorization policies with ztunnel

Page as Markdown

    

Apply Layer 4 authorization policies with ztunnel in ambient mesh to control which workloads can communicate with each other.

The ztunnel proxy enforces authorization policy at Layer 4 (L4). Because ztunnel operates at L4, only L4 attributes from Istio’s authorization policies are supported.

A waypoint proxy can enforce both L4 and L7 policy. See Choosing enforcement points for guidance on where to apply L4 policy when you also deploy waypoints.

Kubernetes network policies continue to work alongside ztunnel if your cluster has a CNI plugin that supports them, providing additional defense-in-depth.

Policy enforcement using ztunnel

When a workload is enrolled in ambient mesh, the ztunnel enforces authorization policy at the receiving (server-side) ztunnel in the path of a connection.

Figure: The policy enforcement point is the destination ztunnel.
Figure: The policy enforcement point is the destination ztunnel.

A basic L4 authorization policy looks like the following. This example policy uses a selector to allow traffic from the curl service account to pods labeled app: httpbin in the default namespace.

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 no authorization policy is provisioned, all traffic is allowed by default. Once a policy is provisioned, pods targeted by the policy only permit explicitly allowed traffic. In this example, pods labeled app: httpbin allow connections only from cluster.local/ns/ambient-demo/sa/curl. All other traffic is denied.

You can verify that the policy is attached by checking the status field.

kubectl get authorizationpolicy allow-curl-to-httpbin -n default -o yaml
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 that the policy object resides in, and an optional selector1. Policies in the Istio root namespace (typically istio-system) target all namespaces. Policies in any other namespace 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
SourcePeer identityprincipalsnotPrincipals
SourceNamespacenamespacesnotNamespaces
SourceIP blockipBlocksnotIpBlocks
OperationDestination portportsnotPorts
ConditionSource IPsource.ipn/a
ConditionSource namespacesource.namespacen/a
ConditionSource identitysource.principaln/a
ConditionRemote IPdestination.ipn/a
ConditionRemote portdestination.portn/a

Use of disallowed policy attributes

Ztunnel operates at L4 and cannot enforce L7 attributes. If a policy with L7 attribute rules is targeted at a ztunnel, it fails safe:

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

In both cases, the result is more restrictive than requested.

The following example extends the previous policy with an HTTP method check (an L7 attribute), intending to allow only GET requests from the curl service account to httpbin. Because ztunnel cannot enforce the method match, the ALLOW rule never matches, and all connections, including those from curl, are denied.

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"]

The connection attempt fails.

command terminated with exit code 56

The status field confirms the policy was accepted, but fails 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

Default DENY

Set up a default DENY policy to deny all traffic by default, then explicitly allow only the traffic that you want to permit. If you miss a condition, traffic is unexpectedly denied rather than unexpectedly allowed.

The following policy creates a default deny for all L4 traffic in the default namespace. With no spec rules, no traffic matches any allow rule, and ztunnel denies all incoming connections:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: default-deny
  namespace: default
spec:
  {}

If you use waypoints, also configure a default deny for waypoints.

Choosing enforcement points when waypoints are used

When a waypoint proxy is added to a workload, you have two possible enforcement points for L4 policy2.

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

Apply policies at the earliest enforcement point that can handle them. In most cases, once you add a waypoint, it becomes the ideal enforcement point.

Without a waypoint, traffic arrives at the destination ztunnel with the identity of the source workload.

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

Waypoints do not impersonate the source workload identity. With a waypoint in the traffic path, the destination ztunnel sees traffic with the waypoint’s identity, not the source identity.

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

This means that when you have a waypoint installed, the ideal enforcement point shifts. Even for L4-only policies, if you depend on the source identity, attach the policy to the waypoint. A ztunnel policy should also target the workload to enforce that in-mesh traffic must arrive from the waypoint.

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 outside). Enabling STRICT mode means pods only accept mTLS-encrypted traffic.

The DISABLE mode is not supported in ambient mesh and is ignored. ztunnel and HBONE require mTLS.


  1. Policies attached to waypoints use the targetRef field instead. ↩︎

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