Securing Multi-Tenant Kubernetes on AWS: mTLS, Network Policies, and Real Isolation
Multi-tenant Kubernetes is a promise and a problem at the same time. You get utilisation and operational efficiency; you take on the job of making sure one compromised workload cannot become everyone's compromised workload. On AWS, that job is mostly about protocol-level trust between services — and most clusters are not set up for it.
The threat model
In a multi-tenant cluster, the network boundary is already breached by design. Tenants share nodes, the control plane, and the network overlay. The question is not "how do we keep attackers out" but "how do we stop one tenant from reaching another".
The risks that matter:
- Lateral movement — a compromised pod in tenant A reaching tenant B's services.
- Cross-tenant traffic sniffing — plain-text service calls that any workload on the same node can observe.
- Control-plane targeting — misconfigured RBAC or network policies that expose the API server or etcd.
The two controls that matter most
1. Mutual TLS via a service mesh
By default, pod-to-pod traffic is unauthenticated plain text. A service mesh (Istio, Linkerd) puts a sidecar proxy on every workload and forces mTLS: each pod gets a cryptographic identity, and only authenticated services can talk to each other.
Operational notes:
- The mesh's certificate authority is the crown jewels. Protect the CA root key; a leak there breaks the trust model for the whole cluster.
- Scope certificate issuance by namespace so a tenant cannot request an identity for another tenant's workload.
- Test the failure mode: when a certificate expires or is revoked, the call should fail closed, not fall back to plain text.
2. Network Policies
Network Policies are the cluster's L3/L4 firewall. They restrict ingress and egress by namespace and pod labels, enforcing least privilege.
- Start with a default-deny policy per namespace, then allow only the specific dependencies each workload needs.
- Validate policies in CI against observed network flows. An allow-all catch-all rule is the most common gap.
- Re-audit on a schedule — policies drift as services are added.
AWS-specific layering
Combine Kubernetes controls with native AWS services:
- Security Groups are the coarse outer boundary at the node level; Network Policies are the fine-grained inner segmentation. Use both.
- IRSA (IAM Roles for Service Accounts) gives each pod the minimum AWS permissions it needs, instead of handing out node-instance credentials.
- AWS Secrets Manager for service credentials, with access scoped by IAM policy.
Isolation beyond the network
- One namespace per tenant, with
ResourceQuotaandLimitRangeto stop a noisy neighbour from starving the cluster. - Aggressive RBAC: prefer namespaced
Role/RoleBindingover cluster-wideClusterRolebindings. - Enforce the
RestrictedPod Security Standard on tenant namespaces — non-root, no privilege escalation, limited capabilities. - Treat security rules as code (GitOps). A manual change on the API server should be detected and reverted automatically.
Runtime monitoring
Prevention fails. Runtime security tools watch syscalls and process execution inside containers and alert when a web server pod suddenly tries to open a shell or a raw socket. Pair that with control-plane audit logs and you have a detect layer that does not depend on network policies being perfect.
The pattern
Multi-tenant security is not a product. It is the combination of identity-based service trust, default-deny networking, least-privilege cloud access, and runtime detection. Any one of those alone is a speed bump; together they are a defensible architecture.
This is an expanded technical note based on our guide to protocol security gaps in multi-tenant Kubernetes on AWS. The original is here: https://hsecurities.in/blog/protocol-security-gaps-multi-tenant-kubernetes-amazon