Kubernetes security is a collection of controls, not a single switch. The practical goal is to reduce unnecessary privilege, limit blast radius, and make suspicious behavior visible.
1. Start with least privilege
Use namespace-scoped Roles wherever possible and grant only the verbs and resources each workload needs. Keep cluster-admin access exceptional, time-bound, and auditable.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: app-reader
rules:
- apiGroups: [""]
resources: ["pods", "services"]
verbs: ["get", "list"]2. Enforce workload boundaries
Enable Pod Security Admission and use the restricted profile for production namespaces. Add network policies, image scanning, and admission checks so a compromised workload cannot move freely through the cluster.
3. Treat images as release artifacts
Build images from minimal, pinned base images and scan them before they reach a registry. Sign trusted artifacts, reject known-critical vulnerabilities according to an agreed policy, and rebuild regularly for operating-system patches.
trivy image --severity HIGH,CRITICAL --exit-code 1 registry.example.com/orders:1.4.2
# Verify the image before promotion, not after production deployment4. Protect secrets and the control plane
Kubernetes Secrets are not a complete secrets-management strategy. Restrict access to the API server, encrypt secret data at rest, avoid putting credentials in images or manifests, and integrate with a managed store such as AWS Secrets Manager or an equivalent vault.
A secret that is readable by every service account in a namespace is not protected. Access should be explicit, minimal, rotated, and observable.
5. Apply network policy deliberately
Start with an inventory of expected traffic between namespaces and services. Default-deny policies are useful only when DNS, metrics, ingress, and required service flows are allowed intentionally. Roll them out in observe, report, and enforce stages.
6. Make audit events useful
Enable API audit logging with a policy that captures privileged actions without drowning the team in routine read traffic. Send events to durable storage and alert on role changes, secret access, unexpected exec sessions, and disabled admission controls.
7. Design runtime response
Runtime tools such as Falco can identify unexpected shells, sensitive file access, and unusual process behavior. Define the response before enabling alerts: who investigates, what evidence is retained, and when a workload is isolated or redeployed.
8. Test the controls
Security checks belong in pull requests and cluster reviews. Test RBAC with impersonation, validate admission policies against representative manifests, and rehearse credential rotation. A control that has never been exercised is an assumption.
- Map identities, namespaces, and trust boundaries
- Remove broad permissions and verify with impersonation
- Scan and sign images before promotion
- Enforce pod, network, and admission policy in stages
- Monitor privileged actions and rehearse incident response
9. Protect recovery paths
Back up cluster state and application data according to recovery objectives, then test restoration in an isolated environment. A secure cluster that cannot recover from deletion, corruption, or ransomware is only secure until the first serious incident.
10. Make security observable
Protect etcd, enable audit logs, scan images with tools such as Trivy, and route runtime signals to a system the team actually monitors. Controls without useful alerts become configuration noise.
Review the controls after every major platform change. The cluster is a living system: new controllers, operators, admission policies, and service accounts can change the threat model without changing the application code.
Roll controls out like software
Start in audit mode where the control supports it, capture the workloads it would block, and give each exception an owner and expiry. Then enforce in a representative namespace before expanding the policy. NetworkPolicy only filters traffic when the cluster CNI actually enforces it; an elegant YAML file without an enforcing dataplane is security theater with indentation.
Security is less a wall than a series of doors with named owners. The design question is what each identity can do after one door is opened.
A useful threat-model question
Never treat a passing deployment as proof of security. Review permissions and runtime behavior continuously as the platform changes.