This article is based on reporting originally published at containerjournal.com.
Why Kubernetes Default Configurations Are Not Enough
Many organizations deploy Kubernetes as-shipped, assuming the defaults provide a reasonable security baseline. They do not. Kubernetes is designed around developer velocity — getting containers into production quickly — and its out-of-the-box settings reflect that priority. Security is largely left as an exercise for the operator.
This gap has real consequences. According to a survey of 540 IT professionals conducted by Kubernetes security platform provider StackRox (referenced in its State of Container and Kubernetes Security Report), 39% of respondents said their organizations adopted Kubernetes primarily to ship applications faster. Yet nearly half (44%) of those same organizations had delayed moving applications to production because of security concerns — meaning the very agility they sought was undermined by security gaps in their configurations.
Where the Default Configuration Falls Short
Unrestricted Network Policies
Kubernetes network policies work similarly to firewall rules: they control which pods can communicate with which endpoints. By default, however, no network policies are applied, which means every pod can communicate freely with every other component in the cluster. If an attacker compromises a single pod, that default permissiveness gives them a wide lateral movement surface across your entire environment.
Weak Secrets Management
Kubernetes Secrets are intended to store sensitive data such as encryption keys, API tokens, and credentials. However, the default behaviour leaves them exposed in several ways:
- Any user with permission to create a Pod that references a Secret can read that Secret’s value by simply running the Pod.
- Any user or process with root access to a Kubernetes node can read any Secret from the API server.
These weaknesses mean that an attacker who compromises a privileged account — or gains node-level access — can harvest sensitive data without needing to break any encryption.
Custom Configurations That Improve Security
The following hardening steps address the most common default-configuration weaknesses. They should be treated as a starting point, not a complete checklist.
1. Restrict watch and list RBAC Permissions on Secrets
The watch and list verbs on the secrets resource allow a caller to enumerate and observe the values of every Secret in a namespace. Granting these broadly — for example, to application service accounts — is a common misconfiguration.
Best practice is to restrict these verbs to only the system-level components that genuinely require them. Application workloads should instead use get on specific, named Secrets, nothing broader. This follows Kubernetes’ own secrets management guidance around least-privilege RBAC.
# Example: a restrictive Role that allows reading a specific Secret only
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: my-app
name: secret-reader
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["my-app-secret"]
verbs: ["get"]Code language: PHP (php)
2. Define Stricter Network Policies
StackRox recommends a deny-by-default network posture. The approach has two steps:
- Apply a default-deny policy to all new namespaces. This blocks all ingress and egress traffic unless explicitly permitted, containing any compromised pod to its own network segment.
- Use labels to whitelist required communication paths. Once a deny-all baseline is in place, add explicit
NetworkPolicyobjects that permit only the pod-to-pod or pod-to-internet traffic your application actually needs. Restrict inter-namespace traffic so pods in namespace A cannot reach pods in namespace B unless a policy explicitly allows it.
# Default-deny all ingress and egress in a namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressCode language: PHP (php)
Note: Network policies are enforced by the Container Network Interface (CNI) plugin. Not all CNI plugins support NetworkPolicy. Verify that your chosen CNI — such as Calico, Cilium, or Weave Net — enforces policies before relying on them for security.
3. Enable and Configure Pod Security Policies (or Their Replacements)
Pod Security Policies (PSP) allow cluster administrators to define a set of conditions that a pod must meet before it is admitted to the cluster. To activate PSP enforcement, the PodSecurityPolicy admission controller must be enabled on the API server:
kube-apiserver --enable-admission-plugins=PodSecurityPolicy
A restrictive baseline PSP should at minimum:
- Require all containers to run as a non-root user.
- Disallow privilege escalation (
allowPrivilegeEscalation: false). - Drop all Linux capabilities and add back only those explicitly needed.
- Enforce read-only root filesystems where possible.
- Disallow host network, host PID, and host IPC namespaces.
Important deprecation notice: PodSecurityPolicy was deprecated in Kubernetes 1.21 and removed in Kubernetes 1.25. For clusters running 1.25 or later, use the built-in Pod Security Admission controller with PodSecurity labels on namespaces, or a policy engine such as OPA Gatekeeper or Kyverno.
Ongoing Monitoring Is Essential
Hardening configuration is not a one-time task. Clusters evolve: new workloads are deployed, new team members are granted access, and infrastructure changes. Organizations should implement continuous monitoring to detect:
- Drift from approved network policy configurations.
- New pods running with elevated privileges.
- Unexpected RBAC role bindings, especially those granting broad Secret access.
- Anomalous API server activity or unexpected lateral movement between namespaces.
Tools such as Falco (runtime security), kube-bench (CIS benchmark scanning), and commercial Kubernetes security platforms can automate much of this monitoring and alert teams to deviations before they become incidents.
Summary
| Area | Default Risk | Recommended Action |
|---|---|---|
| Network Policies | All pods can communicate freely | Apply default-deny; whitelist required traffic with labels |
| Secrets RBAC | watch/list broadly granted | Restrict to named Secrets with get only for workloads |
| Pod Privileges | Containers may run as root | Enable Pod Security Admission or a policy engine; enforce non-root, no privilege escalation |
| Ongoing Posture | No alerting on configuration drift | Deploy runtime monitoring (e.g., Falco) and periodic CIS benchmark scans |
Kubernetes defaults are designed for convenience, not defence-in-depth. Taking the time to configure network policies, tighten RBAC for Secrets, and enforce pod-level security constraints will significantly reduce the attack surface of any production cluster.