Kubernetes Security Misconfigurations: A Practical Checklist
A Kubernetes manifest that deploys cleanly and passes every functional test can still be a security problem - because nothing about a container running as root or a pod with no resource limits looks obviously wrong in a normal code review.
Containers Running as Root
Without an explicit securityContext, a container runs as root by default - meaning a container escape vulnerability hands an attacker root on the underlying node, not just a limited user.
1securityContext:
2 runAsNonRoot: true
3 runAsUser: 1000
4 allowPrivilegeEscalation: falseMissing Resource Limits
A pod with no CPU/memory limits can consume unbounded resources on its node - whether from a genuine traffic spike or a runaway process - starving every other workload scheduled there. This is an availability risk that looks identical to a normal capacity problem until you trace it back to one misbehaving pod with no ceiling.
1resources:
2 requests:
3 memory: "128Mi"
4 cpu: "250m"
5 limits:
6 memory: "256Mi"
7 cpu: "500m"Overly Broad RBAC
A ClusterRole granting * on * resources - copied from a tutorial and never scoped down - gives a workload far more access than it needs. If that workload is ever compromised, the attacker inherits every permission it was granted, cluster-wide.
- Grant only the specific verbs and resources a workload actually calls, not a blanket wildcard.
- Prefer a namespaced
Roleover aClusterRolewhen the workload only needs access within one namespace.
Secrets Mounted as Plain Environment Variables
Kubernetes Secret objects are only base64-encoded, not encrypted, by default - and a secret exposed as a plain environment variable is visible to anything that can read the pod spec or trigger a crash dump that includes the process environment. A dedicated secrets manager, or at minimum mounting secrets as files rather than environment variables, reduces this exposure surface.
Why These Pass Code Review
None of these mistakes cause a deployment to fail or a test to break - the workload runs correctly either way. That's exactly why automated scanning of manifests before they're applied matters: a human reviewer checking "does this work" has no natural reason to also check "does this default to root" unless they're specifically looking for it.
Automate this in your next PR
Run a free repo scan and see outdated dependencies, CVEs, and code quality issues before they ship.
Run a free repo scanRelated reading
Scanverra vs. Snyk
A developer-security platform scanning open-source dependencies, source code, containers, and IaC, priced per contributing developer with a capped free tier.
Scanverra vs. SonarQube (SonarSource)
A static code analysis platform for bugs, vulnerabilities, code smells, and technical debt across 30+ languages, free up to 50k lines of code.
Infrastructure as Code Security: Scanning Terraform, Kubernetes, and CloudFormation
A misconfigured Terraform module or an over-permissive Kubernetes manifest ships the same way application code does - here's how IaC scanning catches it before apply, not after.