Most Azure networks aren’t designed to fail gracefully.
They’re designed to be convenient: easy peering, wide address space, few hard edges. Everything works, deployments are fast, nobody blocks progress.
Until something breaks in the worst possible way, a compromised workload already inside the network and you discover that “convenient” and “contained” are rarely the same thing.
In an assume‑breach model, blast radius isn’t theoretical. It’s the difference between an incident and an outage‑shaped investigation.
The Mental Model
The common assumption
VNets are boundaries. If we didn’t mean for things to talk, security controls will handle it.
This model treats:
- Address space as neutral
- Peering as low‑risk plumbing
- Routing as an implementation detail
Security, in this framing, lives elsewhere.
Why it breaks
Azure networking is opinionated in one quiet but important way:
If traffic is routable, the platform assumes it’s legitimate.
VNets, peerings, and routes don’t express intent. They express possibility. Once a packet has a valid path, Azure does not ask whether that path aligns with your threat model.
In an incident, possibility always beats intent.
How It Really Works
Blast radius in Azure networks is shaped by structural reachability, not by how carefully your firewall rules are written.
Three mechanics matter most.
Address space sets the outer limit
CIDR ranges define what could ever be reached.
If two workloads sit in address spaces that can be routed between:
- They are part of the same potential blast radius
- Any containment relies on controls outside the network layer
Addressing is not bookkeeping. It’s scope definition.
Peering collapses assumed boundaries
VNet peering creates:
- Full IP reachability between address spaces
- No inherent notion of trust direction
- No concept of “only for these workloads”
From a routing perspective, peered VNets behave like a single, larger network unless you deliberately constrain paths.
That’s efficient. It’s also expansive.
Routing decides how compromise spreads
User Defined Routes (UDRs), system routes, and propagated paths answer one question during an incident:
Where can packets actually go right now?
The answer is often broader and less remembered than architects expect.
Real‑World Impact
Under assume breach, blast radius isn’t an abstract risk. It shows up as very concrete outcomes:
- A Non‑Prod compromise that suddenly has line‑of‑sight to Prod
- A “small” spoke that can reach far more than its owners realise
- An incident response slowed down by surprise connectivity
The pattern is consistent: networks optimised for convenience quietly optimise for spread.
Blast Radius Smell Tests
These aren’t best practices. They’re gut checks you can run against a real estate as it exists today.
1. Reachability Without Intent
Question to ask:
Can this workload reach IP ranges it was never explicitly designed to talk to simply because routing allows it?
If the answer is yes, that reachability is part of your blast radius, regardless of firewall posture.
This smell commonly comes from:
- “Just in case” peering
- Broad, loosely allocated address space
- Default routes no one has reviewed in years
Under breach conditions, attackers care about what’s reachable, not what was intended.
2. Environment Boundaries That Only Exist in Diagrams
Question to ask:
If I ignore names, subscriptions, and tags, are Prod and Non‑Prod actually isolated at the routing layer?
If environments are routable:
- They are not isolated
- They simply rely on convention to stay apart
Attackers don’t see environments. They see IP ranges and next hops.
If a Non‑Prod workload is compromised, the network decides whether that incident stays there, not your naming standards.
3. Temporary Connectivity That Never Left
Question to ask:
Which peerings or routes would surprise you if they appeared in an incident review?
Migration links, troubleshooting routes, one‑off access that “we’ll remove later” these quietly accumulate.
They are dangerous because:
- They’re forgotten
- They’re rarely monitored
- They aren’t defended in anyone’s mental model
Routing doesn’t care how old a decision is.
Implementation Examples
Visualising accidental blast radius
10.0.0.0/16"] Prod["Prod VNet
10.1.0.0/16"] NonProd["Non‑Prod VNet
10.2.0.0/16"] Shared --- Prod Shared --- NonProd
This looks segmented.
From a routing perspective, it often isn’t. Shared services become an implicit bridge unless paths are deliberately constrained.
A peering that widens scope by default
| |
Nothing here is misconfigured.
But combined with similar peerings elsewhere, this enables:
- Lateral reach that wasn’t consciously designed
- Incident paths that rely entirely on downstream controls to stop spread
That’s blast radius expressed as configuration.
Gotchas & Edge Cases
- Subscription boundaries don’t limit routing
- Address space reuse hides, rather than reduces, blast radius
- Old peerings are rarely re‑evaluated
- Default system routes often enable more reach than diagrams suggest
If you haven’t inspected effective routes during a failure scenario, you don’t actually know your containment story.
Best Practices
- Treat every routable path as an explicit trust decision
- Align address space with containment goals, not just growth
- Periodically review reachable IP ranges, not just VNets
- Remove connectivity that no one can clearly justify today
This is architectural discipline, not extra tooling.
It’s expanded by quiet ones no one revisits.