On this page
What Is a Kubernetes Network Policy?
By default every pod can reach every other pod. A network policy restricts that traffic to explicit flows, containing a compromise instead of letting it spread.
Quick answer
- A network policy is a firewall rule for pods, selecting which traffic is allowed to and from a set of pods.
- With no policies, a cluster is flat: every pod can reach every other pod and often the cloud metadata endpoint.
- Policies are additive within a selection: once a pod is selected by any policy, only explicitly allowed traffic is permitted.
- Most clusters should start from default-deny in a namespace and open only the flows the app needs.
- Policies control layer 3/4 traffic by labels; they do not inspect HTTP or replace application authorization.
What is a network policy?
A network policy selects a group of pods by label and declares which ingress (incoming) and egress (outgoing) traffic is allowed. It is enforced by the cluster’s network plugin, not by the pod itself, so a compromised container cannot talk its way past it. The policy is additive: the moment a pod is selected by at least one policy for a direction, all traffic in that direction is denied unless a rule allows it. That is why a single well-written policy can flip a namespace from wide open to closed.
What does the default allow?
Everything, in both directions, for every pod in the cluster. Any pod can open a connection to any other pod’s IP and port, and can generally reach the node’s metadata service and other cluster services. That flat network is convenient for development and is exactly what turns a single vulnerable service into a cluster-wide incident: the attacker’s container can reach your database directly, without ever touching the internet.
How do I write a default-deny policy?
Start by selecting every pod in a namespace with an empty pod selector and declaring no allowed ingress (and, if you are ready for it, no egress). Then add allow policies for the specific flows your app uses. The example below denies all ingress in the namespace; a companion policy would allow traffic to the API only from the frontend.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: app
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-from-frontend
namespace: app
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 3000What are the limits of network policies?
They operate at layer 3 and 4, so they allow or deny by address, label, and port — not by HTTP path or method. They do not encrypt traffic; use a service mesh or mTLS if you need that. Enforcement depends on your cluster’s network plugin actually supporting policy, which is worth verifying, and egress restrictions are often harder to get right because DNS and external services need explicit allowances. Treat policies as the containment layer, not the whole security model.
Where this bites vibecoders
AI assistants almost never generate network policies, because the application works without them and the manifests stay shorter. The consequence is a cluster where the attack surface of every service is every other service — a database with an app-layer bug is directly reachable from a compromised frontend, and the cloud metadata service is one HTTP request away. Writing even a handful of policies changes the shape of a breach from ‘attacker walks the cluster’ to ‘attacker is stuck in one container’.
Where AI coding assistants get this wrong
- Generating no network policies at all, leaving the cluster flat.
- Assuming a firewall or security group outside the cluster protects pod-to-pod traffic.
- Writing a default-deny policy and forgetting to allow DNS egress, breaking name resolution.
- Selecting pods by the wrong labels, so the policy silently applies to nothing.
- Believing network policies can filter HTTP paths or authenticate requests.
Checklist
- Add a default-deny ingress policy to each application namespace.
- Allow only the specific pod-to-pod flows the app needs.
- Allow DNS egress explicitly before restricting egress.
- Verify labels in the policy match the pods you intend to select.
- Confirm the cluster’s network plugin enforces policy.
- Keep an allow rule for health checks and the ingress controller.
FAQ
Do network policies work on every cluster?
No. They require a network plugin that enforces them, such as Calico, Cilium, or the default on many managed clusters. If the plugin does not support policy, the objects are accepted but have no effect, which is worse than no policy because it creates false confidence.
Should I deny all egress from my pods?
Eventually, yes, but egress is harder because DNS, registries, and external APIs need explicit allowances. A common path is to start with default-deny ingress, add egress restrictions for the most sensitive workloads, and expand from there.
How is a network policy different from a service mesh?
A network policy allows or denies layer 3/4 traffic between pods. A service mesh adds identity, mutual TLS, retries, and per-request policy on top. They complement each other: the policy narrows who can talk, the mesh secures and observes the conversation.
Related topics
- Kubernetes Security for AI Builders: Hardening the Cluster Your Assistant Configured
- The Kubernetes Security Checklist for AI-Built Clusters
- What Is Kubernetes RBAC (and What Did Your AI Grant Away)?
- What Is Zero Trust Architecture?
- What Is Kubernetes and Why Does My App Need It?
- What Is a Service Mesh?