Skip to content
This version of the documentation is currently under development. Select the stable version from the version drop down.

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Migrate egress controls from sidecar to ambient

Page as Markdown

Map sidecar egress patterns (REGISTRY_ONLY, egress gateways, exportTo) to their ambient equivalents.

Sidecar and ambient meshes enforce egress controls differently. To migrate without losing coverage, review the following mappings of common sidecar egress patterns to their ambient equivalents. For more information about migration, see Migrate from a sidecar mesh.

Behavioral differences

Before migrating, review the following behavioral changes that affect egress configuration in an ambient mesh.

outboundTrafficPolicy: REGISTRY_ONLY is not enforced in ambient

In sidecar mode, setting outboundTrafficPolicy: REGISTRY_ONLY in MeshConfig blocks traffic from sidecar proxies to any external destination not registered in the service registry. In an ambient mesh, ztunnel does not read outboundTrafficPolicy. Traffic to unregistered destinations passes through by default.

The ambient equivalent is the ztunnel egressPolicies Helm value, which instructs ztunnel to deny traffic to any destination not recognized in the service registry. When combined with ServiceEntry resources and gateway AuthorizationPolicy rules, this pattern provides stronger egress control than REGISTRY_ONLY because the enforcement point is inside ztunnel rather than inside an injectable sidecar. For migration steps, see Migrate from REGISTRY_ONLY.

exportTo is not supported in ambient

In sidecar mode, exportTo: ["."] on a ServiceEntry limits its visibility to the originating namespace. Workloads in other namespaces cannot resolve or route to that service entry.

In ambient mode, exportTo is ignored. All ServiceEntry resources are globally visible regardless of the exportTo field. Namespace-scoped access control must be expressed through AuthorizationPolicy resources that target the ServiceEntry or the egress gateway.

Sidecar egress gateways require reconfiguration

Sidecar egress gateways use VirtualService and DestinationRule to steer traffic through an Envoy-based gateway deployment. In ambient mode, the same Envoy-based gateway can serve as an L7 egress waypoint, but the binding mechanism changes: instead of a VirtualService route, you add istio.io/use-waypoint and istio.io/use-waypoint-namespace labels to the ServiceEntry that registers the external destination. Ztunnel routes matched traffic to the gateway automatically without a VirtualService.

Migration paths

Choose the path that matches your current sidecar egress configuration. Some migrations require more than one path.

To identify your patterns, check your MeshConfig for outboundTrafficPolicy, your VirtualService and DestinationRule resources for external destinations, and your ServiceEntry resources for exportTo fields.

Migrate from REGISTRY_ONLY

If you use outboundTrafficPolicy: REGISTRY_ONLY in sidecar mode to block access to unregistered external destinations, use the following procedure in ambient.

  1. For each external service that workloads must access, create a ServiceEntry. Bind the ServiceEntry to the ztunnel-egress gateway using istio.io/use-waypoint labels. Follow the full steps in L4 ztunnel-native egress.

  2. Configure ztunnel to deny traffic to any destination not in the service registry. This is the ambient equivalent of REGISTRY_ONLY.

    helm upgrade ztunnel oci://us-docker.pkg.dev/soloio-img/istio-helm/ztunnel \
      --version 1.31.0-solo \
      --namespace istio-system \
      --reuse-values \
      --set 'egressPolicies[0].matchCidrs={0.0.0.0/0,::/0}' \
      --set 'egressPolicies[0].policy=Deny'

    Ztunnel applies egress policies only to traffic that does not match a known destination in the service registry. Traffic to registered ServiceEntry destinations is routed through the gateway, and is not evaluated by this policy.

  3. Add AuthorizationPolicy resources to control which namespaces can access each ServiceEntry. See Step 3 in the L4 ztunnel-native egress guide for examples.

Note

Ztunnel egressPolicies denies unregistered destinations. It does not replace the AuthorizationPolicy model for known destinations. Both controls are needed: egressPolicies blocks unknown external IPs, and AuthorizationPolicy controls access to each registered external service.

Migrate from sidecar egress gateways

If you use a sidecar-based egress gateway with VirtualService and DestinationRule routing, choose the ambient egress approach that matches your enforcement requirements.

