# ========================================================================== # Zero Trust Authorization Policies - Deny by Default, Allow Explicitly # ========================================================================== # # Policy hierarchy: # 1. Mesh-wide DENY (default - everything blocked) # 2. Ingress Gateway ALLOW (external traffic entry point) # 3. Service-to-service ALLOW (explicit inter-service communication) # 4. Monitoring ALLOW (Prometheus scraping, Kiali queries) # # In ambient mode, L7 policies are enforced by waypoint proxies in each # namespace. L4 policies (source namespace/principal) are enforced by ztunnel. # Each namespace with ALLOW/CUSTOM policies must have a waypoint Gateway. # ========================================================================== # --- Ingress Gateway: Allow all external traffic through the edge gateway --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-ingress-gateway namespace: istio-system spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - {} --- # --- Allow Prometheus to scrape Istio control plane + gateway metrics --- # Selector scopes this to istio-system workloads only. # Without a selector, policies in the root namespace (istio-system) apply # mesh-wide in ambient mode, creating implicit deny for all ambient workloads. apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-prometheus-scraping namespace: istio-system spec: selector: matchLabels: app.kubernetes.io/part-of: istio action: ALLOW rules: - from: - source: namespaces: - prometheus to: - operation: ports: - "15014" # istiod control plane metrics - "15020" # sidecar/gateway merged metrics - "15090" # Envoy admin metrics --- # --- Allow Kiali to query istiod --- # Selector scopes this to istiod only (ambient root namespace caveat above). apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-kiali namespace: istio-system spec: selector: matchLabels: app: istiod action: ALLOW rules: - from: - source: principals: - cluster.local/ns/istio-system/sa/kiali-service-account --- # --- Authentik: Allow traffic from ingress + apps doing OIDC --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-authentik-access namespace: authentik spec: action: ALLOW rules: # Intra-namespace (server ↔ worker ↔ postgres) - from: - source: namespaces: - authentik # CNPG operator managing database instances - from: - source: namespaces: - cnpg-system # Ingress gateway for browser flows - from: - source: namespaces: - istio-system # Apps doing OIDC token exchange - from: - source: namespaces: - argocd - gitlab - grafana - nextcloud - home-assistant - guacamole - netbird - cattle-system - frigate - teslamate # Prometheus scraping (L4-only; L7 path checks deferred to waypoint) - from: - source: namespaces: - prometheus --- # --- Grafana: Allow ingress + Prometheus datasource queries + scraping --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-grafana-access namespace: grafana spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - grafana - from: - source: namespaces: - istio-system - from: - source: namespaces: - prometheus # NetBird VPN cluster routers (non-mesh, use ipBlocks) - from: - source: ipBlocks: - "10.244.0.0/16" --- # --- Prometheus: Allow ingress + self-scraping + Grafana --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-prometheus-access namespace: prometheus spec: action: ALLOW rules: # Intra-namespace (Prometheus ↔ alertmanager ↔ node-exporter) - from: - source: namespaces: - prometheus - from: - source: namespaces: - istio-system - grafana # NetBird VPN cluster routers (non-mesh, use ipBlocks) - from: - source: ipBlocks: - "10.244.0.0/16" --- # --- MQTT: Allow Home Assistant + Frigate + ESPHome + Prometheus --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-mqtt-access namespace: mqtt spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - mqtt - from: - source: namespaces: - istio-system - home-assistant - frigate - teslamate # Prometheus scraping (L4-only; L7 path checks deferred to waypoint) - from: - source: namespaces: - prometheus --- # --- External DNS: Allow internal access + Prometheus --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-external-dns namespace: external-dns spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - external-dns - from: - source: namespaces: - istio-system # Prometheus scraping (L4-only; L7 path checks deferred to waypoint) - from: - source: namespaces: - prometheus --- # --- Unpoller: Allow Prometheus scraping --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-unpoller-access namespace: unpoller spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - unpoller # Prometheus scraping (L4-only; L7 path checks deferred to waypoint) - from: - source: namespaces: - prometheus --- # --- Netbird: Allow ingress + Prometheus --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-netbird-access namespace: netbird spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - netbird # CNPG operator managing database instances - from: - source: namespaces: - cnpg-system - from: - source: namespaces: - istio-system # Netbird operator querying management API - from: - source: namespaces: - netbird - from: - source: namespaces: - prometheus # kube-apiserver webhook calls to netbird-operator webhook service (node IPs) - from: - source: ipBlocks: - "172.28.101.0/24" --- # --- Netbird Operator: Allow intra-namespace + Prometheus --- # Operator runs in the "netbird" namespace, not "netbird-operator" (which # doesn't exist) - fixed 2026-08-17, was blocking istio-mesh-config from # ever going Synced (kubectl apply failed: "namespaces netbird-operator # not found"). apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-netbird-operator-access namespace: netbird spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - netbird # Prometheus scraping (L4-only) - from: - source: namespaces: - prometheus --- # --- CrowdSec: Allow intra-namespace + CNPG + Prometheus --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-crowdsec-access namespace: crowdsec spec: action: ALLOW rules: # Intra-namespace (LAPI <-> agent) - from: - source: namespaces: - crowdsec # CNPG operator managing database instances - from: - source: namespaces: - cnpg-system # Prometheus scraping (L4-only; L7 path checks deferred to waypoint) - from: - source: namespaces: - prometheus # Firewall bouncer (hostNetwork DaemonSet) connects from node IPs - from: - source: ipBlocks: - "172.28.101.0/24" --- # --- Scylla Manager: Allow ingress + Prometheus + intra-namespace --- apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: allow-scylla-manager-access namespace: scylla-manager spec: action: ALLOW rules: # Intra-namespace - from: - source: namespaces: - scylla-manager - from: - source: namespaces: - istio-system - from: - source: namespaces: - prometheus # Scylla operator managing clusters - from: - source: namespaces: - scylla-operator