Layer 7 features in ambient mode

Ambient mode provides stable L7 capabilities through the Gateway API HTTPRoute resource and the Istio AuthorizationPolicy resource.

The AuthorizationPolicy resource functions in both sidecar and ambient modes. In ambient mode, authorization policies can be targeted for ZTunnel enforcement or attached to a waypoint for waypoint enforcement. To attach a policy to a waypoint, include a targetRef that references either the waypoint itself or a Service configured to use that waypoint.

You can attach L4 or L7 policies to a waypoint proxy for identity-based enforcement. Once a waypoint is part of the traffic path, the destination ZTunnel identifies traffic by the waypoint's identity.

Istio peer authentication policies that configure mTLS modes are supported by ZTunnel. In ambient mode, policies that set the mode to DISABLE are ignored because ZTunnel and HBONE always enforce mTLS. For details, see Peer authentication (Istio documentation).

Prerequisites

  • An active ACP CLI (kubectl) session by a cluster administrator with the cluster-admin role.
  • Istio is deployed in ambient mode.
  • The Bookinfo sample application is deployed (for the following example).
  • The waypoint proxy is deployed (for the following example).

Routing traffic using waypoint proxies

With a waypoint proxy deployed, you can split traffic between different versions of the Bookinfo reviews service for feature testing or A/B testing.

Procedure

  1. Create the traffic routing configuration. Save the following as traffic-route.yaml:

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: reviews
      namespace: bookinfo
    spec:
      parentRefs:
        - group: ""
          kind: Service
          name: reviews
          port: 9080
      rules:
        - backendRefs:
            - name: reviews-v1
              port: 9080
              weight: 80
            - name: reviews-v2
              port: 9080
              weight: 20
  2. Apply the traffic routing configuration:

    kubectl apply -f traffic-route.yaml

Verification

Access the productpage service from within the ratings pod:

kubectl exec "$(kubectl get pod -l app=ratings -n bookinfo -o jsonpath='{.items[0].metadata.name}')" \
  -c ratings -n bookinfo \
  -- bash -lc '\
     for i in {0..19}; do \
       curl -sS productpage:9080/productpage | grep -om1 "reviews-v[12]"; \
     done'

Most responses (80%) will contain reviews-v1 output, while a smaller portion (20%) will contain reviews-v2 output.

Example output
reviews-v1
reviews-v2
reviews-v1
reviews-v1
reviews-v1
reviews-v2
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v1
reviews-v2
reviews-v1
reviews-v1

Clean up the routing configuration

kubectl delete -n bookinfo httproute reviews

Adding authorization policy

Use an L7 authorization policy to explicitly allow the curl service to send GET requests to the productpage service while blocking all other operations.

Procedure

  1. Create the authorization policy. Save the following as authorization-policy.yaml:

    apiVersion: security.istio.io/v1
    kind: AuthorizationPolicy
    metadata:
      name: productpage-waypoint
      namespace: bookinfo
    spec:
      targetRefs:
        - kind: Service
          group: ""
          name: productpage
      action: ALLOW
      rules:
        - from:
            - source:
                principals:
                  - cluster.local/ns/curl/sa/curl
          to:
            - operation:
                methods: ["GET"]
    1. The targetRefs field specifies the service targeted by the authorization policy of the waypoint proxy.
  2. Apply the authorization policy:

    kubectl apply -f authorization-policy.yaml

Verification

  1. Create a namespace for the curl client:

    kubectl create namespace curl
  2. Deploy the curl client:

    kubectl apply -n curl -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/curl/curl.yaml
  3. Add the istio-discovery=enabled label to the curl namespace:

    kubectl label namespace curl istio-discovery=enabled
  4. Enable ambient mode for the curl namespace:

    kubectl label namespace curl istio.io/dataplane-mode=ambient
  5. Verify that a GET request to the productpage service succeeds with an HTTP 200 response:

    kubectl -n curl exec deploy/curl -- sh -c '\
      curl -s -o /dev/null -w "HTTP %{http_code}\n" \
        -X GET \
        http://productpage.bookinfo.svc.cluster.local:9080/productpage'

    Expected output

    HTTP 200
  6. Verify that a POST request to the same service is denied with an HTTP 403 response:

    kubectl -n curl exec deploy/curl -- sh -c '\
      curl -s -o /dev/null -w "HTTP %{http_code}\n" \
        -X POST \
        http://productpage.bookinfo.svc.cluster.local:9080/productpage'

    Expected output

    HTTP 403
  7. Verify that a GET request from another service (such as the ratings pod in the bookinfo namespace) is also denied with RBAC: access denied:

    kubectl exec "$(kubectl get pod -l app=ratings -n bookinfo \
      -o jsonpath='{.items[0].metadata.name}')" \
      -c ratings -n bookinfo \
      -- curl -X GET -sS productpage:9080/productpage

    Expected output

    RBAC: access denied

Clean up the verification resources

# Remove the authorization policy
kubectl delete -n bookinfo authorizationpolicy productpage-waypoint
# Remove the namespace from the ambient data plane
kubectl label namespace curl istio.io/dataplane-mode-
# Remove the Curl deployment and namespace
kubectl delete -n curl -f https://raw.githubusercontent.com/istio/istio/refs/heads/master/samples/curl/curl.yaml
kubectl delete namespace curl

Additional resources