Open-Source Wikis

/

Istio

/

Systems

/

Ambient mesh

istio/istio

Ambient mesh

Active contributors: howardjohn, stevenctl, keithmattix, hzxuzhonghu, costinm

Purpose

Ambient mode is Istio's sidecar-less data plane. This page covers the istiod side of Ambient: the registry that turns Kubernetes state into the workload API, the workload-API protocol itself, and the parts of the networking core that build Envoy config for waypoint proxies. The node-side mechanics (CNI, in-pod redirection, ZDS) are covered in applications/istio-cni. The Rust ztunnel proxy lives in istio/ztunnel and is consumed via istio.deps.

The architecture documents in this repo are:

Directory layout (istiod-side)

pilot/pkg/serviceregistry/
├── kube/controller/ambient/   # The krt-based ambient registry
│   ├── index.go               # The Index struct (top-level)
│   ├── workloads.go           # Workload collection (pod/WE → Workload)
│   ├── services.go            # Service collection
│   ├── waypoints.go           # Waypoint resolution
│   ├── authorization.go       # L4 policy compilation for ztunnel
│   ├── address.go             # Address collection (IP → Workload | Service)
│   └── ...
└── ambient/                   # Shared types (ambient.Index moved here in 2026-04)

pilot/pkg/networking/core/
├── listener_waypoint.go       # Waypoint listener generator
├── cluster_waypoint.go        # Waypoint cluster generator
├── waypoint.go                # Waypoint metadata helpers
└── tunnelingconfig/           # HBONE encoding helpers

pilot/pkg/xds/
├── workload.go                # Workload API generator (the wDS surface)

pkg/workloadapi/
├── workload.proto             # The wire format for ztunnel
├── workload.pb.go             # Generated Go
└── security/                  # Authorization message definitions

pkg/zdsapi/                    # Protocol between istio-cni node-agent and ztunnel
                               # (used by the node, *not* by istiod)

Key abstractions

Symbol File Role
ambient.Index pilot/pkg/serviceregistry/kube/controller/ambient/index.go Registers all the ambient krt collections
Workload (proto) pkg/workloadapi/workload.proto The unit ztunnel programs (one per pod)
Service (proto) pkg/workloadapi/workload.proto The service abstraction ztunnel sees
Address (proto) pkg/workloadapi/workload.proto Polymorphic Workload|Service keyed by IP
Authorization (proto) pkg/workloadapi/security/... Compiled L4 RBAC for ztunnel
WorkloadGenerator pilot/pkg/xds/workload.go The xDS generator that streams the above
Waypoint resolution pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go Gateway-API-driven waypoint mapping

How it works

graph LR
    subgraph K8s
        s[Services]
        ep[EndpointSlices]
        p[Pods]
        we[WorkloadEntries]
        ns[Namespaces]
        ga[Gateway / HTTPRoute / TCPRoute]
        ap[AuthorizationPolicy / PeerAuthentication]
    end
    subgraph AmbientRegistry["Ambient registry (krt)"]
        wcol[Workload collection]
        scol[Service collection]
        addr[Address collection]
        wp[Waypoint collection]
        auth[Authorization collection]
    end
    s --> scol
    ep --> wcol
    p --> wcol
    we --> wcol
    ns --> wcol
    ns --> scol
    ga --> wp
    ap --> auth
    wcol --> addr
    scol --> addr
    wp --> wcol
    wp --> scol
    addr --> wgen[WorkloadGenerator<br/>xds/workload.go]
    auth --> wgen
    wgen -->|wDS| zt[ztunnels]
    subgraph WaypointConfig["Waypoint Envoy config"]
        wlistener[listener_waypoint.go]
        wcluster[cluster_waypoint.go]
    end
    wcol --> WaypointConfig
    scol --> WaypointConfig
    WaypointConfig -->|xDS| waypoint[Waypoint Envoy pods]

The ambient registry

ambient.Index is built entirely on pkg/kube/krt/. It is one of the largest krt-based controllers in the codebase. Each Collection is a one-to-one or one-to-many transformation of inputs to outputs. When any input changes, krt recomputes only the affected outputs and dispatches events.

Top-level collections (in pilot/pkg/serviceregistry/kube/controller/ambient/):

  • WorkloadsCollection — joins Pods, EndpointSlices, WorkloadEntries, ServiceEntries, ServiceImports, and Namespace metadata to produce the canonical Workload representation. One entry per pod IP and one per WE.
  • ServicesCollection — joins core Services, ServiceEntries, and ServiceImports. Stores the merged Service representation.
  • WaypointsCollection — resolves Gateway resources of class istio.io/waypoint to a service or service-account scope. A namespace, service account, or service can be attached to a waypoint.
  • AuthorizationCollection — compiles AuthorizationPolicy and PeerAuthentication into ztunnel's L4-only authorization model. The compiler is in authorization.go.
  • AddressCollection — flattens Workload and Service into the polymorphic Address keyed by IP (the type ztunnel actually subscribes to).

