Istio Ambient Mesh Without Sidecars: Zero-Trust How-To
Bottom Line
Istio Ambient Mesh gives you zero-trust mTLS and identity at Layer 4 with ztunnel, then adds Layer 7 policy only where you need it through optional waypoint proxies. The result is a sidecarless rollout path that is simpler to operate than per-pod proxies.
Key Takeaways
- ›Istio ambient installs zero-trust networking without injecting sidecars into app pods
- ›The base data plane is ztunnel: per-node, L4-only, mTLS and identity by default
- ›Use waypoints only for L7 policy, routing, retries, and HTTP-aware telemetry
- ›Current stable docs show Istio 1.29.2 and Kubernetes 1.31-1.35 support
- ›Verify enrollment fast with istioctl ztunnel-config workloads and look for HBONE
Zero-trust networking for microservices usually means stronger identity, default encryption, and finer-grained policy, but traditional service meshes pay for that with sidecar sprawl. Istio Ambient Mesh changes the tradeoff. In the current stable docs as of April 28, 2026, Istio 1.29.2 delivers sidecarless mesh with a per-node ztunnel for Layer 4 security and optional waypoint proxies for Layer 7 controls. This tutorial shows the shortest path from cluster to verified zero-trust enforcement.
- Install the ambient profile to get istiod, CNI, and ztunnel.
- Enroll a namespace with
istio.io/dataplane-mode=ambient; no app restart or sidecar injection required. - Use PeerAuthentication and AuthorizationPolicy for L4 zero-trust defaults.
- Add a waypoint only when you need L7 authorization, routing, or HTTP metrics.
Prerequisites
Bottom Line
Use ztunnel to get mesh identity and mTLS everywhere first, then add waypoints only to the workloads that need HTTP-aware controls. That is the cleanest operating model for ambient zero-trust.
- A Kubernetes cluster on a version supported by the current ambient getting-started docs: 1.31 through 1.35.
kubectl,curl, and permissions to install cluster-scoped resources.- A test namespace; this walkthrough uses
defaultand the official Bookinfo sample. - An understanding that this guide uses istioctl for speed. Istio’s ambient install docs recommend Helm for production installs.
Implementation Steps
1. Download the Istio CLI and install Gateway API CRDs
The stable ambient guide uses Istio 1.29.2 and Kubernetes Gateway API CRDs v1.4.0. Download the release bundle first so you also get the sample manifests used later.
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.29.2
export PATH=$PWD/bin:$PATH
istioctl version
kubectl get crd gateways.gateway.networking.k8s.io > /dev/null || \
kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/experimental-install.yaml
2. Install ambient mode
Ambient support is included in the ambient profile. This installs the control plane, the CNI node agent, and the ztunnel daemonset that enforces the secure overlay on each node.
istioctl install --set profile=ambient --skip-confirmation
kubectl get pods -n istio-system
You should see running pods for istiod, istio-cni-node, and ztunnel.
3. Deploy workloads and enroll the namespace
Ambient mode does not require you to mutate application pods. Deploy the app normally, then label the namespace to bring those workloads into the mesh.
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl apply -f samples/bookinfo/platform/kube/bookinfo-versions.yaml
kubectl apply -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml
kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default
kubectl label namespace default istio.io/dataplane-mode=ambient
kubectl apply -f samples/curl/curl.yaml
That namespace label is the important shift from sidecar mode. Instead of injecting a proxy into every pod, ambient redirects traffic through the node-local ztunnel. Under the hood, in-mesh transport uses HBONE.
4. Enforce strict mTLS and a Layer 4 allow-list
Enrollment enables secure transport, but strict zero-trust posture means refusing plaintext and narrowing which identities may talk to a workload. Start with PeerAuthentication and an L4 AuthorizationPolicy.
kubectl apply -f - <<'EOF'
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default-strict
namespace: default
spec:
mtls:
mode: STRICT
EOF
kubectl apply -f - <<'EOF'
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: productpage-ztunnel
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/bookinfo-gateway-istio
EOF
This policy is enforced at the ztunnel layer. The effect is simple: only the Bookinfo gateway’s workload identity can open connections to productpage.
5. Add a waypoint for Layer 7 policy
Now add L7 controls without reintroducing sidecars. A namespace waypoint gives you HTTP-aware authorization and routing while keeping the application pods unchanged.
istioctl waypoint apply --enroll-namespace --wait
kubectl get gtw waypoint
kubectl apply -f - <<'EOF'
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: productpage-waypoint
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"]
EOF
kubectl apply -f - <<'EOF'
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: productpage-ztunnel
namespace: default
spec:
selector:
matchLabels:
app: productpage
action: ALLOW
rules:
- from:
- source:
principals:
- cluster.local/ns/default/sa/bookinfo-gateway-istio
- cluster.local/ns/default/sa/waypoint
EOF
The detail many teams miss is the last policy update. Once L7 enforcement moves to the waypoint, the destination still needs an L4 policy that allows the waypoint identity to connect.
Verification and Expected Output
Confirm the ambient control plane is healthy
kubectl get pods -n istio-system
- Expected: running pods for
istiod, oneztunnelper node, andistio-cni-node. - Expected install output includes:
Istio core installed,Istiod installed,CNI installed, andZtunnel installed.
Confirm workloads are using HBONE
istioctl ztunnel-config workloads
- Expected: application pods in the enrolled namespace show HBONE in the
PROTOCOLcolumn. - Expected: non-mesh or infrastructure entries may still show plain
TCP.
Confirm the L4 policy blocks the wrong identity
kubectl exec deploy/curl -- curl -s http://productpage:9080/productpage
- Expected before the waypoint L7 policy is added: the request fails, commonly with exit code 56.
Confirm the waypoint is programmed and enforcing HTTP rules
kubectl get gtw waypoint
kubectl exec deploy/curl -- curl -s http://productpage:9080/productpage | grep -o "<title>.*</title>"
kubectl exec deploy/curl -- curl -s http://productpage:9080/productpage -X DELETE
- Expected: the waypoint gateway shows
PROGRAMMED=True. - Expected: the GET request returns
<title>Simple Bookstore App</title>. - Expected: the DELETE request returns
RBAC: access denied.
Troubleshooting Top 3
- Workloads are not actually in ambient mode. Check the namespace label and the workload view. Run
kubectl get ns -L istio.io/dataplane-modeandistioctl ztunnel-config workloads. If you do not see HBONE, the namespace was not enrolled or traffic redirection is not active. - The waypoint exists but is not handling traffic. First confirm Gateway API CRDs are installed and the waypoint reports
PROGRAMMED=True. Then runistioctl ztunnel-config serviceoristioctl ztunnel-config workloadsto verify the destination service or pod is associated with the waypoint you expect. - Your policy attachment point is wrong. In ambient mode, L7 authorization for a waypoint uses
targetRefs, while L4 enforcement on the destination workload still uses a label selector. If behavior looks inconsistent, runistioctl analyze, then inspectistioctl proxy-statusandkubectl logs deploy/waypoint.
waypoint service account at the destination when L7 policy is enforced upstream.What's Next
- Move from namespace-wide enrollment to service- or workload-specific waypoints where trust boundaries differ.
- Add traffic management at the waypoint layer for canaries, retries, and timeouts.
- Enable Prometheus or Kiali if you want to move from L4 TCP telemetry to richer L7 visibility.
- For production, convert the install path from istioctl to Helm so ambient components are versioned and promoted through your normal platform pipeline.
Frequently Asked Questions
What is the difference between ztunnel and a waypoint proxy in Istio Ambient Mesh? +
Do I need to restart pods to move workloads into Istio ambient mode? +
istio.io/dataplane-mode=ambient, and the official docs explicitly position this as a no-sidecar, no-redeploy path. That is one of the main operational advantages over sidecar injection.How do I verify that ambient mesh is actually using mTLS? +
istioctl ztunnel-config workloads. If enrolled workloads show HBONE in the protocol column, they are configured to use the ambient secure overlay. You can strengthen enforcement with PeerAuthentication set to STRICT so plaintext traffic is rejected.Why does my L7 AuthorizationPolicy not work with ambient mode? +
targetRefs to attach to a Service or other supported target. You also need a compatible L4 policy at the destination that allows the waypoint identity; otherwise the HTTP policy can be correct while the connection is still blocked lower in the stack.Get Engineering Deep-Dives in Your Inbox
Weekly breakdowns of architecture, security, and developer tooling — no fluff.