---
title: "Istio Network Policy"
source: "https://www.tigera.io/learn/guides/istio/istio-network-policy/"
description: "Istio uses its own Authorization Policies for application-level (Layer 7) network control, which are more flexible than Kubernetes network policies that operate at the network-level (Layers 3 and 4). While Istio doesn't implement Kubernetes network policies, it provides functional equivalents."
---

## Guides: Istio Network Policy

# Combining Istio Authorization Policy with Kubernetes Network Policy

- [Istio](https://www.tigera.io/learn/guides/istio/)

- [Istio Network Policy](https://www.tigera.io/learn/guides/istio/istio-network-policy/)

- [Istio Gateway](https://www.tigera.io/learn/guides/istio/istio-gateway/)

- [Istio Dashboard](https://www.tigera.io/learn/guides/istio/istio-dashboard/)

- [Istio vs Linkerd](https://www.tigera.io/learn/guides/istio/istio-vs-linkerd/)

- [Istio Multi Cluster](https://www.tigera.io/learn/guides/istio/istio-multi-cluster/)

- [Istio Kubernetes](https://www.tigera.io/learn/guides/istio/istio-kubernetes/)

- [Istio Proxy](https://www.tigera.io/learn/guides/istio/istio-proxy/)

- [Istio Security](https://www.tigera.io/learn/guides/istio/istio-security/)

- [Istio Service Mesh](https://www.tigera.io/learn/guides/istio/istio-service-mesh/)

- [Istio Ingress](https://www.tigera.io/learn/guides/istio/istio-ingress/)

- [Istio Ambient](https://www.tigera.io/learn/guides/istio/istio-ambient/)

Istio uses its own Authorization Policies for application-level (Layer 7) network control, which are more flexible than Kubernetes network policies that operate at the network-level (Layers 3 and 4). While Istio doesn’t directly implement Kubernetes network policies, it provides functional equivalents and extensions to enhance security, including features like request routing, token validation, and access control based on service accounts, hostnames, or request paths.

This article will cover the differences between Istio’s authorization policies and Kubernetes network policies, explain why it’s important to use both types of policies together, and provide a tutorial that shows how to implement this in practice.

## What Is an Istio Authorization Policy?

Key aspects of Istio authorization policies include:

- **Functionality:** These policies operate at Layer 7 (application layer) and control access based on the content of the request, such as HTTP headers, paths, and JWT tokens.

- **Flexibility:** Suitable for operational goals like service routing, retries, and security that requires application-level knowledge, such as token validation.

- **Actions:** Policies can have ALLOW, DENY, or CUSTOM actions, and requests are evaluated in a specific order: CUSTOM, then DENY, then ALLOW.

- **Implicit enablement:** By default, Istio allows all requests. You must apply an authorization policy to enforce access control.

- **Example:** You can create an authorization policy to deny requests that do not have a valid JWT token by using a DENY action on requests without a request principal.

Istio authorization policies are written in YAML and are applied at various scopes, such as at the mesh, namespace, or workload level. Administrators can define rules specifying which service accounts, namespaces, or IP blocks can call certain endpoints using particular HTTP methods and paths.

This type of policy enables fine-grained access control based on attributes such as source and destination workloads, request headers, methods, and paths. This policy works with Istio’s envoy sidecars, which intercept and enforce policies at the application level, enabling allow and deny actions for incoming and outgoing traffic across services governed by the service mesh.

**In this article:**

- What Is a Kubernetes Network Policy?

- Istio Authorization Policy vs. Kubernetes Network Policy: Key Differences

- Why Combine Istio Authorization Policies and Kubernetes Network Policies for Better Security

- Challenges When Managing Istio Policies and Kubernetes Network Policies Together

- Tutorial: Restricting Traffic Using Istio AuthorizationPolicy and Kubernetes NetworkPolicy

- Validating and Troubleshooting Istio with Network Policy Enforcement

## What Is a Kubernetes Network Policy?

Key aspects of Kubernetes network policies include:

- **Functionality:** These are a native Kubernetes API for controlling network traffic between pods at the network and transport layers (Layers 3 and 4).

- **Strengths:** They are highly efficient, isolated from the pods, and useful for implementing network security at a basic level.

- **Conflict with Istio:** Historically, running both Kubernetes Network Policies and Istio’s sidecar proxy could cause conflicts. To ensure Istio functions correctly, it was often necessary to disable network policy enforcement on the nodes, which increased the attack surface.

- **Workarounds:** Some solutions, like those from [Calico](https://www.tigera.io/tigera-products/calico/), allow for Istio and application-layer network policies to work together by integrating with Istio’s authorization features.

Kubernetes network policies are enforced by supported network plugins (CNI providers) rather than Kubernetes itself, ensuring that traffic is allowed or blocked according to specified ingress and egress rules. These policies support selection based on namespace, labels, and IP ranges, but operate at a lower layer compared to Istio authorization policies.

Rules within a NetworkPolicy define allowed sources and destinations, targeting traffic by port and protocol but without direct awareness of application-level data such as HTTP methods or specific paths. As a result, Kubernetes network policies provide a layer of security, primarily focused on restricting lateral movement and segmenting workloads within the network.

## Istio Authorization Policy vs. Kubernetes Network Policy: Key Differences

The following table summarizes the key differences between the two types of policies. We explore these differences in more detail below.

**Feature**
**Istio authorization policy**
**Kubernetes network policy**

**OSI Layer**
Layer 7 (Application)
Layers 3 (Network) and 4 (Transport)

**Control Focus**
Service-to-service communication based on request content and identity
Traffic flow between pods and the network

**Complexity**
Highly flexible and application-protocol aware
Universal and efficient

**Security Type**
Application-level security (e.g., JWT validation)
Network-level security (e.g., port and IP blocking)

### 1. OSI Layer

**Istio authorization policies** operate at Layer 7 (application layer) of the OSI model. This means that Istio can inspect and filter traffic based on application protocols like HTTP, including HTTP methods, headers, and paths. Because Istio leverages sidecar proxies (envoy), it is capable of enforcement decisions using contextual information about the traffic payload and metadata, not just its network route or protocol.

**Kubernetes network policies** work at Layer 3 (network layer) and Layer 4 (transport layer). These policies control traffic primarily based on IP addresses, port numbers, and protocols (TCP/UDP). They cannot interpret application-specific payload or content, and their enforcement occurs via network plug-ins (such as Calico) at the pod or node network interface level. This distinction limits Kubernetes network policies to coarse-grained traffic rules.

### 2. Control Focus

**Istio authorization policy** focuses on controlling access to application endpoints and functions. Administrators can define policies specifying which clients, based on their identity or request characteristics, are permitted to make calls to specific URLs or microservice operations. The fine-grained, context-aware nature of Istio authorization policy enables centralized control for service-to-service communication at the application layer, closely aligning with zero-trust security models.

**Kubernetes network policy** is designed to restrict connectivity between pods or namespaces at the networking level. Its scope is primarily about which pods can talk to which other pods, rather than what actions or API calls they can perform once connected. This provides a basic foundation for network segmentation or [microsegmentation](https://www.tigera.io/learn/guides/microsegmentation/), but does not account for the intent or legitimacy of specific application requests.

### 3. Complexity

**Istio authorization policies** introduce a higher degree of complexity and granularity compared to Kubernetes network policies. Writing and maintaining Istio policies requires understanding of service identities, attributes, and often a deep integration with application architecture. Policies can grow complex as requirements evolve to cover multiple workloads, namespaces, and use various match conditions (methods, paths, principals, etc.). Effective policy management may demand specialized knowledge of Istio features and mesh-wide impact.

**Kubernetes network policies** are generally more straightforward to create, as they simply specify pod selectors, namespace selectors, and network-level rules. This simplicity can make them easier to adopt for basic use cases like isolating teams or environments. However, their lack of application-layer awareness means that finer-grained security requirements cannot be met without introducing a more advanced solution such as Istio.

### 4. Security Type

**Istio authorization policies** provide application-level (Layer 7) security, which enforces access to specific microservice operations or resources. By incorporating request context, identity information, and metadata, these policies can implement attribute-based access control (ABAC), enforcing security based on who is making the request, under what conditions, and what they are attempting to do. This supports models such as least privilege and zero-trust within the service mesh.

**Kubernetes network policies** implement network-level (Layer 3/4) security, controlling the flow of packets between pods or namespaces. These policies do not know about application context or service identities; they simply block or allow traffic at the network interface. Their effectiveness is crucial for basic containment, but are insufficient alone for enforcing fine-grained application-level access controls required by modern security standards.

## Why Combine Istio Authorization Policies and Kubernetes Network Policies for Better Security

Relying on either Istio authorization policies or Kubernetes network policies alone leaves gaps in a security architecture. Combining both enables a defense-in-depth approach by layering network-level and application-level controls:

- At the network layer (L3/L4), **Kubernetes network policies** enforce coarse-grained traffic restrictions based on IPs, ports, and protocols. This blocks unauthorized communication between pods or namespaces and reduces lateral movement within the cluster. However, these policies cannot inspect application data or make decisions based on user identity, request paths, or tokens.

- **Istio authorization policies** provide application-layer (L7) security, allowing detailed access control based on request context, such as JWT tokens, HTTP methods, or user identities. This enables zero-trust microsegmentation, where each service enforces strict identity-based rules on who can call what and under which conditions. This is especially critical for enforcing least-privilege access in multi-service architectures.

Using both together ensures unauthorized traffic is blocked early at the network layer and then further filtered at the application layer. For example, a Kubernetes policy can prevent traffic from reaching sensitive services except from trusted namespaces, while Istio can enforce that even allowed calls include valid identity tokens.

**Important notes:**

- A service mesh like Istio does not provide workload isolation. It controls and observes traffic, but cannot prevent compromised workloads from reaching others unless paired with lower-layer controls.

- Likewise, network policies cannot express application-level intent or authorization logic. A common misconception is treating network policy as equivalent to application authorization, which leads to over-reliance on IP-based controls for trust decisions.

- By combining L3/L4 enforcement with L7-aware policies, organizations can achieve layered protection that aligns with modern security principles like zero trust and microsegmentation.

### Tips from the Expert

In my experience, here are tips that can help you better implement Istio Authorization Policy and Kubernetes NetworkPolicy together for layered security:

#### Inject workload identity fingerprints into logs:

Configure Envoy sidecars to log identity metadata (e.g., SPIFFE ID, JWT claims, service account) alongside request logs. This allows SOC teams to correlate L7 security decisions with authenticated identities for forensic analysis, especially when investigating cross-namespace attacks.

#### Use dedicated namespaces to enforce policy boundaries:

Instead of broadly applying policies at the cluster or mesh level, isolate sensitive workloads into their own namespaces. Then, apply AuthorizationPolicies and NetworkPolicies specifically scoped to those namespaces to avoid overly permissive cross-namespace access.

#### Leverage audit and dry-run modes before enforcing policies:

Istio offers dry-run mode for authorization policies via the action: CUSTOM with a shadow rule. This lets you test the impact of a new policy without affecting live traffic, reducing risk of outages during policy rollout.

#### Deploy policy drift detection for layered policy enforcement:

Use a GitOps-based approach to store both Istio and Kubernetes policies in version control. Continuously compare the live cluster state with source-of-truth manifests to detect unauthorized changes.

#### Implement egress gateways with L7 and L3/L4 control:

Route all egress traffic through Istio's egress gateway and combine it with Kubernetes NetworkPolicy that only allows pod-to-egress-gateway communication. This centralizes outbound access control and audit while preventing pods from bypassing L7 enforcement via direct IP access.

![Profile Picture](https://www.tigera.io/app/uploads/2026/04/Dillon-Barry-150x150.jpeg)

#### Dillon Barry

Technical Marketing Engineer (TME)

Dillon Barry is a Technical Marketing Engineer at Tigera. He has worked with Kubernetes and Cloud Native technologies for over 8 years at some of the largest and most forward thinking companies in the industry. Based in Ireland, Dillon has a wealth of experience across different roles and industries as a consultant and solutions architect, with a background at companies like Pivotal and VMware. Dillon has a Bachelor's degree in Computer Science and an interest in everything modern computing.

## Challenges When Managing Istio Policies and Kubernetes Network Policies Together

While combining Istio and Kubernetes policies strengthens security, managing both introduces operational complexity. Each system has its own policy engine, syntax, and enforcement behavior, increasing the risk of drift between intent and reality:

- **Visibility:** Because enforcement occurs at different OSI layers (L3/L4 for Kubernetes and L7 for Istio) it’s difficult to visualize how policies interact. Operators often lack a unified view of which traffic is allowed or denied end-to-end, making it hard to understand or validate the effective security posture.

- **Policy conflicts:** A Kubernetes network policy might allow traffic that an Istio authorization policy later denies, or vice versa. Unintended deny rules can break communication between services, and without integrated tooling, pinpointing the root cause is slow and error-prone.

- **Complexity:** Troubleshooting traffic failures becomes more complicated across layers. When a service cannot connect, teams must check network plug-ins, Kubernetes policies, and Istio rules, each with separate logging, metrics, and control planes. Misconfigured rules in either layer can introduce silent failures or unpredictable behavior.

- **Performance and latency:** These can also be impacted if policies are not designed efficiently. For instance, overly broad network policies or complex Istio authorization rules can increase CPU usage in sidecars or network plug-ins, degrading throughput. This is especially critical at scale, where policy evaluation must remain performant.

- **Lack of unified observability tools:** Without correlated logs and metrics across Kubernetes and Istio, teams struggle to audit access, detect anomalies, or confirm policy effectiveness. This gap often forces manual correlation of data from multiple sources, slowing down incident response and policy tuning.

## Tutorial: Restricting Traffic Using Istio AuthorizationPolicy and Kubernetes NetworkPolicy

This tutorial demonstrates how to restrict traffic between two namespaces using Istio’s AuthorizationPolicy and Kubernetes’ NetworkPolicy. The goal is to deploy two NGINX pods in separate namespaces and progressively apply policies to block traffic to one of them.

### Step 1: Deploy Sample Workloads

First, define a template file istio-np.yaml.template to create the resources:

```
`apiVersion: v1 kind: Service metadata: name: svc-$SERVICE_NAME spec: type: ClusterIP ports: - name: http-web port: 80 targetPort: 80 selector: app: $SERVICE_NAME --- apiVersion: v1 kind: ConfigMap metadata: name: config-$SERVICE_NAME data: nginx.conf: ' events {} http { server { listen 80; location / { return 200 "Hello world - $SERVICE_NAME!"; } } } ' --- apiVersion: apps/v1 kind: Deployment metadata: name: $SERVICE_NAME spec: selector: matchLabels: app: $SERVICE_NAME strategy: type: Recreate template: metadata: annotations: sidecar.istio.io/logLevel: debug sidecar.istio.io/proxyLogLevel: rbac:debug labels: app: $SERVICE_NAME spec: containers: - image: nginx:latest name: $SERVICE_NAME ports: - containerPort: 80 name: web volumeMounts: - name: config-vol mountPath: /etc/nginx/ volumes: - name: config-vol configMap: name: config-$SERVICE_NAME items: - key: nginx.conf path: nginx.conf`
```

Create namespaces and enable Istio sidecar injection:

```
`kubectl create namespace mesh-ns-a kubectl create namespace mesh-ns-b kubectl label namespace mesh-ns-a istio-injection=enabled --overwrite kubectl label namespace mesh-ns-b istio-injection=enabled --overwrite`
```

![Output of creating and labeling the mesh namespaces](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-01.jpg)

Generate manifests for both workloads:

```
`export APP_ID=ng-a export SVC_PORT=81 export POD_PORT=8081 envsubst < mesh-workloads.yaml.tpl | kubectl apply -n mesh-ns-a -f - export APP_ID=ng-b export SVC_PORT=82 export POD_PORT=8082 envsubst < mesh-workloads.yaml.tpl | kubectl apply -n mesh-ns-b -f -`
```

![Output of deploying the ng-a and ng-b workloads](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-02.jpg)

Apply the manifests:

```
`kubectl apply -f istio-np-1.yaml -n np-test-1 kubectl apply -f istio-np-2.yaml -n np-test-2`
```

![Output of applying the istio-np manifests](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-03.jpg)

### Step 2: Verify Initial Connectivity

Use curl to verify that the two pods can communicate:

```
`POD_A="$(kubectl get pod -n mesh-ns-a -l app.kubernetes.io/name=ng-a -o jsonpath='{.items[0].metadata.name}')" kubectl exec -n mesh-ns-a -it "$POD_A" -- \ sh -lc 'curl -fsS --max-time 3 http://web-ng-b.mesh-ns-b.svc.cluster.local:82/ || echo "Failed calling ng-b"' POD_B="$(kubectl get pod -n mesh-ns-b -l app.kubernetes.io/name=ng-b -o jsonpath='{.items[0].metadata.name}')" kubectl exec -n mesh-ns-b -it "$POD_B" -- \ sh -lc 'curl -fsS --max-time 3 http://web-ng-a.mesh-ns-a.svc.cluster.local:81/ || echo "Failed calling ng-a"'`
```

Expected output:

```
`Hello from ng-b (ns demo)! Hello from ng-a (ns demo)!`
```

![Output of the initial connectivity check between ng-a and ng-b](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-04.jpg)

### Step 3: Block Traffic Using Istio AuthorizationPolicy

Create the following policy to deny all ingress in np-test-2:

```
`apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ap-deny-all-inbound namespace: mesh-ns-b spec: action: DENY rules: - {} # deny every inbound request in this namespace`
```

Apply the policy:

```
`kubectl apply -f istio-deny-ingress-mesh-ns-b.yaml`
```

![Output of applying the Istio deny-all AuthorizationPolicy](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-05.jpg)

Test connectivity again:

Expected output:

```
`Failed calling ng-b Hello from ng-a (ns demo)!`
```

![Output of the connectivity check after the Istio policy](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-06.jpg)

You can confirm the block by inspecting the sidecar proxy logs:

```
`POD_B="$(kubectl get pod -n mesh-ns-b -l app.kubernetes.io/name=ng-b -o jsonpath='{.items[0].metadata.name}')" kubectl logs -n mesh-ns-b "$POD_B" -c istio-proxy --tail=300 \ | grep -i rbac \ | grep -i deny`
```

![Output of the istio-proxy logs showing RBAC denials](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-07.jpg)

### Step 4: Block Traffic Using Kubernetes NetworkPolicy

Delete the Istio policy to test NetworkPolicy independently:

```
`kubectl delete -f istio-deny-ingress-mesh-ns-b.yaml`
```

![Output of deleting the Istio AuthorizationPolicy](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-08.jpg)

Create the following NetworkPolicy to block all ingress in np-test-2:

```
`apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: np-deny-all-inbound namespace: mesh-ns-b spec: podSelector: {} policyTypes: - Ingress ingress: []`
```

Apply the policy:

```
`kubectl apply -f k8s-np-deny-ingress-mesh-ns-b.yaml`
```

![Output of applying the Kubernetes NetworkPolicy](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-09.jpg)

Test connectivity again:

Expected output:

```
`Blocked (expected) calling ng-b Hello from ng-a (ns demo)!`
```

### Step 5: Debugging

Check which Istio policies are in effect:

```
`POD_B="$(kubectl get pod -n mesh-ns-b -l app.kubernetes.io/name=ng-b -o jsonpath='{.items[0].metadata.name}')" istioctl x authz check "$POD_B" -n mesh-ns-b`
```

To debug NetworkPolicy issues, check the logs of your CNI:

For Calico:

```
`kubectl logs -n kube-system -l k8s-app=calico-node`
```

![Output of the calico-node logs](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-10.jpg)

For kube-router:

```
`kubectl logs -n kube-system -l k8s-app=kube-router`
```

### Step 6: Cleanup

```
`# remove policies (new file names) kubectl delete -f k8s-np-deny-ingress-mesh-ns-b.yaml kubectl delete -f istio-deny-ingress-mesh-ns-b.yaml # remove workloads (delete by reusing the same template vars) APP_ID=ng-a SVC_PORT=81 POD_PORT=8081 envsubst < mesh-workloads.yaml.tpl | kubectl delete -n mesh-ns-a -f - || true APP_ID=ng-b SVC_PORT=82 POD_PORT=8082 envsubst < mesh-workloads.yaml.tpl | kubectl delete -n mesh-ns-b -f - || true # delete namespaces kubectl delete namespace mesh-ns-a kubectl delete namespace mesh-ns-b # delete local files rm -f mesh-workloads.yaml.tpl istio-deny-ingress-mesh-ns-b.yaml k8s-np-deny-ingress-mesh-ns-b.yaml`
```

![Output of the cleanup commands](https://www.tigera.io/app/uploads/2026/10/istio-network-policy-tutorial-11.jpg)

## Validating and Troubleshooting Istio with Network Policy Enforcement

When traffic fails between services, identifying whether the block comes from Istio or a Kubernetes network policy is critical. Because enforcement happens at different layers, the source of the failure determines the tools and techniques used to resolve it.

To detect whether a **deny** is caused by Istio, inspect the Envoy proxy logs attached to the pod. Look for messages indicating authorization denials, such as missing JWTs or denied principals.

Use istioctl proxy-config to view the effective configuration, and istioctl pc routes or pc authz to verify policy rules applied to a workload. For dynamic runtime insights, distributed tracing tools (e.g., Jaeger) can reveal where requests are dropped within the service mesh.

If the failure originates from the **network layer**, use kubectl get networkpolicies to review applied Kubernetes network policies. Network plug-ins like Calico or Cilium often provide their own diagnostics (calicoctl, cilium status) and flow logs to confirm if packets are dropped at the interface level. Packet capture tools (e.g., tcpdump) can also help confirm whether traffic reaches the pod at all.

Common failure modes include:

- **Missing Istio sidecar injection**, causing no L7 enforcement but unexpected L3/L4 blocks

- **Allow rules in Istio, but deny rules in Kubernetes**, leading to confusion when traffic is blocked early

- **Policy overlaps**, where both systems permit different subsets of traffic, creating gaps or unintentional blocks

- **Latency-sensitive services degraded by heavy policy evaluation**, especially when too many rules are evaluated per request

To validate policies across both layers, simulate traffic using tools like curl, netcat, or istioctl experimental describe workload, and check both Envoy metrics and CNI plugin logs. Building a testing strategy with staged deployments and synthetic probes can help catch misconfigurations before they reach production.

<!-- plugin=object-cache-pro client=phpredis metric#hits=6592 metric#misses=17 metric#hit-ratio=99.7 metric#bytes=2555806 metric#prefetches=436 metric#store-reads=31 metric#store-writes=31 metric#store-hits=447 metric#store-misses=7 metric#sql-queries=33 metric#ms-total=797.83 metric#ms-cache=16.39 metric#ms-cache-avg=0.2687 metric#ms-cache-ratio=2.1 -->
