Security

Real offensive depth

Testing and defence led by a published security researcher with five CVEs, including a CVSS 9.1 Mirai botnet kill-switch.

All security →
Compliance

Audit-ready, fixed scope

SOC 2, ISO, and the Canadian privacy stack, run end to end with an independent auditor.

All frameworks →
Resources

Learn the space

Original research, free tools, and plain-language guides on security and compliance, from a published security researcher.

Read the blog →
Security

Container Security in Kubernetes: The Basics Most Startups Skip

You moved to Kubernetes because you wanted portable, scalable infrastructure. You got it. You also got a much larger attack surface than most engineering teams realize, and a control plane that is opt-in secure rather than secure by default.

Most startups running Kubernetes in production are doing fewer than five of the basic security controls. Here are the ones that matter and the order to do them in. It is also the list we work through when we run a cluster security review.

The defaults you have to fix immediately

Containers running as root. Most images run as UID 0 by default. If an attacker escapes the container, they land as root on the node. Set a non-root user in your Dockerfiles and enforce it in pod specs with runAsNonRoot: true.

Privileged containers. Privileged containers can do almost anything the node can. There is almost never a legitimate reason for a workload to be privileged. Enforce a Pod Security Standard at the namespace level that blocks privileged mode.

Missing resource limits. Without CPU and memory limits, a single misbehaving pod can take down a node. Set sensible defaults at the LimitRange level so every pod has them whether or not the developer remembered.

Wide-open network policies. By default, every pod can talk to every other pod. Implement default-deny NetworkPolicies per namespace and allowlist specific ingress/egress. This single change limits blast radius dramatically when something does get compromised.

Image security

Your container images are a supply chain. Most teams treat them like static assets and ignore the security implications.

  • Use minimal base images. Distroless, Alpine, or scratch images cut your attack surface by orders of magnitude versus full Ubuntu/Debian bases.
  • Scan images on build. Trivy, Grype, or Snyk in your CI pipeline. Fail builds on high-severity CVEs in your direct dependencies.
  • Pin image digests, not tags. latest changes. v1.2.3 can be repushed. Pin sha256 digests in production manifests to make sure you deploy what you reviewed.
  • Sign your images. Sigstore/cosign makes image signing nearly free. Verify signatures at admission with policy-controller.
Want this handled? Tell us what your buyer is asking for and we will tell you what the work involves, what it costs, and what you can do yourself. Talk to us

Cluster-level controls

Beyond pod-level basics, a few cluster-level controls dramatically reduce risk.

RBAC, properly scoped. The default service accounts have more access than they need. Create per-workload service accounts with the minimum required permissions. Audit cluster-admin grants regularly. Strip them where you can.

Admission control. Use an admission controller (Kyverno or OPA Gatekeeper) to enforce policies at deploy time, not as a manual review. Block privileged pods, require signed images, enforce labels, fail closed.

Secrets management. Stop putting secrets in environment variables in plain Kubernetes Secrets (which are base64, not encrypted). Use a real secrets manager (AWS Secrets Manager, GCP Secret Manager, HashiCorp Vault) with workload identity for retrieval.

Audit logging. Enable Kubernetes audit logs. Ship them off-cluster to your SIEM or log aggregator. When something does go wrong, audit logs are usually how you reconstruct what happened.

What to monitor

The minimum runtime monitoring for production Kubernetes:

  • Falco or equivalent for runtime threat detection (suspicious process execution, unexpected outbound connections, container escapes).
  • Cloud provider audit logs for control plane access.
  • Alerts on RBAC changes, especially anything granting cluster-admin.
  • Alerts on new pod creation in sensitive namespaces (kube-system, prod data tiers).

None of this requires a security team. All of it is achievable in a few weeks of focused work. The teams that get breached on Kubernetes are not getting hit by exotic CVEs. They are getting hit by missing basics.

Need a Kubernetes security review?

We audit Kubernetes deployments against CIS benchmarks and real-world threat models, then help you fix what we find. Typical engagement: two weeks.

Book a review

The node is the real boundary, not the pod

Teams reason about Kubernetes as if the pod were the security boundary. It is not. A pod is a set of namespaces and cgroups on a shared kernel, and anything that gets a container closer to that kernel collapses the separation you think you have. The four settings that do most of the collapsing are hostPath volume mounts, hostNetwork, hostPID, and added Linux capabilities such as SYS_ADMIN or NET_ADMIN. A workload with a hostPath mount of /var/run/docker.sock or the containerd socket is effectively root on the node regardless of what its securityContext claims. Audit for those four things before you audit for anything clever, because a single logging sidecar shipped by a vendor Helm chart can quietly reintroduce all of them.

The second thing people miss is the cloud metadata endpoint. On AWS, a pod that can reach 169.254.169.254 can request credentials for the node instance profile, and node roles are usually far broader than workload roles. Enforce IMDSv2 with a hop limit of 1 so containers cannot reach it, or block the address in your egress network policy, then move workloads to IRSA or the equivalent workload identity on GCP and Azure. The same applies to service account tokens: Kubernetes automounts a token into every pod by default, and a compromised web frontend with a mounted token plus a permissive role is how a single application bug becomes cluster access. Set automountServiceAccountToken to false as the default and turn it on for the workloads that genuinely call the API server.

What auditors and enterprise buyers actually ask about your cluster

Container security shows up in SOC 2 and ISO 27001 evidence requests, but rarely in the language engineers expect. Nobody asks whether you run Falco. They ask for evidence that changes to production are authorized and reviewed, that access to production systems is restricted and reviewed periodically, that vulnerabilities are identified and remediated within a defined window, and that logging is enabled and retained. Kubernetes is simply where that evidence lives.

