Skip to content

Authservice Ambient Mode📜

This document describes the additional configuration required to make protected workloads (like the monitoring chart) function with Istio ambient mode.

Overview📜

In ambient mode, Istio uses waypoint proxies instead of sidecars to enforce L7 policies. By default (waypoint.enabled: true), authservice creates a waypoint gateway (authservice-waypoint) that handles JWT validation and authorization for protected workloads. Alternatively, enforcement can happen at the istio ingress gateway without a waypoint by setting waypoint.enabled: false (see Gateway Enforcement).

flowchart TD
    subgraph "Sidecar Mode"
        A1[Request] --> B1[Sidecar Proxy]
        B1 --> C1[Workload]
    end

    subgraph "Ambient Mode"
        A2[Request] --> B2[ztunnel]
        B2 --> C2[Waypoint Proxy]
        C2 --> D2[Workload]
    end

Key Differences from Sidecar Mode📜

Aspect Sidecar Mode Ambient Mode
Policy attachment selector.matchLabels targetRef to Gateway
L7 enforcement Sidecar proxy Waypoint proxy
Network path Direct to pod ztunnel → waypoint → pod
Waypoint port N/A 15008 (HBONE)

The ambient column describes the default waypoint mode. With waypoint.enabled: false, ambient mode keeps the sidecar-style policy attachment (label selector) and enforces at the istio ingress gateway instead — see Gateway Enforcement.

Waypoint Gateway📜

When istio.ambient.enabled: true and waypoint.enabled: true (the default), authservice creates:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: authservice-waypoint
  namespace: authservice
spec:
  gatewayClassName: istio-waypoint
  listeners:
  - name: mesh
    port: 15008
    protocol: HBONE
    allowedRoutes:
      namespaces:
        from: All

Workloads opt-in to use this waypoint by adding labels to their Service:

labels:
  istio.io/use-waypoint: authservice-waypoint
  istio.io/use-waypoint-namespace: authservice
  istio.io/ingress-use-waypoint: "true"

Gateway Enforcement (Without a Waypoint)📜

Setting waypoint.enabled: false runs ambient mode without the authservice waypoint. The waypoint Gateway is not created, and the authservice policies (jwt-authn, jwt-authz, authservice, shared-kiali-authz-policy) fall back to the same shape used in sidecar mode: they are created in istio-system with a protect: keycloak label selector instead of a targetRef.

Because istio-system is the Istio root namespace, the selector matches labeled pods mesh-wide. Labeling the istio ingress gateway pods with protect: keycloak attaches the policies there, so authentication is enforced at the gateway before traffic enters the mesh:

flowchart LR
    A[Request] --> B[Istio Gateway<br/>protect: keycloak<br/>ext_authz + JWT validation]
    B --> C[ztunnel]
    C --> D[Workload]

Big Bang Values Example📜

istio:
  ambient:
    enabled: true

# Label the public ingress gateway pods so the authservice policies
# (selector protect=keycloak in istio-system) attach to the gateway
istioGateway:
  values:
    gateways:
      public:
        upstream:
          labels:
            protect: keycloak

addons:
  authservice:
    enabled: true
    values:
      waypoint:
        enabled: false

Protected services must not carry the waypoint routing labels in this mode, or ztunnel will try to route through a waypoint that does not exist. The Big Bang umbrella sets these labels on monitoring services when ambient is enabled, so strip them by setting the keys to null (Helm deletes keys explicitly set to null when coalescing values):

monitoring:
  values:
    upstream:
      prometheus:
        service:
          labels:
            istio.io/use-waypoint: null
            istio.io/use-waypoint-namespace: null
            istio.io/ingress-use-waypoint: null
      alertmanager:
        service:
          labels:
            istio.io/use-waypoint: null
            istio.io/use-waypoint-namespace: null
            istio.io/ingress-use-waypoint: null

Caveats📜

  • Only Envoy-based proxies can enforce these policies. The fallback policies use a CUSTOM (ext_authz) action and JWT validation, which are L7 features. ztunnel is L4-only, so an ambient-enrolled application pod labeled protect: keycloak will not be protected — only gateway pods (full Envoy) enforce the policies. In this mode the gateway is the single enforcement point; traffic that bypasses the gateway (in-mesh service-to-service traffic) is not authenticated by authservice.
  • The selector is mesh-wide. Because the policies live in the root namespace, any pod in any namespace carrying the protect: keycloak label matches. Label only the gateway pods you intend to protect.
  • The authservice-waypoint network policies in the chart’s default values still render in this mode; they are harmless no-ops since their pod selector matches nothing.

Network Policies for Monitoring📜

Note: This section applies to the default waypoint mode (waypoint.enabled: true). In gateway-enforcement mode there is no waypoint, so the waypoint-specific policies below do not apply — traffic flows gateway → ztunnel → pod over HBONE directly.

For protected workloads in the monitoring namespace to function with ambient mode, network policies must allow traffic between the waypoint and the workload. Policies must include both the application port and port 15008 (HBONE).

1. Egress from Waypoint to Prometheus📜