Sidecar patternAmbient equivalent
VirtualService + L4 port match only, no HTTP inspectionL4 ztunnel-native egress
VirtualService + HTTP header, path, or method matchingL7 waypoint egress
DestinationRule with TLS originationL7 waypoint egress

The key configuration change in both cases is the binding mechanism. In sidecar mode, a VirtualService routes traffic from the source sidecar to the egress gateway. In ambient mode, you add istio.io/use-waypoint and istio.io/use-waypoint-namespace labels to the ServiceEntry that registers the external destination. Ztunnel routes matched traffic to the gateway automatically without a VirtualService.

To migrate from an existing sidecar egress gateway:

  1. Create a ServiceEntry for each external destination, adding istio.io/use-waypoint labels to bind it to the ambient egress gateway. If you migrate to L7 waypoint egress, the gateway uses the istio-waypoint GatewayClass; if you migrate to L4 ztunnel-native egress, it uses the solo-ztunnel-egress GatewayClass.

  2. Apply AuthorizationPolicy resources targeting the ServiceEntry and the egress Gateway to control which source namespaces and service accounts can use each external service. DestinationRule resources remain valid in ambient for TLS origination when using L7 waypoint egress.

  3. Verify that ambient-enrolled workloads are routing correctly through the new gateway.

  4. Remove the VirtualService resources that previously routed traffic through the sidecar egress gateway. Removing the VirtualService after the ambient binding is in place avoids a routing gap where sidecar workloads lose their egress route before the ambient path is established.

Migrate from exportTo-scoped ServiceEntries

In sidecar mode, a team might publish a ServiceEntry with exportTo: ["."] to limit visibility to their own namespace and prevent other teams from routing to the same external host. In ambient mode, exportTo is not enforced. Replace exportTo namespace scoping with AuthorizationPolicy.

Warning

In ambient mode, the ServiceEntry is globally visible even with namespace-scoped placement. Without an AuthorizationPolicy, any namespace that can reach the egress gateway can access the external service. Always apply an AuthorizationPolicy to each ServiceEntry to preserve the access control that exportTo provided in sidecar mode.

Sidecar pattern of namespace-scoped ServiceEntry:

apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: external-api
  namespace: team-a
spec:
  hosts:
  - api.example.com
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: DNS
  location: MESH_EXTERNAL
  exportTo:
  - "."

Ambient equivalent of global ServiceEntry with AuthorizationPolicy scoping:

apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: external-api
  namespace: team-a
  labels:
    istio.io/use-waypoint: egress-waypoint
    istio.io/use-waypoint-namespace: istio-egress
spec:
  hosts:
  - api.example.com
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: DNS
  location: MESH_EXTERNAL
---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-team-a-to-external-api
  namespace: team-a
spec:
  targetRefs:
  - kind: ServiceEntry
    group: networking.istio.io
    name: external-api
  action: ALLOW
  rules:
  - from:
    - source:
        namespaces: ["team-a"]

The AuthorizationPolicy denies all namespaces except team-a from reaching api.example.com through this ServiceEntry. Because the ServiceEntry is in the team-a namespace, workloads in other namespaces cannot resolve it through the gateway without an explicit ALLOW policy.

Mixed sidecar and ambient clusters

When your cluster runs sidecar-injected workloads alongside ambient-enrolled workloads during migration, note the following:

  • Sidecar proxies do not route through the ztunnel-egress gateway. The solo-ztunnel-egress GatewayClass is an in-process ztunnel feature and has no listener that sidecar Envoy proxies can route to.
  • To prevent sidecars from attempting to route through an ambient egress gateway, add the solo.io/sidecar-skip-waypoint: "true" annotation to any ServiceEntry that uses istio.io/use-waypoint labels. This annotation causes sidecar proxies to ignore the waypoint binding and continue using their existing registry-based routing.
  • The REGISTRY_ONLY equivalent (egressPolicies: Deny) applies only to ambient-captured traffic. Sidecar proxies continue to enforce their own outboundTrafficPolicy setting independently.

For a full guide to running sidecar and ambient workloads in the same cluster, see the sidecar-to-ambient migration guide.