This companion supports the six-part Engineering Exposure Reduction series. Its purpose is to make a bounded engineering decision reproducible: name the path, choose the boundary, test the operation, preserve necessary dependencies and compare the evidence.
It is a practitioner toolkit, not a Microsoft standard, a complete attack graph or a production auto-remediation framework. Version 1 supplies six review templates, inspection queries and locally tested evidence-comparison tooling. Azure procedures are proposed checks, not observed tenant outcomes. No Azure deployment or live enforcement result is claimed; this version does not include Bicep deployment modules.
Download and local quick start
Download the v1 toolkit ZIP and its SHA-256 checksum.
The bundle contains everything needed to run the local example:
| File | Purpose |
|---|---|
README.md | Runtime, instructions, expected results and limitations |
Workbook.md | Six reusable templates, assumption ledger and sign-off checks |
Compare-ExposureEvidence.ps1 | Read-only validation and comparison of sanitized JSON |
Test-ExposureEvidence.ps1 | Fixture assertions and 11 mutation cases |
fixtures\before.json, fixtures\after.json | Synthetic baseline/after inputs, not observations |
queries\PrivateEndpointInventory.kql | Resource Graph inventory of automatic connections |
queries\FirewallNetworkEvidence.kql | Log Analytics network-rule context |
Windows PowerShell 5.1 is the validated local runtime. No Azure credentials or external PowerShell modules are needed for the comparator or self-test. Review the downloaded scripts, extract the ZIP, then open PowerShell in the extracted directory:
| |
The test prints PASS: fixture comparison and 11 mutation cases; no Azure calls made. It creates uniquely named temporary JSON files and cleans them up. The comparator reads its inputs and prints JSON without changing the files. If execution policy blocks a script, follow your organization’s approved process rather than disabling machine policy.
To check the ZIP, run Get-FileHash -LiteralPath .\azure-exposure-reduction-toolkit-v1.zip -Algorithm SHA256 and compare the hash with the downloaded checksum. This detects different bytes; it is not a signature or proof of publisher authenticity.
Series and modules
| Series article | Toolkit module |
|---|---|
| From Finding to Path: Model Azure Exposure as Reachability | Path record and inventory context |
| WAF, Firewall, DDoS or Network Security Perimeter? Choose by Threat Boundary | Threat-to-control decision matrix |
| Constrain Shared Network Paths with Azure Firewall and AVNM Security Admin Rules | Enforcement and scope test matrix |
| Private Access with Explicit Egress and Exfiltration Guardrails | Destination/operation and residual-risk worksheet |
| Make Remediation Repeatable with Policy, IaC and Expiring Exceptions | Change and exception workflow |
| Measure Exposure Reduction, Not Just Control Deployment | Evidence-pack contract and local comparison |
The series is scheduled for November 3, 5, 10, 12, 17 and 19, 2026. Article links become available as each article is published. The downloaded workbook and local comparison can be used independently of those pages.
Prerequisites and safety boundary
Use only a disposable, author-owned Azure scope with synthetic data and explicit deployment/test authorization. Separate read-only inventory permissions, configuration write permissions and service data permissions. The illustrative service is Blob on supported general-purpose v2 Storage; do not assume equivalent behavior for DFS, Files or another PaaS service.
Record the selected Azure cloud/region, SKU, API/resource versions, CLI/module versions, diagnostic table schema and test principal. Confirm current documentation and resource support before execution. Set a cost/time cap before enabling Firewall, AVNM or billable diagnostics.
Nothing here deploys Azure resources automatically. Do not use an existing tenant merely because a command accepts its identifiers. Never collect tokens, keys or sensitive object contents in evidence exports.
1. Path record and read-only inventory
Use a stable record for each source/principal/destination/operation relationship:
| |
This is a practitioner record, not an Azure resource payload. The finding’s provenance and observation time should accompany it.
Run the bundle’s inventory query in Azure Resource Graph, not Log Analytics:
| |
It discovers declared automatic Private Endpoint connections, not usable operations. Manually requested connections use a different property and need separate inspection. Empty output can reflect missing read scope, inventory delay or no matching resources; it does not prove no path exists. For a supported VM NIC, this read-only Azure CLI inspection collects routing context:
| |
Record the selected destination and route, not just the existence of an exported table. Read failures or missing scope make the context unknown.
2. Threat-to-control matrix
| Path failure | Candidate | Required boundary evidence | Counterexample |
|---|---|---|---|
| Unwanted application request | WAF on selected supported host | Effective policy/mode and harmless rule-match result | Direct-origin access or an authorized harmful operation remains possible |
| Unwanted traversing connection | Azure Firewall | Selected route, effective parent/child policy and rule result | An alternate route never reaches the appliance |
| Unwanted supported PaaS public access | NSP | Supported association, mode and service-specific access result | Private Endpoint traffic is not blocked by explicit NSP rules |
| Network-layer availability pressure | Eligible DDoS offering | Actual coverage configuration and support review | Application-layer overload or dependency failure remains |
Use a harmless test marker against an author-owned application. Do not provide exploit payloads or generate DDoS traffic. Coverage review is not a mitigation experiment.
3. Shared-path enforcement matrix
| Case | Expected documented relationship | Required observation |
|---|---|---|
| AVNM Allow plus NSG deny | NSG may reject | Fresh connection, supported target and effective configuration |
| AVNM Deny plus NSG allow | Admin deny blocks | Same case with corroborating enforcement evidence |
| AVNM AlwaysAllow plus NSG deny | Further NSG evaluation bypassed | Narrow approved case; record the loss of workload-level restriction |
| Firewall application restriction plus broad network allow | Earlier matching network rule can terminate evaluation | Policy hierarchy, rule types and actual flow |
| Out-of-scope source/target | Claimed central boundary may not apply | Separate result; never fold into an in-scope pass |
Current AVNM documentation excludes Private Endpoints from security admin-rule application and describes eventual consistency. Check the full current exclusion list for the chosen topology.
This module is a bounded test matrix, not a deployable Firewall/AVNM configuration. If you implement it, select supported API versions and a disposable canary scope, compile your IaC, inspect the deployment diff, and document permissions, convergence, rollback and cleanup. Do not reuse historical AVNM examples or assume a simulation mode.
4. Controlled egress and residual risk
From the actual source context, resolve the normal service name and inspect TCP connectivity:
| |
This deliberately stops on a failed diagnostic probe; it is not the prohibited-operation acceptance test. A blocked data operation needs its own service result and control attribution.
For each destination record source resolver, returned address, principal, subresource, operation, expected/actual result, error/request reference, control evidence and residual. Test approved reads, controlled unintended writes, separately declared public access, telemetry continuity and responder access.
Keep service-side onward movement separate from workload egress. Identify the owner and review export, replication or downstream consumers rather than claiming the first-hop restriction covers them.
5. Change and exception workflow
Use this sequence: reviewed path claim -> versioned diff -> scoped preflight -> approved canary -> operation/positive-control tests -> expansion or stop -> residual/rollback record.
The exception record needs owner, approver, resource/assignment scope, waiver or mitigated rationale, expiry, compensating test, renewal conditions and an expiry action. Azure Policy’s expiresOn ends honoring the exemption; Microsoft documents that the object remains. Do not assume expiry immediately changes existing deployed state.
Validate actual policy effects, aliases, remediation identity roles and applicability. Add an incident override that prevents routine automation restoring unsafe reachability while responders contain a workload. Test the override’s expiry and reconciliation process too.
6. Evidence comparison
The local PowerShell helper compares sanitized exports only. It does not query Azure, deploy controls or calculate a security score.
Each input contains scopeVersion, configurationVersion, observedAtUtc, and cases. Each case contains pathId, source, principal, destination, operation, intent (prohibited or required), status (reachable, blocked or unknown) and evidenceRefs.
Comparisons reject mismatched scope, changed case identities, duplicate/missing cases, invalid states, non-UTC observation times and absent evidence references. A scope change needs a new comparison contract, not a silently smaller denominator. For unknown cases, an evidence reference can identify the failed collection or test record; it must not invent the missing observation.
Use the quick-start commands above with the bundled fixtures. Their dates are invented ordering inputs, not observations. Expected results deliberately include both an improved candidate and a newly reachable path:
| Report field | Fixture result |
|---|---|
assuranceStatus | not-assessed |
candidateRemoved | unwanted-write |
newlyReachable and remainingReachableProhibited | alternate-write |
inconclusive | unknown-export |
baselineRequiredNotReachable and requiredNotReachable | empty arrays |
The report lists candidate removed prohibited paths, remaining reachable paths, newly reachable prohibited paths, unknowns and failed required cases. A candidate-removed classification is a bookkeeping result, not proof of attributable enforcement or durable containment. Verify raw evidence, recovery checks and reopening authority before drawing that conclusion.
For your own evidence, copy the fixtures to new files, preserve stable case identities and replace synthetic values with authorized, sanitized observations. Use actual configuration versions and UTC timestamps. Evidence references must identify real records, including collection failures for unknown cases. The comparator does not open or authenticate those referenced records.
The bundle’s Firewall query runs in an authorized Log Analytics workspace with resource-specific network-rule logging and AZFWNetworkRule available. Replace the illustrative window and addresses:
| |
These fields do not supply a deterministic principal-to-Blob-operation join. Time/tuple correlation can be ambiguous with translation or concurrent traffic. Missing rows remain inconclusive until collection, transit and window assumptions are checked.
Validation, acceptance and maintenance
Version 1’s fixture assertions and 11 mutation cases have been run locally on Windows PowerShell 5.1. They cover unchanged and unknown results, required-path failure, scope/case mismatches, duplicate IDs, changed principals, invalid status, missing evidence and timestamp constraints. This validates local comparison behavior, not Azure enforcement. The workbook and queries are documentary/procedural examples; they have not been executed against a live Azure scope.
Before executing an Azure procedure, complete the workbook’s assumption ledger: cloud/region, SKU/service support, selected API versions, client versions, scope/roles, DNS/routes, actual diagnostic schema and collection timing. Record the documentation basis separately from dated lab observations.
Accept a change only when the intended boundary is supported by evidence, required paths still work and residuals have accountable ownership. Newly reachable prohibited paths, failed recovery and unresolved observations need explicit disposition; one removed candidate is not an overall pass.
Retest after API, schema, support, topology or role changes. Run the local self-test after editing the comparator or fixtures. General telemetry collection guidance remains in the Azure Security Telemetry Toolkit; this companion focuses on deciding and validating a bounded exposure change.