<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Network Watcher on Brewed in the Cloud by Chris Hailes</title><link>https://blog.brewedinthecloud.com/tags/network-watcher/</link><description>Recent content in Network Watcher on Brewed in the Cloud by Chris Hailes</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Thu, 22 Oct 2026 00:00:00 +1100</lastBuildDate><atom:link href="https://blog.brewedinthecloud.com/tags/network-watcher/rss.xml" rel="self" type="application/rss+xml"/><item><title>Can the Packet Reach the Identity’s Target?</title><link>https://blog.brewedinthecloud.com/p/can-packet-reach-identity-target/</link><pubDate>Thu, 22 Oct 2026 00:00:00 +1100</pubDate><guid>https://blog.brewedinthecloud.com/p/can-packet-reach-identity-target/</guid><description>&lt;p&gt;The access review says the workload identity can read the storage account. The network diagram says the subnet has no route to it.&lt;/p&gt;
&lt;p&gt;Which one is right?&lt;/p&gt;
&lt;p&gt;Possibly both. Azure RBAC describes authority. Routes, DNS, firewalls, and network security groups shape reachability. Until you test the same source, destination, protocol, and operation, those documents are describing different slices of the system.&lt;/p&gt;
&lt;p&gt;There is a familiar temptation here: treat a “reachable” result as an attack path, or an “unreachable” result as containment. Both conclusions get ahead of the evidence.&lt;/p&gt;
&lt;h2 id="the-mental-model"&gt;The Mental Model
&lt;/h2&gt;&lt;p&gt;A network test answers a narrow question: from this source, can a particular kind of connection be established to this destination at this time?&lt;/p&gt;
&lt;p&gt;It does not answer whether the workload has permission to perform an operation once connected. Nor does a role assignment answer whether the packets can get there.&lt;/p&gt;
&lt;div class="mermaid"&gt;flowchart LR
W[Workload source] --&gt;|DNS chooses destination| D[Resolved address]
D --&gt;|route and policy for protocol/port| N[Network path]
N --&gt;|connection may succeed| S[Target service]
I[Workload identity] --&gt;|authorization for operation| S
&lt;/div&gt;
&lt;p&gt;The testable claim is not “the identity can reach storage.” It is more like: “This VM&amp;rsquo;s application process resolves this hostname to this address, can establish TCP 443, and can read this test object using this principal.”&lt;/p&gt;
&lt;p&gt;That sentence is longer because the architecture is more complicated than one green check.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Reachability is a property of a tested source, destination, protocol, and time—not an enduring property of an identity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="how-it-really-works"&gt;How It Really Works
&lt;/h2&gt;&lt;h3 id="fix-the-test-tuple-before-you-run-a-probe"&gt;Fix the test tuple before you run a probe
&lt;/h3&gt;&lt;p&gt;Record the source resource and actual runtime context, target FQDN or IP, expected resolver, protocol, destination port, and the business operation to test. For a workload identity path, capture the principal ID and the exact data or service action separately.&lt;/p&gt;
&lt;p&gt;Avoid a vague scan of “the subnet.” A VM and a container on that VM may have different local firewall, proxy, DNS, or identity behaviour. A subnet-level effective rule view can explain policy, but it cannot prove what a process used.&lt;/p&gt;
&lt;p&gt;For this article&amp;rsquo;s example, assume an Azure VM application connects to an Azure Storage Blob private endpoint using the service hostname and HTTPS on TCP 443. It is illustrative; no test was run against an Azure subscription. Record actual VM/Storage SKUs, region, endpoint subresource, resolver configuration, and client SDK/API version before applying the method to a tenant.&lt;/p&gt;
&lt;h3 id="use-diagnostics-for-the-question-they-can-answer"&gt;Use diagnostics for the question they can answer
&lt;/h3&gt;&lt;p&gt;Azure Network Watcher&amp;rsquo;s Connection troubleshoot supports TCP or ICMP tests from documented sources including virtual machines and virtual machine scale sets to destinations including VMs, FQDNs, URIs, and IP addresses. Its results can surface connectivity, DNS, route, NSG, and other supported configuration issues. The agentless experience is currently documented as preview; feature availability and behaviour need to be checked for the target environment.&lt;/p&gt;
&lt;p&gt;That is useful. It is not an application transaction. A TCP success says a connection probe reached a listening port under the tested conditions. It does not prove the application resolved the same name, used the same proxy, negotiated TLS as expected, or presented the identity you reviewed. A TCP failure can come from the target not listening, a guest firewall, a missing route, policy, or a diagnostic prerequisite—not necessarily the security boundary you meant to test.&lt;/p&gt;
&lt;p&gt;Pair the diagnostic with a test from the actual workload context. Resolve the application hostname there, record the address, then attempt a safe connection. Where practical, make a non-mutating application request with the intended identity. Keep results separate so one tool&amp;rsquo;s scope is not mistaken for another&amp;rsquo;s.&lt;/p&gt;
&lt;h3 id="inspect-policy-but-dont-confuse-it-with-observation"&gt;Inspect policy, but don&amp;rsquo;t confuse it with observation
&lt;/h3&gt;&lt;p&gt;Review the effective route, relevant NSG rules, Azure Firewall or network virtual appliance policy, peering/gateway path, and target-side restrictions that apply to the source/destination tuple. Which surfaces matter depends on the topology. A route table screenshot without the effective next hop is not enough; an NSG allow rule does not prove the target is listening.&lt;/p&gt;
&lt;p&gt;For Network Watcher, confirm the service is enabled in the source VM&amp;rsquo;s region and check its current RBAC permission requirements. Built-in Network Contributor, Contributor, and Owner roles can include broad actions; custom roles may be more appropriate after verifying the exact diagnostic actions. Do not expand permissions merely to make a one-time test convenient.&lt;/p&gt;
&lt;p&gt;The diagnostic data model, API version, supported sources, and permission set can change. This draft does not call a Network Watcher REST API, query a log schema, or assume a specific VM agent/extension. Name those versions and prerequisites when a real implementation uses them.&lt;/p&gt;
&lt;h3 id="test-the-service-operation-separately"&gt;Test the service operation separately
&lt;/h3&gt;&lt;p&gt;If TCP connects, use the workload&amp;rsquo;s credential path to attempt one safe, read-only operation. For Blob Storage with Microsoft Entra ID, the data service evaluates authorization for the request; network reachability does not make the request permitted.&lt;/p&gt;
&lt;p&gt;If the operation fails, record the service response and identity used. If it succeeds, record the object and operation. Avoid logging bearer tokens. The test should use non-sensitive data and a principal with only the access required for that test.&lt;/p&gt;
&lt;h2 id="real-world-impact"&gt;Real-World Impact
&lt;/h2&gt;&lt;p&gt;Suppose a workload has a role that appears to permit access to a sensitive data store, but the test from its current source cannot reach the target. That is worth investigating, but it is not a reason to leave the role untouched forever. The route may change; a proxy or alternate path may exist; another workload may share the identity.&lt;/p&gt;
&lt;p&gt;Now reverse the result. The TCP probe succeeds, but the data operation is denied. Adding more network blocks might not reduce the specific authority exposure at all. The intended identity may not be in use, or the permission may be missing. An error message and principal ID are more useful than another blanket rule.&lt;/p&gt;
&lt;p&gt;Use a reachability matrix that records both positive and negative cases:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Destination&lt;/th&gt;
&lt;th&gt;Protocol/port&lt;/th&gt;
&lt;th&gt;Network result&lt;/th&gt;
&lt;th&gt;Service operation&lt;/th&gt;
&lt;th&gt;Interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Workload process&lt;/td&gt;
&lt;td&gt;Intended endpoint&lt;/td&gt;
&lt;td&gt;TCP 443&lt;/td&gt;
&lt;td&gt;Observed result&lt;/td&gt;
&lt;td&gt;Safe read as target identity&lt;/td&gt;
&lt;td&gt;Tests intended path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same source&lt;/td&gt;
&lt;td&gt;Known out-of-scope endpoint&lt;/td&gt;
&lt;td&gt;TCP 443&lt;/td&gt;
&lt;td&gt;Observed result&lt;/td&gt;
&lt;td&gt;No data operation&lt;/td&gt;
&lt;td&gt;Challenges network boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same source&lt;/td&gt;
&lt;td&gt;Intended service name&lt;/td&gt;
&lt;td&gt;TCP 443&lt;/td&gt;
&lt;td&gt;Observed result&lt;/td&gt;
&lt;td&gt;Same read with wrong/unauthorized identity, if safe&lt;/td&gt;
&lt;td&gt;Separates reachability from authority&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Fill this in only from real tests. A blank or untested cell is not “denied.” Re-test after the change and retain the exact source, destination, protocol, timestamp, and identity so another engineer can reproduce the claim.&lt;/p&gt;
&lt;h2 id="gotchas-and-edge-cases"&gt;Gotchas and Edge Cases
&lt;/h2&gt;&lt;p&gt;The gap between control-plane configuration and a running process is where confident conclusions tend to get expensive. A clean route analysis can coexist with an application outage; a successful probe can coexist with a broken trust boundary.&lt;/p&gt;
&lt;h3 id="diagnostic-sources-may-not-match-the-process"&gt;Diagnostic sources may not match the process
&lt;/h3&gt;&lt;p&gt;Connection troubleshoot operates from supported Azure resource types and test modes. A test from a VM does not automatically represent every container, sidecar, proxy, or application library on that VM. Record what emitted the traffic and what did not.&lt;/p&gt;
&lt;h3 id="a-port-test-can-pass-for-the-wrong-service"&gt;A port test can pass for the wrong service
&lt;/h3&gt;&lt;p&gt;An address can accept TCP without being the intended service. Check DNS, destination ownership, TLS/service identity, and the application response. Do not treat “socket opened” as equivalent to “request reached the intended resource.”&lt;/p&gt;
&lt;h3 id="network-policy-is-not-the-only-failure-domain"&gt;Network policy is not the only failure domain
&lt;/h3&gt;&lt;p&gt;Guest firewall, process configuration, server listener state, DNS, service firewall, and platform diagnostic prerequisites may all affect results. Classify the failure before proposing a security change. If the diagnostic itself needs permissions or connectivity the workload lacks, that is not proof the workload&amp;rsquo;s normal path is blocked.&lt;/p&gt;
&lt;h3 id="one-successful-test-ages-quickly"&gt;One successful test ages quickly
&lt;/h3&gt;&lt;p&gt;Routes, DNS, identities, and policy change independently. A reachability result is a snapshot, not a perpetual guarantee. Preserve its time and configuration context, and decide which changes invalidate it.&lt;/p&gt;
&lt;h2 id="best-practices"&gt;Best Practices
&lt;/h2&gt;&lt;p&gt;Before changing policy, write down what a passing test means. Specify the workload context, FQDN and expected destination, TCP/ICMP choice, port, identity, operation, and what result should be denied. Then use a diagnostic that answers the network question and a separate request that answers the authorization question.&lt;/p&gt;
&lt;p&gt;When results disagree, don&amp;rsquo;t average them. If the network probe succeeds and the service denies access, inspect identity and operation. If the role appears valid and the request times out, inspect DNS, routing, enforcement, and target listener. If the answers change depending on source, name that boundary instead of calling the environment “reachable.”&lt;/p&gt;
&lt;p&gt;Finally, preserve the failed and successful cases. They define where the boundary currently is. After a remediation, run the same tuple again and test an adjacent path that should remain available. That is how you tell containment from accidental outage.&lt;/p&gt;
&lt;div class="insight"&gt;
&lt;div class="insight-icon"&gt;🍺&lt;/div&gt;
&lt;div class="insight-content"&gt;
&lt;strong&gt;Brewed Insight:&lt;/strong&gt; The packet can reach a target the identity cannot use. The identity can be authorized for a target the workload cannot reach. Neither edge is the whole path; the review has to test where they meet.
&lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.insight {
display: flex;
align-items: center;
background-color: #0089e41c;
border-left: 10px solid #D69A2D;
padding: 10px;
margin: 20px 0;
border-radius: 4px;
}
.insight-icon {
font-size: 24px;
margin-right: 10px;
}
.insight-content {
flex: 1;
}
&lt;/style&gt;&lt;h2 id="learn-more"&gt;Learn More
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/azure/network-watcher/connection-troubleshoot-overview" target="_blank" rel="noopener"
&gt;Connection troubleshoot overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/azure/network-watcher/rbac-permissions" target="_blank" rel="noopener"
&gt;Azure RBAC permissions for Network Watcher&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/azure/network-watcher/connection-troubleshoot-manage" target="_blank" rel="noopener"
&gt;Troubleshoot outbound connections with Connection troubleshoot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview" target="_blank" rel="noopener"
&gt;Managed identities for Azure resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="link" href="https://learn.microsoft.com/en-us/azure/storage/blobs/authorize-access-azure-active-directory" target="_blank" rel="noopener"
&gt;Authorize blob access with Microsoft Entra ID&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>