A common pattern is emerging where an Azure Function will be written that calls back into an O365 tentant to execute calls against various APIs on even via Powershell.
I want to be able to add an Azure AD Conditional Access policy that limits “where” these Azure Functions can connect from.
For example if I have tenant A, and I have an Azure function running on tenant B that uses Powershell to connect to tenant A - how do I configure a conditional access policy on tenant A that controls if tenant B can call tenant A (hope this makes sense).
I had an Azure Function running in a Consumption plan in Tenant B, with this plan I cannot really identify the source IP Address of the function when it is designed to call into Tenant A and so I cannot configure a Tenant A Conditional Access Policy to allow this function "in" (unless I allow ALL IP Addresses from the Azure Data Centre the function is running in).
I then created an Azure Function running in an App Service Plan, with this plan I *can* identify the source IP Address of the function, and so I can register this source IP Address on the Tenant A Conditional Access Policy.
Some other investigations that tripped me up as I was trying to understand all of this connectivity and access controls. The function I was testing was a simple PowerShell script that ran the PnP commands.
This powershell ALWAYS succeeded, even under the Consumption plan and I couldn't understand why. The reason is that using the -Credentials parameter the commandlet uses the Legacy Authentication and not Modern Authentication, and so my Azure Conditional Access Policy never kicked in. I tweaked the Powershell to use the following:
The Microsoft Teams commandlets DO use Modern Authentication and so the Conditional Access Policy does kick in, and for the function on the Consumption Plan the script fails the correct error.
[Error] Connect-MicrosoftTeams : One or more errors occurred.: AADSTS53003: Blocked by conditional access.
When I ran this script in the function running under the App Service Plan it succeeded, as I configured the App Service Plan Outgoing IP Address as being allowed in the Conditional Access Policy.
So if you want to control where functions can connect too your tenant you need to consider the plan the function runs under, and you also need to consider what commands your function will use to connect to your tenant.