Azure App Service provides a way to configure access restriction policies to allow/deny network access on workloads (Azure Function App/Web App etc) hosted on the App Service. This policy can be set to allow/deny access based on
1) IP addresses
2) Azure Virtual Network subnets.
The detailed description of this capability is available in the Microsoft Documentation of this feature.
By setting network access restrictions, you can ensure that only the consumers with specific IP addresses or Azure Virtual Networks are allowed to access the App service.
In the below example, we have a API built using Azure Function App that can be consumed by several teams/business units within an organization. We have set access restrictions on the API app to allow specific IPs and Azure Virtual Networks.
There are a few considerations in order to configure these access restrictions through the Azure portal.
1) The user account that configures these access restrictions must be assigned specific privileges on the consumer's Virtual Network. Either 'Network Contributor' role can be assigned to this account OR to ensure the least privileges, a custom role with the below permissions can be assigned
- Microsoft.Network/virtualNetworks/subnets/joinViaServiceEndpoint/action
- Microsoft.Network/virtualNetworks/subnets/read
- Microsoft.Network/virtualNetworks/read
This means that individual user accounts from the API's development/operations team will have access to consumer's VNETs.
2) The user account must continue to have access on these virtual networks in order to be able to make any changes to the access restriction configurations. For example, if the access of a user account configuring these policies is removed from the "Cloud COE" VNET, an attempt to add or remove a policy fails.To get around this issue, the VNET from which user's access was revoked must be removed from the configuration first.
The failure message can be seen in detail through the Azure CLI
az webapp config access-restriction remove -g SharePointSiteProvisioningAPI -n SiteProvisioningAPI --rule-name "Cloud COE IP-1"
The client 'OpsUser@<domain>.onmicrosoft.com' with object id '<objectID>' has permission to perform action 'Microsoft.Web/sites/config/write' on scope '/subscriptions/<subscriptionID>/resourceGroups/SharePointSiteProvisioningAPI/providers/Microsoft.Web/sites/SiteProvisioningAPI/config/web'; however, it does not have permission to perform action 'joinViaServiceEndpoint/action' on the linked scope(s) '/subscriptions/<subscriptionID>/resourceGroups/CloudCenterOfExcellenceRG/providers/Microsoft.Network/virtualNetworks/CloudCOE-Vnet/subnets/CloudCOE-Subnet-SiteProv' or the linked scope(s) are invalid.
Automate access restriction configurations using a Service Principal :
The use of individual user accounts for configuring access restriction can be avoided by automating this operation using a Service Principal identity. One way to achieve this is by Azure PowerShell or Azure CLI. However, NOTE : that if you wish to whitelist a Virtual Network that lies in a different subscription, this isn't supported in Azure CLI at the time of writing this blog post.
Till the time (if and when ?) cross subscription whitelisting is available in Azure CLI/Az PowerShell, this can be achieved using the Azure Management REST API.
The script below authenticates to AAD using a Service Principal, which has been assigned a custom RBAC role (with permissions explained above) on the API consumer's Virtual Networks and uses the Azure Management API to update 'ipSecurityRestrictions' in web site's config. The Script is intended to be used on PowerShell Core with latest Az module version to enable the use of 'Get-AzAccessToken' command.
Configure the '$ipRules' and '$vnetRules' in the script to configure access restrictions.