Sitemap
Press enter or click to view image in full size
Inside Kubernetes, trust nothing by default.

Kubernetes Network Policies Explained: Building Zero-Trust Networking

--

One of the biggest misconceptions in Kubernetes is this:

“My workloads are inside the cluster, so they’re already secure.”

Not necessarily.

By default, most Kubernetes clusters are surprisingly open internally.

Unless you explicitly restrict traffic:

  • Any Pod may communicate with almost any other Pod
  • Across namespaces
  • Across applications
  • Across environments

That’s convenient for getting started.

But in production?
It’s a serious security risk.

This is exactly why Network Policies exist.

They allow you to move from:

“Everything can talk to everything”

to:

“Only explicitly allowed communication is permitted.”

In other words:

Zero-trust networking inside Kubernetes.

Let’s break down how it works.

Why Internal Cluster Networking Is Risky

In traditional environments, internal networks were often considered:

  • Trusted
  • Private
  • Safe

Modern security thinking has changed that completely.

Today’s assumption is:

Breaches happen.

The important question becomes:

“How far can an attacker move after compromise?”

Without network restrictions:

  • One compromised Pod can scan or access many others
  • Lateral movement becomes easy

That’s exactly what zero-trust networking tries to prevent.

The Default Kubernetes Networking Model

Most Kubernetes CNIs allow:

Any Pod → Any Pod

by default.

Example:

frontend Pod → database Pod
random Pod → payment API
test namespace → production services

Everything may be reachable internally unless policies exist.

What Is a Kubernetes Network Policy?

A Network Policy defines:

Which traffic is allowed between Pods.

Think of it as:

  • A Kubernetes-native firewall
  • Applied at Pod level

Policies control:

  • Ingress traffic
  • Egress traffic

Important Concept: Policies Are Allow Rules

Network Policies are:

Whitelist-based.

Meaning:

  • Once policies apply to a Pod
  • Only explicitly allowed traffic is permitted

Everything else becomes denied implicitly.

That’s a critical mindset shift.

First: Ingress vs Egress

Ingress Policy

Controls:

Incoming traffic TO a Pod

Example:

  • Which Pods may access database

Egress Policy

Controls:

Outgoing traffic FROM a Pod

Example:

  • Which external APIs app can call

Real Example: Protecting a Database

Imagine:

frontend → backend → database

You want:

  • Only backend Pods to reach database

Without policy:

  • Any Pod may access database

That’s dangerous.

Example Network Policy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-backend-to-db
spec:
podSelector:
matchLabels:
app: database
ingress:
- from:
- podSelector:
matchLabels:
app: backend

Meaning:

Only Pods labeled app=backend may connect to database Pods.

What Happens Now

Allowed:

backend → database

Blocked:

frontend → database
random Pod → database

This dramatically reduces lateral movement risk.

Zero Trust Starts with Default Deny

One of the most important patterns is:

Default deny policy.

Example:

spec:
podSelector: {}
policyTypes:
- Ingress

This blocks:

  • All ingress traffic
  • Unless explicitly allowed

Now communication becomes:

Intentional instead of implicit.

Real Production Pattern

Typical production architecture:

Internet
↓
Ingress Controller
↓
Frontend
↓
Backend API
↓
Database

Policies enforce:

  • Frontend cannot reach database
  • Only backend accesses database
  • Monitoring namespace allowed selectively
  • External internet access restricted

This creates:

Layered internal security boundaries.

Egress Policies: The Often-Ignored Half

Most teams focus only on ingress.

But egress matters enormously.

Why Egress Policies Matter

Compromised applications often:

  • Exfiltrate data
  • Contact malicious services
  • Scan external systems

Egress policies limit:

Get TheVega.AI’s stories in your inbox

Join Medium for free to get updates from this writer.

Where workloads can connect outward.

Real Example

Application only needs access to:

api.stripe.com
internal-auth-service

Egress policy blocks:

  • Everything else

This reduces blast radius significantly.

Namespace Isolation

Policies can also isolate namespaces.

Example:

#Deny all
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-environment
namespace: prod
spec:
podSelector: {}
policyTypes:
- Ingress
---
#Allow same namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-namespace
namespace: prod
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {}

Without policies:

  • Dev workloads may accidentally access production services

With policies:

  • Cross-environment communication restricted

Critical for multi-team clusters.

Press enter or click to view image in full size
Zero-trust networking starts with default deny.

The CNI Dependency Most Teams Miss

Here’s something important:

Network Policies require CNI support.

Not all networking plugins enforce them equally.