The authservice waypoint needs egress to prometheus pods on both the application port and HBONE:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-egress-from-authservice-waypoint-to-ns-monitoring-pod-prometheus-tcp-port-9090
  namespace: authservice
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: authservice-waypoint
  policyTypes:
    - Egress
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: monitoring
          podSelector:
            matchLabels:
              app.kubernetes.io/name: prometheus
      ports:
        - port: 9090
          protocol: TCP
        - port: 15008
          protocol: TCP

2. Ingress to Prometheus from Waypoint📜

The monitoring namespace needs to allow ingress from the authservice waypoint:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-to-prometheus-tcp-port-9090-from-ns-authservice-pod-authservice-waypoint
  namespace: monitoring
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: prometheus
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: authservice
          podSelector:
            matchLabels:
              app.kubernetes.io/name: authservice-waypoint
      ports:
        - port: 9090
          protocol: TCP
        - port: 15008
          protocol: TCP

3. Ingress to Waypoint from Gateway📜

The istio gateway needs to reach the waypoint on HBONE:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-ingress-to-authservice-waypoint-tcp-port-15008-from-ns-istio-gateway-any-pod
  namespace: authservice
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: authservice-waypoint
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: istio-gateway
          podSelector: {}
      ports:
        - port: 15008
          protocol: TCP

Authorization Policies📜

In ambient mode, AuthorizationPolicies must allow the waypoint to access the protected workload. This can be done via namespace or principal matching:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-ingress-to-prometheus-tcp-port-9090-from-ns-authservice
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: prometheus
  action: ALLOW
  rules:
    - from:
        - source:
            namespaces:
              - authservice
      to:
        - operation:
            ports:
              - "9090"

For more restrictive configurations, use principal-based matching:

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: allow-waypoint-to-prometheus
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: prometheus
  action: ALLOW
  rules:
    - from:
        - source:
            principals:
              - cluster.local/ns/authservice/sa/authservice-waypoint
      to:
        - operation:
            ports:
              - "9090"

Configuring via Big Bang Values📜

These network policies are configured via bb-common values.

Authservice Chart (values.yaml defaults)📜

The authservice chart includes waypoint network policies by default:

networkPolicies:
  ingress:
    to:
      # Ingress to waypoint from gateway
      authservice-waypoint:15008:
        from:
          k8s:
            "istio-gateway/*": true
  egress:
    from:
      # Egress from waypoint to prometheus
      authservice-waypoint:
        to:
          k8s:
            monitoring/prometheus:9090: true

Monitoring Chart Configuration📜

The monitoring chart needs to allow ingress from the waypoint and label the prometheus service:

monitoring:
  enabled: true
  sso:
    enabled: true
  values:
    # Ingress to prometheus from waypoint
    networkPolicies:
      ingress:
        to:
          prometheus:9090:
            from:
              k8s:
                authservice/authservice-waypoint: true

    # Labels to route traffic through authservice waypoint
    upstream:
      prometheus:
        service:
          labels:
            istio.io/use-waypoint: authservice-waypoint
            istio.io/use-waypoint-namespace: authservice
            istio.io/ingress-use-waypoint: "true"

HBONE Port Injection📜

When istio.ambient.enabled: true, bb-common automatically adds port 15008 (HBONE) to network policies. This is indicated by the label:

ambient.istio.network-policies.bigbang.dev/hbone-injected: "true"

Traffic Flow in Ambient Mode📜

In ambient mode, all traffic flows through ztunnel (the L4 component). When a service has waypoint labels, ztunnel routes traffic through the waypoint for L7 policy enforcement.

sequenceDiagram
    participant Browser
    participant Gateway as Istio Gateway
    participant ztunnel1 as ztunnel (node)
    participant Waypoint as authservice-waypoint
    participant Authservice
    participant ztunnel2 as ztunnel (prometheus node)
    participant Prometheus

    Browser->>Gateway: GET https://prometheus.dev.bigbang.mil
    Gateway->>ztunnel1: Route to prometheus service

    Note over ztunnel1: Service has waypoint label<br/>Route via waypoint

    ztunnel1->>Waypoint: HBONE (port 15008)

    Note over Waypoint: CUSTOM policy triggers<br/>ext_authz to authservice

    Waypoint->>Authservice: Authorization check
    Authservice-->>Waypoint: OK + JWT header

    Note over Waypoint: RequestAuthentication validates JWT<br/>AuthorizationPolicy allows request

    Waypoint->>ztunnel2: Forward to prometheus
    ztunnel2->>Prometheus: Request with JWT
    Prometheus-->>Browser: Response

Troubleshooting📜

Request denied with no matching policy📜

Ensure the AuthorizationPolicy allows the waypoint service account:

kubectl get authorizationpolicy -n monitoring -o yaml
# Look for: principals: ["cluster.local/ns/authservice/sa/authservice-waypoint"]

Connection timeout to monitoring📜

Check network policies allow HBONE traffic:

# Verify egress from waypoint
kubectl get networkpolicy -n authservice -o yaml

# Verify ingress to monitoring
kubectl get networkpolicy -n monitoring -o yaml

Waypoint not receiving traffic📜

Verify the service has the correct labels:

kubectl get svc -n monitoring monitoring-monitoring-kube-prometheus -o yaml | grep -A5 labels
# Should include:
#   istio.io/use-waypoint: authservice-waypoint
#   istio.io/use-waypoint-namespace: authservice

See Also📜