Authorization policy with waypoint proxies

Authorization policy with waypoint proxies

Without a waypoint installed, you can only use Layer 4 security policies. By adding a waypoint, you gain access to the full set of Layer 7 attributes in Istio’s AuthorizationPolicy, as well as request authentication.

Policy enforcement using waypoints

A basic Layer 7 (L7) authorization policy looks like this:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-waypoint-policy
  namespace: default
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/curl
    to:
    - operation:
        methods: ["GET"]

There are two primary differences from a policy bound to ztunnel:

  • The targetRefs field is used instead of a selector
  • Layer 7 attributes are supported

Binding policy to all waypoints

In general, the targetRefs field is used to target policy destined for certain services, and those policies are bound to the waypoints which those services are configured to use.

In some cases, you may wish to apply a policy to every waypoint. The canonical example is a “default DENY” policy, where waypoints implicitly deny all traffic that is not explicltly allowed by another policy.

This is achieved by targeting the GatewayClass resource:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: default-deny-waypoint
  namespace: istio-system
spec:
  targetRefs:
  - kind: GatewayClass
    group: gateway.networking.k8s.io
    name: istio-waypoint
GatewayClass is a cluster-scoped resource. Istio requires that policies which are bound to a GatewayClass reside in the root namespace, typically istio-system.

For complete coverage, this policy should be combined with a default DENY policy for L4, enforced by ztunnel.

Restricting workloads to only accept traffic from waypoints

Where appropriate, ambient mesh will automatically route traffic through waypoints. By default, this is only when traffic is sent to a service.

The ztunnel for a destination workload will continue to accept connections from any endpoint. (To ensure all traffic received by a workload comes from an in-mesh source, enable STRICT peer authentication.)

In order to ensure that waypoint policy enforcement cannot be bypassed, you can create a ztunnel policy to only allow connections from a workload’s waypoint1:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-ztunnel-policy
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/waypoint

Exceptions

Common use cases where you may wish to allow a waypoint to be bypassed include accepting connections from a gateway, which can act as policy enforcement points themselves, and scraping Prometheus metrics from a pod, where the overhead of a waypoint is not useful. In these cases, add the appropriate rules to the ztunnel policy for the port you are serving metrics on:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: productpage-ztunnel-policy
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - cluster.local/ns/default/sa/waypoint
  - from:
    - source:
        principals:
        - cluster.local/ns/istio-system/sa/prometheus
    to:
      - operation:
          ports: ["9090"]

Considerations for authorization policies

In ambient mesh, authorization policies can either be targeted (for ztunnel enforcement) or attached (for waypoint enforcement). For an authorization policy to be attached to a waypoint it must have a targetRef which refers to the waypoint, or a Service which uses that waypoint.

A configuration-first view of authorization policy

A configuration-first view of authorization policy

The ztunnel cannot enforce L7 policies. If a policy with rules matching L7 attributes is targeted with a workload selector (rather than attached with a targetRef), such that it is enforced by a ztunnel, it will fail safe by becoming a DENY policy.

See the ztunnel policy guide for more information, including when to attach policies to waypoints for TCP-only use cases.

Policy enforcement for traffic splitting

In the waypoint, authorization policies are enforced pre-routing, based on the service that traffic was originally destined for. In traffic splitting setups where a parent service routes to child services, only the authorization policy applied to the parent service is enforced, even when all services use a waypoint.

For example, consider a reviews route that uses backendRefs to send traffic to the endpoints of the reviews-v1 service.

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
  - group: ""
    kind: Service
    name: reviews
    port: 9080
  rules:
  - backendRefs:
    - name: reviews-v1
      port: 9080

If you have an authorization policy that targets reviews-v1, it will not be enforced on traffic destined for reviews.

For this reason, we recommend applying the same authorization policy to all services in the traffic splitting setup. This can help you make sure you don’t lose granular control of what is accessing your workloads.

For the reviews example, you can apply an authorization policy that targets both the parent (reviews) and children (reviews-v1, reviews-v2, reviews-v3) services.

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: reviews-waypoint-policy
  namespace: default
spec:
  targetRefs:
  - kind: Service
    group: ""
    name: reviews-v1
  - kind: Service
    group: ""
    name: reviews-v2
  - kind: Service
    group: ""
    name: reviews-v3
  - kind: Service
    group: ""
    name: reviews
...

  1. When at least one ALLOW rule exists for a destination, all other traffic is denied. ↩︎