Skip to main content

Network security & zero trust

The old security model was a castle: a hard wall around the network, everyone inside trusted. That model fails in the cloud, where there's no clean "inside," workloads come and go, and a single leaked key (8.2) walks straight past the wall. The modern model is zero trust: trust nothing by default — not even traffic already inside your network — and verify every request. This lesson builds the network half of cloud defense: isolating things so they're unreachable by default, controlling what can talk to what (in and out), encrypting traffic between services, and applying the same least-privilege instinct to the network that 8.2 applied to identity.

On-ramp in one breath: don't trust the network just because traffic is "inside." Make everything private and unreachable by default, then explicitly allow only the specific connections each thing needs — both inbound and outbound.

The vocabulary, defined once

  • Defense in depth — multiple independent layers of control, so one failure doesn't mean a breach. No single wall is trusted to hold.
  • Private endpoint — a way to reach a service over the cloud's private network only, with no public internet path at all.
  • Egress control — restricting outbound traffic (what your workload can connect to), not just inbound.
  • Segmentation — dividing the network into isolated zones so a compromise in one can't freely reach the others.
  • mTLS — mutual TLS: both sides of a connection present certificates and verify each other, so each service proves who it is and the traffic is encrypted.
  • Zero trust — the model: never trust by default (not even "internal" traffic); authenticate and authorize every request.

Defense in depth: layers, building on Chapter 2

Chapter 2 gave you the primitives: a VPC (your private network), subnets (segments within it — public vs private), and security groups (per-resource virtual firewalls). Network security stacks these into independent layers so no single mistake is fatal:

🌐 InternetEdge / WAF\n(filtersbad requests)Load balancer\n(onlypublic entry point)Public subnet\n(justthe LB)Private subnet\n(app— no public IP)Privatesubnet\n(database —reachable only from

Trace a request: the internet can reach only the load balancer in the public subnet. The app sits in a private subnet with no public IP — unreachable directly from the internet. The database is in its own private subnet, with a security group that allows connections only from the app's security group. Now count the failures it takes to expose the database directly: the attacker must get past the edge filter, and the load balancer, and the app's segment, and the database's security group. That's defense in depth — each layer is independent, and the database was never on the internet to begin with. This is the structural fix for the "public database" failure mode from 8.1.

Private by default, and egress control

Two durable habits sharpen the picture:

  • Private endpoints over public ones. When your app talks to a managed service (a database, object storage, a secret manager), prefer reaching it over a private endpoint so the traffic never touches the public internet. Less attack surface, and often required for compliance.
  • Control egress, not just ingress. Most people lock down inbound traffic and ignore outbound. But egress control is how you contain a breach: if a compromised workload can only connect out to the three services it legitimately needs, an attacker can't use it to exfiltrate data to their own server or pull down a second-stage payload. Default-deny outbound, allow the known destinations — the same least-privilege logic as IAM, applied to network direction.

Zero trust: the durable shift

Zero trust is the philosophy under all of this. State it plainly:

Never trust a request because of where it came from. Trust it only after verifying who it is and whether it's allowed — every time.

The old way granted trust by network location ("you're inside the VPN, so you're trusted"). Zero trust rejects that, because location is a terrible proxy for safety — a leaked credential or a compromised internal host is "inside" too. Instead, every request — even service-to-service, even internal — is authenticated and authorized on its own merits. Notice this is the network-layer twin of "identity is the new perimeter" (8.2): identity, not network position, decides trust.

Kubernetes NetworkPolicies: segmentation inside the cluster

Inside a Kubernetes cluster (Ch. 4), the default is alarming: every pod can talk to every other pod. That's a flat, fully-trusted network — the opposite of zero trust. A NetworkPolicy fixes it: a Kubernetes object that declares which pods may talk to which, on which ports. The durable pattern is default-deny, then allow:

# Default-deny ALL ingress in this namespace — nothing can reach these pods...
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {} # all pods in the namespace
policyTypes: [Ingress]
# (no ingress rules = deny all inbound)
---
# ...then explicitly allow ONLY the frontend to reach the API on 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
spec:
podSelector:
matchLabels: {app: api}
policyTypes: [Ingress]
ingress:
- from:
- podSelector: {matchLabels: {app: frontend}}
ports:
- {protocol: TCP, port: 8080}

Read it: the first policy denies all inbound traffic to every pod in the namespace; the second re-opens exactly one path — frontend → api on port 8080. Now a compromised pod elsewhere in the cluster cannot reach the API at all. That's segmentation inside the cluster, and it's pure least privilege for pod-to-pod traffic. (NetworkPolicies are enforced by your CNI — the cluster's networking plugin, e.g. Cilium — so they only take effect if your CNI supports them.)

mTLS and the service mesh

NetworkPolicies say who may connect; mTLS adds prove who you are and encrypt it. With mutual TLS, the frontend and API each present a certificate and verify the other's before exchanging a byte — so a service can't be impersonated, and the traffic is encrypted even inside your network (zero trust: don't trust internal links either). Doing this by hand for every service is painful, so a service mesh (or the cert-manager tool, which automates issuing/renewing the certificates) can apply mTLS transparently across all services. The concept — mutual authentication + encryption on every hop — is durable; the mesh/tool is the dated implementation detail.

Why it matters

The castle-wall model is dead: in the cloud there's no trusted "inside," so the durable model is zero trust — verify every request by identity, never by network location. Build it with defense in depth (independent layers: edge filter → load balancer → private app subnet → private database), keep things private by default (private endpoints, no public IPs), and control egress to contain breaches, not just ingress to prevent them. Inside Kubernetes, replace the flat all-pods-can-talk default with default-deny NetworkPolicies that allow only needed paths, and add mTLS so services mutually authenticate and encrypt even internal traffic. Every habit here is the same least-privilege instinct from 8.2, applied to the network.

Common pitfalls

  • Trusting "internal" traffic. A leaked key or compromised host is "inside" too. Authenticate and authorize every request — that's zero trust.
  • Putting databases on a public IP. The classic 8.1 failure. Keep data tiers in private subnets reachable only from the app tier.
  • Locking inbound, ignoring outbound. Without egress control, a compromised workload exfiltrates freely. Default-deny outbound and allow only known destinations.
  • Running a cluster with no NetworkPolicies. The default lets every pod reach every pod — a flat, fully-trusted network. Apply default-deny + explicit allows. (And confirm your CNI enforces them.)
  • Assuming TLS at the edge is enough. Edge-only TLS leaves internal service-to-service traffic unauthenticated and unencrypted. mTLS extends trust verification to every hop.

Where this connects

Checkpoint

Required checkpoint

8.5 — Network security & zero trust

Pass to unlock the Next button below

Next: 8.6 Supply-chain & image security →