Threat Modeling & Zero-Trust Architecture
STRIDE walks a data-flow diagram's trust boundaries to surface spoofing/tampering/repudiation/info-disclosure/DoS/elevation threats, each mapping to a defense; apply least privilege, defense in depth, fail secure, complete mediation, secure defaults, and assume-breach; and implement zero-trust with workload identity, mTLS via a service mesh, identity-aware proxies replacing VPNs, and micro-segmentation.
Threat modeling and zero-trust are complementary
The two skills here are complementary: threat modeling is how you reason about attackers before you build, and zero-trust is the architecture you arrive at when you take the conclusions seriously.
Threat modeling with STRIDE
You draw a data-flow diagram with trust boundaries (where data crosses from less-trusted to more-trusted, for example browser to API, API to database, your service to a third-party processor), then walk each element and each boundary crossing against the STRIDE categories:
S Spoofing pretending to be another identity -> authentication
T Tampering modifying data or code in transit/rest -> integrity (signing, hashes, TLS)
R Repudiation denying an action you took -> audit logging, non-repudiation
I Information disclosure leaking data -> encryption, access control
D Denial of service degrading availability -> rate limits, quotas, redundancy
E Elevation of privilege gaining rights you should not have -> authorization, least privilege
Each STRIDE category maps to a defense property, so the exercise systematically surfaces gaps instead of relying on whoever remembers to think about security. You prioritize the resulting threats (likelihood x impact, or DREAD) and only mitigate what matters.
You are walking a data-flow diagram. Classify each threat by its STRIDE category, which tells you the defense it demands.
Secure-design principles
The principles you apply to the mitigations: least privilege (each component gets the minimum access it needs), defense in depth (layered controls so one failure is not fatal), fail secure (on error, deny rather than allow), complete mediation (check authorization on every access, not once at the start), secure defaults (safe out of the box, opt into risk), and assume breach (design as if the attacker is already inside).
Zero-trust
The old model was a hard perimeter with a soft interior: get past the VPN/firewall and the internal network trusts you. That fails because one phished laptop or one compromised service inside the perimeter can then talk freely to everything (lateral movement), and the blast radius is the whole network. Zero-trust, popularized by Google's BeyondCorp, flips it: never trust, always verify. There is no privileged network location. Every request, including internal east-west service-to-service traffic, is authenticated and authorized on its own merits.
Concretely for microservices: give every workload a cryptographic identity (SPIFFE/SPIRE, or cloud IAM roles), and enforce mTLS for all service-to-service calls via a service mesh (Istio, Linkerd, Consul) so both sides prove who they are and traffic is encrypted and its identity is verified. Replace the VPN with an identity-aware proxy (BeyondCorp-style, or Cloudflare Access / Google IAP) that authenticates the user and device on every request to internal apps. Add micro-segmentation: default-deny network policy so service A can reach only the specific services it needs, not the whole subnet.
Stage 1 of 4: Start with the perimeter model's failure: one phished laptop behind the VPN was implicitly trusted, so lateral movement reached the whole flat network.
The payoff is blast-radius containment. If one service is compromised, it holds a narrowly scoped identity, can reach only its explicit dependencies, and every call it tries is authenticated and logged, so lateral movement is slow, loud, and bounded instead of instant and silent.
Interview nuance: the classic wrong turn is bolting security on at the end ("we will add auth before launch"). Threat modeling is valuable precisely because it is done at design time, when changing a trust boundary is a diagram edit rather than a rewrite. And the classic zero-trust misconception is that it is a product you buy; it is an architecture principle (verify every request, no implicit network trust) that mTLS, identity-aware proxies, and micro-segmentation implement.
Recap: STRIDE walks a data-flow diagram's trust boundaries to surface spoofing/tampering/repudiation/info-disclosure/DoS/elevation threats, each mapping to a defense; apply least privilege, defense in depth, fail secure, complete mediation, secure defaults, and assume-breach; and implement zero-trust (never trust, always verify) with workload identity, mTLS via a service mesh, identity-aware proxies replacing VPNs, and micro-segmentation to contain lateral movement and blast radius.
Last pass before your design write: which model does each statement describe?
Apply
Your turn
The task this lesson builds to.
Produce a threat model for a payments feature using STRIDE, then redesign a flat internal network into a zero-trust model for microservices.
Think about
- What does STRIDE enumerate, and what are the core secure-design principles?
- What does 'never trust, always verify' change about internal traffic?
- How do you limit lateral movement and blast radius?
Practice
Make it stick
A second problem on the same idea, so it survives past today.
Explain how you would run a threat-modeling exercise and a zero-trust rollout for a 200-service platform migrating off a flat corporate network (think a bank moving from perimeter VPN to BeyondCorp) without a big-bang cutover. Lead with how you sequence the migration so nothing breaks and you get blast-radius reduction early.
Think about
- Why scope threat modeling to the highest-risk services first?
- Why is permissive-then-strict mTLS the survivable path?
- Why does enforcing strict mTLS before mapping the call graph break things?