In practice the requests land like this. For change management, the auditor wants to see that a deployment to production traces back to an approved pull request, which means your GitOps repository and its branch protection settings are the artifact, not the cluster. For access review, they want the list of humans and service principals with cluster-admin or equivalent, dated and signed off by someone. Run kubectl get clusterrolebindings output into a quarterly review file and you have satisfied a control that otherwise takes a week to reconstruct. For vulnerability management they want your image scanning policy, a sample of scan output, and evidence that a high severity finding was actually fixed and by when. A scanner that runs but never blocks anything and produces no ticket trail is worse than no scanner, because it demonstrates you knew and did nothing. For logging, they want retention and off-cluster storage. Audit logs sitting on the control plane of a cluster that gets replaced every eight weeks are not retained logs.

Multi-tenancy is the question that decides how hard the rest of the conversation goes. If your customers share a cluster and separation rests on namespaces alone, expect the buyer's security team to press on it, because namespaces are an authorization boundary and not an isolation boundary. Being able to explain the layers you actually run, network policy default-deny, separate node pools or sandboxed runtimes such as gVisor for untrusted code, per-tenant encryption keys, is what settles that thread. The ISO 27001 controls around segregation in networks and secure development want the same explanation in different words, so write it once and reuse it.

How policy enforcement goes wrong

The most common self-inflicted outage in this whole area is switching an admission controller from audit to enforce on a Friday. Kyverno and Gatekeeper both fail closed by default when the webhook is unavailable, which means a policy engine that crashes or gets evicted can block every deployment in the cluster, including the deployment that would fix the policy engine. Set failurePolicy deliberately, exclude kube-system and your own policy namespace from the webhook, run the policy engine with a PodDisruptionBudget and at least two replicas, and give yourself a documented break-glass procedure to delete the webhook configuration when you need to.

Roll policies out in stages. Run every new rule in audit mode for two weeks and read the report, because the violations are almost never where you predicted. In a typical mid-size cluster the first audit run flags the ingress controller, the CSI driver, the metrics agent, and one legacy job that has been running as root since before anyone current joined the company. Fix or exempt each one explicitly with a named exception and an owner rather than loosening the rule for everybody. Exceptions with owners survive an audit. A weakened baseline does not.

The other failure mode is digest pinning without a rebuild path. Pinning sha256 digests is correct, and it also means your base image security patches never arrive unless something updates the digests. Pair pinning with a bot that opens pull requests on new base image builds, and rebuild your images on a schedule rather than only when application code changes. An image that has not been rebuilt in seven months will fail a scan on the operating system layer no matter how clean your own dependencies are.

A realistic order of work

For a team of four to eight engineers with one production cluster, the work fits into roughly six weeks of part-time effort. Week one is inventory: every namespace, every workload, every service account with API access, every image and where it came from. Week two is the node boundary, meaning hostPath, privileged, capabilities, metadata access, and token automount. Week three is RBAC, starting with removing standing cluster-admin from humans and replacing it with a short-lived elevation path. Week four is network policy, default-deny in one namespace first, then outward. Week five is images and admission control in audit mode. Week six is runtime detection and log shipping, plus writing down what you did so it can be handed to an auditor or a buyer later. That last step is the one teams skip, and it is the one that costs the most to reconstruct nine months later during an audit. Our cluster and infrastructure review work follows the same order for the same reason.

When you should not hire anyone for this

If you run fewer than a dozen services on a managed cluster with a single tenant and no untrusted code execution, most of the value here is available to you for free in an afternoon of reading and a week of work. Turn on the managed Pod Security Standards your provider already ships, enable audit logging, remove standing admin, and run one scan. You do not need an external review to do any of that, and any consultant who tells you otherwise is selling a report rather than a fix.

Skip a Kubernetes review entirely if your real risk sits somewhere else. Teams with one cluster and a public API handling customer data usually get more from a penetration test of the application than from a cluster benchmark, because the path to your data in that shape of company runs through broken authorization in the API, not through a container escape. Likewise, if you are running three containers on a managed serverless platform such as Fargate or Cloud Run, the entire node-level portion of this article does not apply to you and buying a Kubernetes assessment would be paying for someone else's problem. The point at which outside help earns its cost is when you have multiple clusters, multiple teams shipping into them, tenant separation to defend to a buyer, or a compliance deadline that makes reconstructing evidence more expensive than paying someone to build it correctly the first time. If you are not sure which of those you are, say so plainly when you talk to us and we will tell you if the answer is no.

Want this handled? Tell us what your buyer is asking for and we will tell you what the work involves, what it costs, and what you can do yourself.

Talk to usOr talk about a retainer

Before you go

Want the rest of this by email?

If this was useful, I send a few short notes on security posture. Unsubscribe in one click, and replies reach me directly.

From Jacob Masse, principal of traztech. No spam, unsubscribe in one click.

Want a second opinion on where you stand?

We run SOC 2, ISO 27001 and the rest of the compliance stack for startups and SMEs, and the security testing that sits behind it. The first call is free, and we will tell you if you are not ready to start yet.

Book a free call

Track record

Who is actually doing the work

5
Published CVEs, including a CVSS 9.1
76
Controls taken from nothing to a passed SOC 2 Type II
Zero
Exceptions on that Type II report
20+
Penetration testing engagements delivered

Published vulnerability research

Five published CVEs. CVE-2024-45163 (CVSS 9.1) is a flaw in the Mirai botnet itself, which gave defenders a way to shut down attacker infrastructure. CVE-2026-42626 takes HP ENVY 5000 printers offline from any unauthenticated device on the same network.

A SOC 2 Type II built from nothing

At Humera, a venture-backed US security company, Jacob built the compliance programme in-house from nothing: no report, no policies, no documented controls. It ended in a Type II attestation across 76 controls with zero exceptions, on a team of 15.