
September 09, 2026
10 min read
By Kokil Thapa | Last reviewed: September 2026
Kubernetes Security: Pod Security and Network Policies are the two controls most teams under-deploy until something breaks in production. Pod Security Standards stop workloads from running as root or mounting host paths. Network Policies segment traffic so a compromised pod cannot reach every service in the cluster. If you run Laravel or API workloads on Kubernetes, these layers sit below your application firewall and deserve the same attention as Linux hardening on the nodes themselves.
What is Kubernetes pod security and why does it matter?
Pod security controls what a container is allowed to do before it ever talks to the network. In 2026, that means Pod Security Standards (PSS) — three built-in profiles shipped with Kubernetes 1.25 and later. PodSecurityPolicy (PSP) was removed; PSS replaced it with simpler namespace-level enforcement.
Each profile defines allowed capabilities:
- Privileged — unrestricted; use only for system components like CNI or storage drivers.
- Baseline — blocks known privilege escalations but allows common legacy patterns.
- Restricted — non-root users, dropped capabilities, no host namespaces; best for application workloads.
On real client projects, the gap is rarely malicious intent. A developer copies a Docker Compose file into a Deployment and sets privileged: true because a local volume mount failed. PSS catches that at admission time instead of during a penetration test.
Enabling Pod Security on a namespace
Apply labels to each namespace. Start with audit mode, read the logs, then switch to enforce:
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted The built-in pod-security admission plugin reads these labels. No extra controller is required on a standard cluster. Pair PSS with seccomp profiles and read-only root filesystems for defense in depth.
How do Pod Security Standards compare to legacy PodSecurityPolicy?
PSP was powerful but painful. Cluster admins wrote complex RBAC so teams could bind policies. Upgrades broke silently. PSS inverts the model: Kubernetes ships three opinionated profiles, and you label namespaces.
| Criteria | PodSecurityPolicy (removed) | Pod Security Standards |
|---|---|---|
| Configuration | Custom PSP objects + RBAC bindings | Three namespace labels |
| Enforcement point | Admission controller + authz | Built-in Pod Security admission |
| Granularity | Per-policy, highly flexible | Three fixed profiles |
| Operational cost | High — drift across teams | Low — label-driven defaults |
| Custom exceptions | Native via policy objects | Requires exempt namespaces or tools like Kyverno or OPA Gatekeeper |
For most application namespaces, restricted PSS plus a dedicated privileged namespace for operators is enough. Reserve custom policy engines for orgs that need PCI-style exceptions documented as code.
How do you write and apply Kubernetes Network Policies?
Network Policies are Kubernetes API objects. They only work if your CNI supports them — Calico, Cilium, and Weave do; basic Flannel without an overlay policy engine does not. A common production mistake is writing policies on a cluster where they are silently ignored.
Read the companion guide on Kubernetes Network Policies explained for CNI-specific notes. The pattern below works on any compliant CNI.
Step 1: Default deny all traffic in the namespace
Without a default deny, every pod can reach every pod. That is the Kubernetes default, and it is too open for production.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress This policy selects all pods and declares both ingress and egress types with no rules. Result: all traffic blocked except DNS if you add a separate egress rule (see step 3).
Step 2: Allow ingress from the ingress controller only
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-ingress-nginx
namespace: production
spec:
podSelector:
matchLabels:
app: laravel-api
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
podSelector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
ports:
- protocol: TCP
port: 8080 Label your ingress namespace consistently. The policy above permits only nginx pods to reach the Laravel API on port 8080.
Step 3: Allow egress to the database and DNS
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-api-egress
namespace: production
spec:
podSelector:
matchLabels:
app: laravel-api
policyTypes:
- Egress
egress:
- to:
- podSelector:
matchLabels:
app: mysql
ports:
- protocol: TCP
port: 3306
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53 Validate with kubectl exec and curl from a debug pod. If a connection hangs, the policy is working — or your CNI is not.
How do Pod Security and Network Policies work together?
Pod Security answers "what can this container do on the node?" Network Policies answer "who can this pod talk to?" They are complementary, not interchangeable. A restricted pod that cannot escalate privileges may still exfiltrate data if egress is open to the internet.
Layer them in this order:
- Harden nodes — patch Ubuntu, restrict SSH, enable auditd. See Ubuntu server security best practices.
- Apply restricted PSS to application namespaces; keep kube-system privileged.
- Deploy default-deny Network Policies per namespace.
- Add allow rules service by service as you deploy.
- Run runtime detection with Falco for Kubernetes runtime security.
- Scan images — use distroless base images where possible.
I've seen teams skip step 3 because staging "worked fine." Production microservices talk to dozens of internal endpoints. Without default deny, lateral movement after one compromised pod is trivial.
Mapping workloads to namespaces
A practical namespace layout for a multi-service enterprise application:
production— enforce restricted, default-deny network policies.staging— enforce baseline, audit restricted, relaxed egress for debugging.platform— privileged for monitoring agents and log collectors.ingress-nginx— baseline; needs hostNetwork on some setups.
Document the label scheme in your runbook. Future you — or the next contractor — should not guess why staging accepts runAsUser: 0.
What are common mistakes when implementing Kubernetes security policies?
These failures show up repeatedly across clusters I help troubleshoot, including platforms similar to the booking systems on Adventure Third Pole Trek where uptime and data isolation both matter.
Mistake 1: Enforcing restricted PSS without fixing manifests
Restricted requires runAsNonRoot: true, dropped capabilities, and a seccomp profile. Old Deployments fail admission with opaque errors. Fix the pod spec first:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL Roll out in audit mode for one sprint. Collect violations from the API audit log before flipping enforce.
Mistake 2: Network Policies without DNS egress
Pods that cannot resolve names appear "broken." Every namespace with egress restrictions needs a kube-dns allow rule. Test with nslookup kubernetes.default from an app pod after applying policies.
Mistake 3: Forgetting control plane and webhook traffic
Admission webhooks, metrics scrapers, and service mesh sidecars inject pods that need their own policies. Istio and Linkerd add sidecar containers; your NetworkPolicy must allow the data plane ports or health checks fail.
Mistake 4: No visibility after lockdown
Policy enforcement without observability breeds shadow IT workarounds. Export denied connection metrics from Cilium or Calico. Correlate with Tetragon eBPF audit events when you need syscall-level detail.
Testing policies before production
Use a throwaway namespace mirroring production labels. Deploy a debug pod and run connectivity tests. Store policy YAML in Git and apply through your pipeline — the same GitLab CI pattern I use on Kubespray-deployed clusters.
For API-heavy stacks, align network boundaries with your API security checklist. Internal service tokens mean nothing if any pod can reach the admin endpoint on port 8080.
How do you validate and monitor policy compliance?
Admission decisions generate audit events when audit mode is on. Query them with your logging stack or kubectl get events filtered by reason FailedCreate.
Useful checks after every deploy:
kubectl auth can-i create pods --namespace=production— confirm RBAC still works.kubectl label namespace production --list— verify PSS labels survived a helm upgrade.- Network policy hit counters — Cilium
cilium policy getor Calico flow logs. - Periodic namespace scans with
kubectl get pods -A -o jsonpiped through JSON formatter tools to find pods missing security contexts.
Policy-as-code tools extend PSS when three profiles are not enough. Compare options in the Kyverno vs OPA Gatekeeper guide. For teams without dedicated platform engineers, PSS labels plus hand-written NetworkPolicy YAML beats a complex policy engine you never maintain.
External references worth bookmarking: the official NetworkPolicy documentation and the CNCF project landscape for CNI and runtime security tooling choices.
Key Takeaways
- Apply Pod Security Standards via namespace labels — audit first, then enforce restricted on app namespaces.
- Start every production namespace with a default-deny NetworkPolicy before adding explicit allow rules.
- Confirm your CNI actually enforces Network Policies; policies on unsupported CNIs provide false confidence.
- Fix pod securityContext in manifests before switching PSS to enforce mode to avoid deployment outages.
- Always allow DNS egress when restricting pod egress, or services fail with misleading timeout errors.
- Combine PSS, Network Policies, distroless images, and runtime monitoring for workable defense in depth.
People Also Ask
Are Network Policies enabled by default in Kubernetes?
No. Kubernetes ships the NetworkPolicy API, but enforcement depends entirely on your CNI plugin. Clusters using plain Flannel or older configurations may accept NetworkPolicy objects without blocking any traffic. Verify with a test deny policy before relying on segmentation in production.
What happens when a pod violates Pod Security Standards?
With enforce mode active, the Pod Security admission plugin rejects the create or update request. The pod never schedules. In warn mode, the pod is created but the API server returns a warning. Audit mode logs the violation to the audit log without blocking or warning the caller.
Can I use Pod Security and Network Policies with managed Kubernetes?
Yes. EKS, GKE, and AKS all support PSS namespace labels on supported versions. Managed offerings typically ship with policy-capable CNIs — for example Calico on EKS or Azure CNI with network policy add-ons. Check your provider docs for the exact enablement flag.
Do Network Policies affect traffic leaving the cluster to the internet?
Yes, if you include egress rules. A default-deny egress policy blocks outbound internet access unless you add an allow rule to external CIDR blocks or a namespace running an egress gateway. Many teams allow egress to 0.0.0.0/0 on ports 443 and 80 initially, then tighten based on flow logs.
Build a cluster security baseline you can maintain
Kubernetes Security: Pod Security and Network Policies is not a one-time hardening sprint. It is a baseline you extend every time a new service ships. Label namespaces, deny by default, allow deliberately, and fix manifests before enforcement breaks your pipeline. If you want help designing that baseline for a production platform — or hardening the Linux layer underneath — contact us or explore testing and optimization services. Solid pod and network policy now saves a painful incident later.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

