Azure App Service Access Restrictions Skip the SCM Endpoint
A single Access Restrictions panel implies one rule set. Azure App Service actually keeps two, and the deployment surface is usually the one left open.
Operational summary
At a glance
- Symptom
- An Azure App Service that was deliberately restricted to a corporate IP range still allows unauthenticated network access to its deployment surface.
- Likely cause
- Azure App Service exposes two distinct HTTP surfaces under one resource: the production site and the SCM/Kudu management site used for Git deployment, ZIP…
- Impact
- An open SCM endpoint exposes deployment tooling to any network that can reach the public internet path to that App Service.
- Verification signal
- Treat the fix as unverified until both hostnames have been tested from both an allowed and a disallowed network.From the disallowed network, request the SCM hostname and confirm…
- Safe correction
- Close the gap by giving the SCM site an explicit, equivalent restriction rather than assuming inheritance.
- Rollback or recovery
- If the new SCM restriction blocks a legitimate deployment pipeline or break-glass access path, remove the added rule immediately rather than widening it under pressure.az webapp config access-restriction…
Symptom
An Azure App Service that was deliberately restricted to a corporate IP range still allows unauthenticated network access to its deployment surface. The production hostname (APP_NAME.azurewebsites.net) correctly returns a blocked response from outside the allowed range, but the SCM/Kudu hostname (APP_NAME.scm.azurewebsites.net) responds normally from any network, including the Kudu console, deployment credentials endpoint and diagnostic tooling.
False Assumption
The team assumed that configuring Access Restrictions once, in the App Service networking blade, applies a single rule set to every inbound path exposed by that App Service resource. The portal presents Access Restrictions as one panel, which reinforces the belief that the production site and the SCM/Kudu management site share the same allow/deny logic.
Root Cause
Azure App Service exposes two distinct HTTP surfaces under one resource: the production site and the SCM/Kudu management site used for Git deployment, ZIP deploy, the Kudu console and diagnostic APIs. Each surface holds its own access-restriction rule collection. Unless the SCM rule collection is explicitly populated, or the same-restrictions option is turned on, the SCM surface keeps its own default state, which permits all inbound traffic. Restricting only the production site therefore leaves the SCM surface exactly as it was before any restriction work began, regardless of how tightly the main site is locked down.
Impact
An open SCM endpoint exposes deployment tooling to any network that can reach the public internet path to that App Service. Depending on authentication posture, this can allow enumeration of deployment credentials, inspection of environment variables through the Kudu console, or code push through Git/ZIP deploy if publishing credentials are later disclosed or brute-forced. The exposure is easy to miss because the production site’s restriction appears to have worked, and nothing in the standard portal view highlights the mismatch between the two rule collections.
Diagnosis
Confirm the split before changing anything. Retrieve both rule collections for the resource and compare them, then test both hostnames from a network outside the intended allow list.
- List the current rule collections for the App Service and inspect
ipSecurityRestrictions(production site) alongsidescmIpSecurityRestrictions(SCM site). - From a network that is not in the intended allow list, request the production hostname and confirm it is blocked.
- From the same disallowed network, request the SCM hostname and check whether it responds instead of being blocked.
Correction
Close the gap by giving the SCM site an explicit, equivalent restriction rather than assuming inheritance. Add a rule scoped to the SCM site that matches the intended allow list, or enable the platform’s same-restrictions option so the SCM collection mirrors the production collection going forward.
az webapp config access-restriction add
--name APP_NAME
--resource-group RESOURCE_GROUP
--rule-name allow-corp-range
--action Allow
--ip-address CORP_CIDR
--priority 100
--scm-site
Confirm the exact flag names against the installed Azure CLI version before running this in any environment, per the stated prerequisite to verify product version and permissions first.
Validation
Treat the fix as unverified until both hostnames have been tested from both an allowed and a disallowed network.
- From the disallowed network, request the SCM hostname and confirm the connection is refused or returns an access-denied response rather than a normal Kudu response.
- From the allowed corporate range, request the SCM hostname and confirm it still returns a normal authenticated response, so deployment tooling has not been broken.
- Re-list the SCM rule collection and confirm it contains only the intended entries, with no residual allow-all default rule still present alongside the new rule.
Rollback
If the new SCM restriction blocks a legitimate deployment pipeline or break-glass access path, remove the added rule immediately rather than widening it under pressure.
az webapp config access-restriction remove
--name APP_NAME
--resource-group RESOURCE_GROUP
--rule-name allow-corp-range
--scm-site
Stop condition: if removing the rule does not restore expected deployment access within one change window, escalate to the resource owner before making further network changes, and capture the current rule collections as evidence beforehand.
Prevention
Treat the SCM/Kudu surface as a separate control point in every review, not a side effect of production-site hardening.
- Add SCM-scoped restriction rules to the same infrastructure-as-code template that defines the production site rules, so they cannot drift apart.
- Include the SCM hostname explicitly in any external exposure scan or firewall test used to sign off App Service network changes.
- Document the two-collection behaviour where App Service network settings are reviewed, so the assumption is visible to the next engineer who touches Access Restrictions.
Apply the safer control
Before you change production
Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.
Fix commands and configuration
ipSecurityRestrictionsscmIpSecurityRestrictionsaz webapp config access-restriction add
--name APP_NAME
--resource-group RESOURCE_GROUP
--rule-name allow-corp-range
--action Allow
--ip-address CORP_CIDR
--priority 100
--scm-siteVerify, roll back or escalate
Verify
Treat the fix as unverified until both hostnames have been tested from both an allowed and a disallowed network.From the disallowed network, request the SCM hostname and confirm the connection is refused or returns an access-denied response rather than a…
Rollback
If the new SCM restriction blocks a legitimate deployment pipeline or break-glass access path, remove the added rule immediately rather than widening it under pressure.az webapp config access-restriction remove --name APP_NAME --resource-group RESOURCE_GROUP --rule-name allow-corp-range --scm-siteStop…
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.