Containers and Kubernetes made deploying software dramatically easier, and in doing so quietly handed every team a large new attack surface that defaults to insecure. A container image is a filesystem plus whatever you shipped in it — including vulnerabilities and secrets you didn't mean to include — and Kubernetes is a powerful distributed system whose defaults optimize for 'it works,' not 'it's locked down.' The good news is that container and Kubernetes security is mostly a set of concrete, well-understood practices rather than anything exotic; the risk comes almost entirely from not applying them, because the platform will happily run a root container with cluster-admin and a hard-coded password without complaint. Hardening happens at three layers — the image, the workload, and the cluster — and doing the unglamorous basics at each is what separates a defensible platform from one that's one misconfiguration away from a very bad day.
Start with a minimal, hardened image
Every container starts from an image, and most images ship far more than the application needs — a full OS, package managers, shells, build tools — each addition another potential vulnerability and another tool an attacker gets for free if they break in. The single highest-leverage move is minimalism: build on small, hardened bases (distroless or a minimal Alpine-style image), include only what the app needs to run, and use multi-stage builds so compilers and build dependencies never make it into the final artifact. A minimal image has a smaller attack surface, fewer CVEs to patch, and denies an intruder the shell and utilities they'd use to pivot. Pair that with scanning — every image checked for known vulnerabilities in your CI pipeline before it ships, not after it's running in production — and pin base images to specific digests so you know exactly what you're deploying. The most secure code is the code that isn't in the container at all.
Don't run as root, and drop what you don't need
By default a container often runs as root, and root inside a container is a lot closer to root on the host than teams assume — if a process is compromised or a container-escape vulnerability is found, running as root turns a contained problem into a host-level one. Run containers as a non-root user with a read-only root filesystem wherever possible, drop all Linux capabilities and add back only the specific few the workload genuinely requires, and prevent privilege escalation. In Kubernetes these are set through the security context and enforced cluster-wide with Pod Security Standards (or an admission policy), so 'don't run privileged' becomes a rule the platform enforces rather than a convention each team is trusted to remember. None of this changes what your application does; it dramatically shrinks what an attacker can do if they get a foothold inside it. It's the container-level expression of least privilege, and it's cheap to apply and expensive to skip.
Lock down the cluster: RBAC and network policy
Kubernetes gives you two powerful controls that are frequently left wide open: who can do what (RBAC) and what can talk to what (network policy). On access, the failure mode is handing out cluster-admin because scoping roles is fiddly — which means one leaked kubeconfig or compromised CI token owns the whole cluster; instead, scope RBAC to least privilege, per namespace and per service account, so an identity can touch only what its job requires. On the network, Kubernetes by default lets every pod talk to every other pod, so a single compromised service can reach your entire cluster laterally — exactly the flat-network problem that zero trust exists to kill. Network policies fix it by allowing only the specific pod-to-pod traffic that's actually needed, turning the cluster into segmented zones so a foothold in one service doesn't grant reach to the database or the secrets. Both controls are default-permissive and have to be deliberately tightened — the cluster won't do it for you.
Handle secrets like secrets
Containers and Kubernetes make it dangerously easy to mishandle credentials, and the shortcuts are everywhere: secrets baked into image layers (where they persist in the registry forever, even if deleted from the final stage), passed as plaintext environment variables, or stored in Kubernetes Secrets that — despite the name — are only base64-encoded and sit in etcd unencrypted by default. None of that is secure. Never bake secrets into images; enable encryption-at-rest for etcd so Kubernetes Secrets are actually encrypted; and for anything sensitive, broker credentials from a real secrets manager (or via a CSI driver) so they're injected at runtime, access-controlled, and rotatable rather than living statically in cluster config. This is the same secrets management and rotation discipline that applies everywhere, with container-specific traps — the image layer and the misleadingly-named Secret object — that catch teams who assume the platform is handling it. Treat every credential as something that will eventually leak, and make sure that when it does, it's short-lived and revocable.
Catch misconfigurations before they ship, and watch at runtime
The overwhelming majority of container and Kubernetes incidents come from misconfiguration, not exotic zero-days — a privileged pod, an over-permissive role, a missing network policy, an unscanned image — which is good news, because misconfigurations are catchable automatically before they ever run. Enforce security as policy in your pipeline and at admission: manifests scanned for insecure settings on every change, and an admission controller that refuses to admit workloads that violate your rules (no privileged containers, no running as root, images must be scanned and signed) so an insecure config is blocked rather than deployed. That shifts security left, where fixes are cheap. Then complement it at runtime — monitor for anomalous behavior like unexpected process execution or network connections, since some threats only appear once workloads are live. Prevention at admission plus detection at runtime, layered together, is what keeps a cluster defensible as it grows and as more teams ship to it.
How Infiniti Tech Partners secures containers and Kubernetes
We harden containerized platforms at all three layers where the risk actually lives. At the image layer, minimal hardened bases, multi-stage builds, and vulnerability scanning in CI so you ship a small, known-good artifact. At the workload layer, non-root users, dropped capabilities, read-only filesystems, and Pod Security Standards enforced cluster-wide so a foothold stays contained. At the cluster layer, least-privilege RBAC, default-deny network policies that segment pod-to-pod traffic, and secrets brokered from a real manager with etcd encryption rather than plaintext env vars. We wire it all into policy-as-code and admission control so insecure configurations are blocked before they deploy, and add runtime monitoring for what only shows up live. The result is a Kubernetes platform that's defensible by default and stays that way as your team and workloads grow — with the consistent, provable controls your compliance posture also depends on.
Frequently asked questions
How do you secure a container image?
Start minimal: build on small, hardened bases like distroless or minimal Alpine, include only what the app needs to run, and use multi-stage builds so compilers and build tools never reach the final artifact — a smaller image means fewer CVEs and denies an intruder the shell and utilities they'd use to pivot. Scan every image for known vulnerabilities in CI before it ships, not after it's running, and pin base images to specific digests so you know exactly what you're deploying. Never bake secrets into image layers, where they persist in the registry forever.
Why shouldn't containers run as root?
Root inside a container is much closer to root on the host than teams assume, so if a process is compromised or a container-escape bug is found, running as root turns a contained problem into a host-level one. Run containers as a non-root user with a read-only root filesystem where possible, drop all Linux capabilities and add back only the few the workload genuinely needs, and prevent privilege escalation. In Kubernetes these are set via the security context and enforced cluster-wide with Pod Security Standards, so it becomes a platform rule rather than a convention each team is trusted to remember.
What are the most important Kubernetes security settings?
Two powerful controls are frequently left wide open. RBAC governs who can do what: scope it to least privilege per namespace and service account instead of handing out cluster-admin, so one leaked kubeconfig doesn't own the whole cluster. Network policy governs what can talk to what: by default every pod can reach every other pod, so a single compromised service can move laterally everywhere — network policies allow only the traffic that's actually needed, segmenting the cluster. Both are default-permissive and must be deliberately tightened; the cluster won't do it for you.
Related reading
API Security: Defending Against the OWASP API Top 10
The real-world API attacks that breach growth-stage SaaS — broken object-level authorization, broken authentication, excessive data exposure, and unrestricted resource consumption — and the concrete defenses for each.
SecurityPasswordless Authentication and Passkeys: A SaaS Migration Guide
Why growth-stage SaaS is moving to passkeys and passwordless auth — how WebAuthn works, what it kills (phishing, credential stuffing, password resets), and how to migrate without locking users out.
SecuritySoftware Supply Chain Security: SBOMs, Signing, and Locking Down Your Pipeline
How growth-stage SaaS can secure the software supply chain — dependency risk, SBOMs, artifact signing, SLSA provenance, and hardening CI/CD against the attacks that hit your build, not your app.