From e1dd28a1f306630ce5c7f3fd1a75ef1be02e8414 Mon Sep 17 00:00:00 2001 From: Paolo Dettori Date: Mon, 8 Jun 2026 14:33:44 -0400 Subject: [PATCH] fix(driver): bypass Istio ambient inbound capture for sandbox pods On OpenShift with Istio ambient mesh (HBONE mode), ztunnel intercepts inbound TCP to the pod and re-originates connections from the pod's main IP instead of preserving the sandbox veth source address. This breaks the proxy's /proc/net/tcp-based identity resolution because peer_addr() returns ztunnel's address, not the sandbox's 10.200.0.2. Always annotate sandbox pods with: ambient.istio.io/bypass-inbound-capture: "true" This tells Istio ambient to skip inbound interception, preserving the original source address on the veth pair so identity resolution can correlate sockets to sandbox processes. The sidecar-mode annotation (traffic.sidecar.istio.io/excludeInboundPorts) has no effect in ambient mode. Fixes: kagenti/kagenti#1855 Assisted-By: Claude (Anthropic AI) Signed-off-by: Paolo Dettori --- internal/driver/provisioner.go | 11 ++++++++++- internal/driver/provisioner_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/internal/driver/provisioner.go b/internal/driver/provisioner.go index d4d27e5..f3a9691 100644 --- a/internal/driver/provisioner.go +++ b/internal/driver/provisioner.go @@ -323,10 +323,19 @@ func (p *K8sProvisioner) buildSandboxSpec(sb *pb.DriverSandbox) map[string]inter podLabels[labelKagentiTeam] = p.cfg.Tenant } + podAnnotations := map[string]interface{}{ + // Bypass Istio ambient inbound capture for sandbox pods. Without this, + // ztunnel (HBONE mode on OpenShift) re-originates veth-pair connections + // from the pod's main IP, breaking the proxy's /proc/net/tcp identity + // resolution which relies on seeing the sandbox's 10.200.0.2 source. + "ambient.istio.io/bypass-inbound-capture": "true", + } + return map[string]interface{}{ "podTemplate": map[string]interface{}{ "metadata": map[string]interface{}{ - "labels": podLabels, + "labels": podLabels, + "annotations": podAnnotations, }, "spec": podSpec, }, diff --git a/internal/driver/provisioner_test.go b/internal/driver/provisioner_test.go index 4521a7a..aa22f94 100644 --- a/internal/driver/provisioner_test.go +++ b/internal/driver/provisioner_test.go @@ -374,6 +374,30 @@ func TestBuildSandboxSpec_TenantLabels(t *testing.T) { } } +func TestBuildSandboxSpec_IstioBypassAnnotation(t *testing.T) { + p := newProvisionerForTest(t) + + sb := &pb.DriverSandbox{ + Id: "sb-istio", + Spec: &pb.DriverSandboxSpec{ + Template: &pb.DriverSandboxTemplate{ + Image: "img:latest", + }, + }, + } + + spec := p.buildSandboxSpec(sb) + podTemplate := spec["podTemplate"].(map[string]interface{}) + meta := podTemplate["metadata"].(map[string]interface{}) + annotations, ok := meta["annotations"].(map[string]interface{}) + if !ok { + t.Fatal("expected annotations in podTemplate metadata") + } + if annotations["ambient.istio.io/bypass-inbound-capture"] != "true" { + t.Errorf("expected ambient bypass annotation, got %v", annotations["ambient.istio.io/bypass-inbound-capture"]) + } +} + func TestBuildSandboxSpec_SATokenEnvVar(t *testing.T) { p := newProvisionerForTest(t)