Migrate policies
In ambient mode, L7 traffic management is handled by waypoint proxies rather than sidecar proxies. This changes how policies are expressed and enforced:
VirtualServicesupport with waypoints is Alpha. While it may work in limited cases, migrating toHTTPRouteis strongly recommended. MixingVirtualServiceandHTTPRoutefor the same workload is not supported and leads to undefined behavior.DestinationRuletraffic policies (connection pool settings, outlier detection, TLS) are supported by waypoints and require no changes. However,HTTPRouteuses Kubernetes Services asbackendRefsfor routing rather than DestinationRule subsets, so version based traffic splitting inHTTPRouterequires separate Services per version.AuthorizationPolicyresources that use L7 rules (HTTP methods, paths, or headers), or that useaction: CUSTOMoraction: AUDIT, must usetargetRefs(instead of workloadselector) to attach the policy to supported resources, for more information check the AuthorizationPolicy documentation.RequestAuthenticationandWasmPluginresources require a waypoint proxy and must be targeted usingtargetRefsto point at the waypoint.EnvoyFilterresources are not supported on waypoints. If you haveEnvoyFilterresources that configure sidecar proxy behavior, they will be silently ignored after migration and must be handled before proceeding:- If the filter adds custom Envoy functionality, evaluate whether a
WasmPlugincan provide equivalent behavior on the waypoint. - If the filter is no longer needed, delete it.
- If there is no ambient-compatible alternative, this is a migration blocker. Do not proceed until the dependency is resolved.
- If the filter adds custom Envoy functionality, evaluate whether a
Audit your existing policies
Start by listing all L7 resources in your cluster:
$ kubectl get virtualservice,destinationrule -AIdentify AuthorizationPolicy resources that will require a waypoint (L7 rules or
CUSTOM/AUDIT actions):
$ kubectl get authorizationpolicy -A --no-headers | while read ns name rest; do
if kubectl get authorizationpolicy "$name" -n "$ns" -o yaml | grep -qE "(methods:|paths:|headers:|action: CUSTOM|action: AUDIT)"; then
echo "$ns/$name"
fi
doneIdentify DestinationRule resources with subsets (these require version-specific Services
in ambient mode):
$ kubectl get destinationrule -A --no-headers | while read ns name rest; do
if kubectl get destinationrule "$name" -n "$ns" -o yaml | grep -q "subsets:"; then
echo "$ns/$name"
fi
doneMigrate VirtualService to HTTPRoute
HTTPRoute is the stable, supported L7 routing API for ambient mode.
Example: Header-based routing
The following VirtualService routes requests with end-user: jason to reviews version 2,
and all other requests to version 1 using subsets:
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1Because HTTPRoute does not support DestinationRule subsets, you must first create
version specific Services:
apiVersion: v1
kind: Service
metadata:
name: reviews-v1
namespace: bookinfo
spec:
selector:
app: reviews
version: v1
ports:
- port: 9080
name: http
---
apiVersion: v1
kind: Service
metadata:
name: reviews-v2
namespace: bookinfo
spec:
selector:
app: reviews
version: v2
ports:
- port: 9080
name: httpThen replace the VirtualService with an HTTPRoute that attaches to the reviews Service
directly (using kind: Service as the parentRef). This is the correct attachment model for
ambient mode — the waypoint uses the Service as the routing anchor:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: reviews
namespace: bookinfo
spec:
parentRefs:
- group: ""
kind: Service
name: reviews
port: 9080
rules:
- matches:
- headers:
- name: end-user
value: jason
backendRefs:
- name: reviews-v2
port: 9080
- backendRefs:
- name: reviews-v1
port: 9080For a complete reference on HTTPRoute capabilities, see the
traffic management documentation.
Migrate AuthorizationPolicy for L7 rules
In sidecar mode, AuthorizationPolicy resources use a selector to target pods directly.
In ambient mode, L7 authorization policies must be enforced by a waypoint proxy and therefore
must use targetRefs to target the waypoint’s parent Service or the Gateway itself.
L4 policies (no change required)
L4 AuthorizationPolicy resources that only match on source principals, namespaces, or IP
ranges work in ambient mode without modification. They are enforced by ztunnel.
# This L4 policy requires no changes for ambient mode
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-frontend
namespace: bookinfo
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- from:
- source:
principals: ["cluster.local/ns/bookinfo/sa/productpage"]L7 policies
Policies that match on HTTP methods, paths, or headers, or that use action: CUSTOM or
action: AUDIT, must target a waypoint proxy. Replace selector with targetRefs
pointing to the Service the waypoint protects, or to the waypoint Gateway resource
itself:
# Before: sidecar-style (selector based)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-get-reviews
namespace: bookinfo
spec:
selector:
matchLabels:
app: reviews
action: ALLOW
rules:
- to:
- operation:
methods: ["GET"]# After: ambient-style (targetRefs to Service)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-get-reviews
namespace: bookinfo
spec:
targetRefs:
- kind: Service
group: ""
name: reviews
action: ALLOW
rules:
- to:
- operation:
methods: ["GET"]Alternatively, you can target the waypoint Gateway resource directly. This applies the
policy to all traffic processed by the waypoint, regardless of the destination Service:
# After: ambient-style (targetRefs to waypoint Gateway)
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: allow-get-reviews
namespace: bookinfo
spec:
targetRefs:
- kind: Gateway
group: gateway.networking.k8s.io
name: waypoint
action: ALLOW
rules:
- to:
- operation:
methods: ["GET"]Targeting a Service is the more precise option and is recommended when the policy
should apply to a single service. Targeting the Gateway is useful when the policy
should apply to all services in the namespace.
Prevent waypoint bypass
When a waypoint is used, ensure that workloads cannot be reached by bypassing it. Use a
workload selector DENY policy enforced by ztunnel (at the destination pod). Since
this policy only checks the source principal (an L4 attribute), ztunnel can enforce it
correctly.
Decide when to apply bypass prevention
During an incremental migration, some source workloads may still be in sidecar mode. Sidecar mode workloads bypass the waypoint and connect directly to ztunnel at the destination, so ztunnel sees the sidecar identity as the source principal, not the waypoint identity. A strict waypoint only DENY policy will reject their traffic.
Choose one of the following options before applying the policy:
Option 1: Delay bypass prevention until all sources are migrated. Do not apply the DENY policy until every workload that calls this service has moved to ambient mode. This is the simpler approach when you control all callers.
Option 2: Allow traffic from both the waypoint and sidecar principals.
Apply the policy immediately, but add the service accounts of the remaining sidecar
workloads to the notPrincipals exception list alongside the waypoint. Remove each
sidecar principal from the list as it is migrated. Once all callers are in ambient mode,
only the waypoint principal needs to remain.
Apply the bypass prevention policy
Look up the service account used by your waypoint:
$ kubectl get pod -n <namespace> -l gateway.istio.io/managed=istio.io-mesh-controller \
-o jsonpath='{.items[0].spec.serviceAccountName}'For Option 1, apply the policy only after all callers are migrated:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-waypoint-bypass
namespace: bookinfo
spec:
selector:
matchLabels:
app: reviews
action: DENY
rules:
- from:
- source:
notPrincipals:
- "cluster.local/ns/bookinfo/sa/waypoint"For Option 2, include sidecar principals in the exception list during migration:
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
name: deny-waypoint-bypass
namespace: bookinfo
spec:
selector:
matchLabels:
app: reviews
action: DENY
rules:
- from:
- source:
notPrincipals:
- "cluster.local/ns/bookinfo/sa/waypoint"
- "cluster.local/ns/bookinfo/sa/productpage"Next steps
Proceed to Enable ambient mode to label namespaces, activate waypoints, and remove sidecar injection.