Popular CNIs supporting policies include:

  • Calico
  • Cilium
  • Weave Net

Without compatible CNI:

  • Policies may exist
  • But enforcement won’t happen

This surprises many teams initially.

In Amazon EKS, NetworkPolicies are enforced only if your CNI supports them.
Modern EKS clusters can use Amazon VPC CNI Network Policy support, while Calico and Cilium are common alternatives. Always verify CNI compatibility before relying on NetworkPolicies for workload isolation.

Kubernetes NetworkPolicy = Intent

CNI = Enforcement Engine

Understanding Additive Policy Behavior

Case 1: Multiple Allow Policies

When multiple NetworkPolicies allow different sources, Kubernetes combines them. The effective access is the union of all allowed traffic.

Policy 1: Allow Backend
Policy 2: Allow Monitoring
Result:
Backend OR Monitoring can access the pod.

Key Point: NetworkPolicies are additive; multiple allow rules expand the allowed traffic.

Case 2: Default Deny + Specific Allow

A default deny policy blocks all traffic by default. Additional policies can then explicitly allow only the required communication paths.

Policy 1: Deny All
Policy 2: Allow Backend
Result:
Only Backend can access the pod.
All other traffic remains blocked.

Key Point: This is the foundation of a Zero Trust model — deny everything first, then allow only what is necessary.

Case 3: Allow and Deny the Same Source

Standard Kubernetes NetworkPolicies support only allow rules and do not provide explicit deny rules.

Policy 1: Allow Backend
Policy 2: Deny Backend
Result:
Not possible in native Kubernetes NetworkPolicy.

Key Point: Kubernetes evaluates only what is allowed. Since there are no deny rules, one policy cannot override or negate another. The effective access is always based on the combined set of allowed traffic.

Real-World Failure Scenario

A vulnerable Pod gets compromised.

Without Network Policies:

  • Attacker scans cluster freely
  • Internal services exposed
  • Databases reachable

With Network Policies:

  • Movement constrained immediately

This is the real value:

Containing breaches.

Common Mistakes

Assuming Policies Are Global Firewalls

Policies apply:

  • Per selected Pods

Not automatically cluster-wide.

Forgetting DNS Traffic

Pods often need:

  • DNS resolution

Blocking DNS accidentally causes:

  • Mysterious connectivity failures

Only Protecting Ingress

Egress matters equally for zero trust.

Creating Overly Permissive Rules

Example:

from:
- namespaceSelector: {}

This may unintentionally allow too much traffic.

Real Production Best Practices

Start with Default Deny

Then explicitly allow required communication.

Use Namespace Segmentation

Separate:

  • Dev
  • Staging
  • Production
  • Shared services

Protect Stateful Systems First

Databases and queues should rarely be broadly reachable.

Restrict Egress Gradually

Begin with:

  • Critical workloads
  • Sensitive namespaces

Monitor Before Tightening

Understand real traffic patterns first.

Otherwise:

  • You may accidentally break applications.

The Mental Model That Makes It Click

Think of Kubernetes networking like office building security:

Without Network Policies:

  • Every room unlocked

With Network Policies:

  • Access badges control movement room-by-room

That’s zero trust:

Never assume internal traffic is automatically safe.

Network Policies vs Traditional Firewalls

| Traditional Firewall    | Kubernetes Network Policy  |
| ----------------------- | -------------------------- |
| IP-based | Label-based |
| Infrastructure-centric | Workload-centric |
| Static | Dynamic |
| External boundary focus | Internal microsegmentation |

This shift is extremely important in cloud-native environments.

Why Zero Trust Matters More in Kubernetes

Kubernetes environments are:

  • Dynamic
  • Highly interconnected
  • Multi-tenant
  • API-driven

Traditional perimeter security alone is insufficient.

Internal segmentation becomes essential.

Final Takeaway

Kubernetes Network Policies are one of the most important — and most underused — security controls in modern clusters.

They help transform cluster networking from:

“Everything talks to everything”

into:

“Only explicitly trusted communication is allowed.”

That’s the foundation of zero-trust networking.

Because in distributed systems:

Security is no longer just about protecting the edge.
It’s about controlling movement inside the system itself.

Are you actively using Network Policies in production today, or are workloads still mostly open internally?
What challenges have you faced while implementing zero-trust networking in Kubernetes? Let’s discuss

--

--

TheVega.AI
TheVega.AI

Written by TheVega.AI

DevOps Engineer passionate about teaching and sharing knowledge. Writing about DevOps, SRE, Linux, Kubernetes, and computer science behind modern infrastructure