Safeguard
Security Guides•

Kubernetes default deny network policy for microservices

Pods accept all traffic by default. See how a default deny NetworkPolicy works, why it needs a supporting network plugin, and how to open only needed paths.

Safeguard Security Team
3 min read

In Kubernetes, pods accept all inbound and outbound traffic until a NetworkPolicy selects them. A default deny policy selects every pod in a namespace and allows nothing, then you add small allow rules per service. It only works if your network plugin enforces NetworkPolicy.

The default is open

The Kubernetes documentation says pods are non-isolated for ingress and egress by default, so every connection is allowed. A pod becomes isolated for a direction only when a policy selects it and lists that direction in policyTypes. That is why a compromised pod in an unrestricted namespace can usually talk to every other pod, including your message broker.

The enforcement catch

NetworkPolicies are implemented by the network plugin. The documentation states that creating one has no effect unless your networking solution supports it. Test this: apply a deny policy to a scratch namespace and confirm a connection actually fails. A policy that is never enforced is a false comfort.

The default deny pattern

The standard example selects all pods in the namespace with an empty pod selector and lists Ingress in policyTypes with no ingress rules:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

An empty selector picks every pod in the namespace. With no ingress rules listed, inbound traffic is denied, apart from traffic from the pod's own node as the docs describe.

Add allow rules per path

Policies are additive. For a given pod and direction, allowed traffic is the union of all policies that apply, so order does not matter. That makes the model easy to reason about: start closed, add one allow rule per real dependency.

For a typical set of services, write an allow rule for each edge:

  1. Gateway to orders service on its service port.
  2. Orders service to the broker on the broker port.
  3. Billing consumer to the broker, nothing else.

Egress needs both sides

A connection needs the source pod's egress policy and the destination pod's ingress policy to both allow it. If you also deny egress by default, remember that pods still need DNS. This is general Kubernetes practice rather than something the policy page spells out in the part I read, so verify it in your cluster: add an explicit egress rule for your cluster DNS.

Roll it out safely

  1. Map real traffic first, using flow logs from your network plugin if it offers them.
  2. Apply default deny ingress in a staging namespace and fix what breaks.
  3. Add egress restrictions last, since they cause the most surprises.
  4. Keep policies in version control and review changes like code.

Network policy limits movement but does not prove identity. For that, pair it with mutual TLS between services.

Safeguard can help here in a small way. Its SBOM and dependency scanning covers the broker client libraries and service frameworks your code pulls in, and reachability analysis shows which advisories your services actually call. You can try a free scan at gold.safeguard.sh/scan.

Quick check

If I apply a NetworkPolicy, is my namespace protected?

Only if your network plugin enforces NetworkPolicy. Test with a connection that should fail.

Do multiple policies conflict?

No. They are additive, and the allowed traffic is the union of all applicable policies.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.