These collections plug into the rest of istiod: the aggregate service registry exposes them as services/endpoints for sidecar mode too, so a single mesh can have both modes.

The workload API (wDS)

Ztunnels do not consume Envoy CDS/EDS. They consume an Istio-specific xDS surface defined in pkg/workloadapi/workload.proto. The proto includes:

  • Workload — pod-or-VM identity, labels, mTLS mode, network, addresses, and waypoint reference.
  • Service — name, namespace, hostname, ports, VIPs, waypoint reference.
  • Addressoneof { Workload, Service } keyed by IP/CIDR.
  • Authorization — compiled L4 rules per workload identity.

The generator at pilot/pkg/xds/workload.go answers ADS/Delta requests for the relevant type URLs (networking.istio.io/Workload, networking.istio.io/Service, …). It serves only the slice each ztunnel needs — typically the workloads on its node plus the services they call.

Waypoints

Waypoints are L7 Envoy pods that handle features ztunnel intentionally doesn't:

  • HTTP routing (URL match, header rewriting, retries, timeouts, faults).
  • L7 authorization.
  • Egress decisions for hosts not in the mesh.

A waypoint is provisioned via the Kubernetes Gateway API:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: my-waypoint
  namespace: my-app
spec:
  gatewayClassName: istio-waypoint
  listeners:
    - name: mesh
      port: 15008
      protocol: HBONE

Istiod's Gateway API translator (pilot/pkg/config/kube/gateway/) recognizes this class and the WaypointsCollection records the binding. Workloads attached to the waypoint (via the namespace label istio.io/use-waypoint=<name>) get a waypoint reference in their Workload proto, which ztunnel uses to redirect L7 traffic through the waypoint.

The waypoint Envoy itself is configured by the same translator that builds sidecar config — see networking-core — but with waypoint-specific listener and cluster shapes (listener_waypoint.go, cluster_waypoint.go).

HBONE

HBONE (HTTP-Based Overlay Network Environment) is the protocol ztunnel speaks across nodes. It is HTTP/2 CONNECT carrying a TLS stream — effectively an mTLS tunnel through a reverse-proxy hop. Library: pkg/hbone/.

For istiod, HBONE shows up in:

  • The waypoint listener generator emits HBONE-aware filter chains (listener_waypoint.go).
  • tunnelingconfig/ builds the per-cluster HBONE encoder for sidecar→waypoint connections.
  • The Workload proto's tunnel_protocol field tells ztunnel whether to wrap a target in HBONE.

Integration points

  • Reads from: All the same Kubernetes inputs as the legacy registry, plus Gateway API resources and Ambient-specific labels.
  • Writes to: Workload-API xDS streams (ztunnels) and standard xDS streams (waypoints), plus status conditions on Gateway / Service / WE resources (pilot/pkg/status/).
  • Talks to: Ztunnels (over xDS) and waypoint Envoys (over xDS). Does not talk to the istio-cni node agent — that is a node-local relationship between CNI and ztunnel via ZDS (pkg/zdsapi/).

Entry points for modification

  • New per-workload field → add to pkg/workloadapi/workload.proto, regenerate with make proto, populate in workloads.go. Coordinate with the ztunnel side (their proto is the same file, vendored in).
  • New L4 policy semantics → authorization.go is the compiler. Tests are in the goldens under testdata/.
  • New waypoint listener feature → listener_waypoint.go. Sidecar-mode listeners are in the sibling listener.go.
  • New ambient input source → add a Collection in pilot/pkg/serviceregistry/kube/controller/ambient/. Use krt.NewManyCollection for one-to-many, krt.NewCollection for one-to-one.

Key source files

File Purpose
pilot/pkg/serviceregistry/kube/controller/ambient/index.go Top-level Index
pilot/pkg/serviceregistry/kube/controller/ambient/workloads.go Workload collection
pilot/pkg/serviceregistry/kube/controller/ambient/services.go Service collection
pilot/pkg/serviceregistry/kube/controller/ambient/waypoints.go Waypoint resolution
pilot/pkg/serviceregistry/kube/controller/ambient/authorization.go L4 policy compiler
pilot/pkg/xds/workload.go Workload API xDS generator
pkg/workloadapi/workload.proto The wire format
pilot/pkg/networking/core/listener_waypoint.go Waypoint listeners
pilot/pkg/networking/core/cluster_waypoint.go Waypoint clusters
pkg/hbone/ HBONE library
pkg/zdsapi/ ZDS protocol (used by node agent + ztunnel)
pkg/kube/krt/collection.go The krt framework Ambient is built on

See also

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Ambient mesh – Istio wiki | Factory