A Kubernetes cluster in production for four months. No NetworkPolicies. ServiceAccount with cluster-admin permissions. Images pulled from public Docker Hub without scanning. This was a real environment with customer data. Unfortunately, this scenario is not an exception but a widespread reality in many organizations. The rush to containerization and orchestration often leads to neglecting security fundamentals, exposing sensitive data and critical infrastructure to extremely high risks. Kubernetes‘ inherent complexity, with its myriad components and configurations, can intimidate even the most experienced teams, leading to insecure default choices or rushed configurations that become black holes in cyber defense.
When exposing a Kubernetes cluster, even for a test environment that later becomes ‘production,’ security must be an absolute priority from day one. A single misconfiguration can have devastating consequences, from data compromise to service disruption. This article provides an operational 12-point checklist to ensure your Kubernetes environment is robust and resilient against the most common threats, based on years of field experience managing complex enterprise infrastructures. Adopting these best practices is not just about compliance but a direct investment in operational continuity and business protection.
Prerequisites / Test Environment
To follow this guide, you will need a working Kubernetes cluster (Minikube, Kind, or a cloud cluster like EKS/AKS/GKE) with kubectl access configured. Some commands require helm and jq installed. The ideal test environment should replicate, as much as possible, the conditions of a production environment, even with a limited workload. Ensure you have administrative permissions for the cluster to apply the described configurations.
1-2: API Server — Authentication and Minimal RBAC
The API Server is the heart of Kubernetes, the access point for all cluster controls. Its security is paramount. Implementing robust authentication is the first step, preferring mechanisms like client certificates, OIDC (OpenID Connect), or Webhook Token Authentication over simple ServiceAccount tokens for human users. For ServiceAccounts, applying the principle of least privilege is crucial.
RBAC (Role-Based Access Control) is key to limiting access. A common mistake is granting cluster-admin permissions to ServiceAccounts or users who do not need them. This is a huge security risk. 73% of Kubernetes cluster attacks exploit credentials with excessive privileges (Red Hat, 2024). Regularly verify who has these permissions:
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin")'
Analyze the output and remove any bindings not strictly necessary. For each ServiceAccount and user, define specific roles and rolebindings that grant only the essential permissions for their functions. For example, an application that only needs to read Pods in a namespace should not have permissions to create Deployments at the cluster level.
3-4: Pod Security — Non-Root, Read-Only, SecurityContext
Pods are the deployment units in Kubernetes. Their security configuration is fundamental to preventing privilege escalation and attacks. Adopt Pod Security Standards (PSS) or, for more granular control, Pod Security Policies (PSP) (though deprecated, their spirit lives on in PSS).
Run containers as a non-root user: Many default Docker images run processes as root. This is a significant risk. Specifying a runAsUser in the securityContext of the Pod or Container is a best practice. For example:
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: my-app
image: my-image:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
readOnlyRootFilesystem: true: Prevents applications from writing to the container’s root filesystem, limiting damage in case of compromise. Data persistence should only occur on specific, well-controlled volumes.
5-6: Network Policy — Default Deny, Namespace Isolation
By default, Pods in Kubernetes can communicate freely with each other. This is a huge risk in a multi-tenant environment or with different applications. Network Policies are essential for segmenting traffic at the Pod/Namespace level.
Implement a default-deny policy: The first step is to block all inbound and outbound traffic in a namespace, and then explicitly allow only what is necessary. This zero-trust approach drastically reduces the attack surface. Approximately 60% of production clusters do not implement Network Policies (Datadog, 2023).
kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
EOF
After applying this policy, no Pod in the default namespace will be able to communicate externally or with other Pods, unless specific Network Policies are created to allow the necessary traffic. This is a drastic change that requires planning but is vital for isolation.
7-8: Secrets — Encryption at Rest, External Secrets Operator
Managing secrets (API keys, passwords, tokens) is one of the biggest challenges in Kubernetes. Kubernetes Secrets are Base64 encoded, not encrypted, and this is not sufficient for production.
Encryption at rest: Ensure your Cloud Provider (or your on-premise setup) encrypts etcd data, where Secrets are stored. Use a Key Management System (KMS) for Secret encryption. For example, GKE and EKS offer native integrations with their KMS.
External Secrets Operator: For more robust management, integrate Kubernetes with external Secret Managers like HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, or Google Secret Manager. The External Secrets Operator synchronizes secrets from these external systems with Kubernetes Secrets, avoiding direct storage of secrets in etcd.
9-10: Image — Private Registry, Admission Controller, Scan
Container images are the foundation of your applications. Their security is a critical point.
Private registry: Do not pull images directly from public Docker Hub in production. Use a private registry (e.g., Harbor, ECR, GCR, ACR) where you have complete control over images and their origin.
Admission Controller for security: Implement Admission Controllers like Kyverno or OPA Gatekeeper to enforce security policies on images. You can block the deployment of images from unauthorized registries, images with known vulnerabilities, or images that do not comply with Pod Security Standards.
Vulnerability scanning: Every image in your private registry must be regularly scanned for vulnerabilities. Tools like Clair, Trivy, or Anchore can be integrated into the CI/CD pipeline to automate this process. An image with critical CVEs should never reach production. 45% of container images in production contain at least one critical vulnerability (Snyk, 2024).
11-12: Audit Logs and Runtime Security with Falco
Even with all precautions, an attack can still occur. Having visibility into what happens in the cluster is fundamental.
Audit Logs: Enable and centralize Kubernetes audit logs. These logs record all requests to the API Server and are crucial for forensic analysis and detecting suspicious activity. Integrate them with your SIEM (Security Information and Event Management) or EDR (Endpoint Detection and Response) for advanced correlation.
Runtime Security with Falco: Falco is an open-source threat detection engine that monitors container and Linux kernel activity. It allows you to detect anomalous behaviors such as shell executions in containers, modifications to critical system files, or unexpected network connections. Installing Falco is relatively simple via Helm:
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco --set falco.grpc.enabled=true
Falco can generate real-time alerts, integrating with notification systems like Slack, PagerDuty, or your SIEM.
kube-bench: Automated CIS Benchmark Audit in 5 Minutes
For a quick and automated audit of your cluster’s compliance with CIS (Center for Internet Security) Benchmark security standards, kube-bench is an indispensable tool. It helps you quickly identify non-compliant configurations.
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs job/kube-bench
By running these commands, kube-bench will be deployed as a Job in your cluster and will perform a scan, providing a detailed report on any CIS Benchmark violations. This is an excellent starting point for identifying areas that need further hardening.
Common Errors and Troubleshooting
One of the most common errors is applying overly restrictive Network Policies without adequate testing, blocking legitimate traffic and causing service disruptions. Always start with permissive policies and gradually restrict them, or test them in a staging environment. Another mistake is underestimating the impact of RBAC changes: a missing permission can block an entire application. Use kubectl auth can-i to test the permissions of a user or ServiceAccount.
When implementing Pod Security Standards, legacy applications might not be compatible with stricter requirements (e.g., readOnlyRootFilesystem). In these cases, consider containerizing the application differently or isolating it in a namespace with less restrictive policies, but always carefully monitored.
FAQ — Frequently Asked Questions
What is the difference between Pod Security Standards (PSS) and Pod Security Policies (PSP)?
Pod Security Policies (PSP) were deprecated in Kubernetes 1.25. Pod Security Standards (PSS) are their successor and provide three policy levels (Privileged, Baseline, Restricted) that can be applied at the namespace or cluster level via Admission Controllers. They are simpler to configure and manage than PSPs.
How can I test the effectiveness of my Network Policies?
You can use tools like netshoot or debug containers to perform connectivity tests between pods. Deploy a temporary pod in a namespace and attempt to reach other pods or services. The output will tell you if the connection is allowed or blocked by the Network Policy.
Is using only a private registry sufficient for image security?
A private registry is an excellent starting point, but it’s not enough on its own. You need to combine a private registry with automated image vulnerability scanning (e.g., Trivy, Clair) and, ideally, with Admission Controllers that block the deployment of non-compliant images or images with known CVEs. This creates a multi-layered defense.
What is the risk of using ServiceAccounts with cluster-admin permissions?
Granting cluster-admin permissions to a ServiceAccount is extremely risky. If an attacker compromises a Pod using that ServiceAccount, they would have full access to the cluster, being able to create, modify, or delete any resource, including other Pods, Secrets, and even the API Server itself. It is one of the primary causes of Kubernetes cluster compromises.
Conclusions with Operational Takeaways
Kubernetes security is a continuous process, not a single event. Adopting a rigorous checklist before exposing a cluster to production is the first step toward building a resilient environment. Remember to:
- Apply the principle of least privilege for RBAC and ServiceAccounts.
- Isolate workloads with
default-denyNetwork Policies. - Protect Secrets with
at restencryption and external Secret Managers. - Ensure image integrity with private registries, vulnerability scans, and Admission Controllers.
- Actively monitor with audit logs and runtime security like Falco.
Each point in this checklist reduces the attack surface and increases the ability to detect and respond to potential threats. Don’t wait until it’s too late. Implement these measures today to protect your data and infrastructure.
Read also
Read also: Docker Production Security: 10 Overlooked Best Practices (2026)
Read also: Zero Trust VPN: The End of Traditional VPNs by 2026
Read also: AD Hardening: 10 Critical Settings to Check Now (2026)
Updated: June 2026