Over the past few years, Microsoft Flow has steadily grown in both popularity and capabilities. In this time dozens of new connectors and hundreds of templates have been added, enabling businesses and end users to automate basic tasks or complex processes. However, it’s not all rainbows and unicorns, as there are many problems associated with governing Flow. In this article, I will highlight some areas for improvement and few possible ways to overcome them, at least when it comes to Exchange Online.

A Microsoft Flow Recap

Configuring forwarding in your Office 365 mailbox

In Office 365, we have several ways to configure email forwarding. An admin can enable this on a per-mailbox basis, users themselves can enable it via OWA or configure a rule from either OWA and Outlook. Flow offers another approach, by leveraging the Office 365 Outlook connector and the underlying API operations to get the content of a message and send a copy of it to an address of your choosing.

What this means is that the user has the capability to open the Flow page, navigate to My Flows, press the New button and select Create from the template, then select the Email category and look for the Forward emails with and without attachment from Office 365 template. Alternatively, they can simply search for the “forward” keyword.

Once the template has been selected, the user provides some basic information so that Flow knows which messages to forward and to who. This process is illustrated in the screenshot below:

The first group represents the trigger, which starts the flow based on a specific event occurring. In this scenario, the trigger is the arrival of a new message in the Inbox folder. The template allows the user to specify a different folder or criteria, so the flow is only triggered by the messages they want. For example, you can exclude messages with attachments or only forward messages received from a specific sender.

The second group represents the flow action, this is the same for any of the remaining groups. For the Send an email action, you must specify the recipient address to which all your messages will be forwarded to. This can be any address, including ones which are external to the user’s organization. If needed, Flow allows the user to specify multiple addresses, separated by a comma. Other settings in Flow include: allowing users to configure a different From address, add additional recipients in the CC or BCC boxes, to specify whether any attachments should be forwarded along with the message, and more.

Next, the Mark as read action is included. If you want to avoid messages being marked as read when forwarded, you can remove the action by pressing the “…” menu on the top right and selecting Delete. The Move email action will also run, transferring the message out your Inbox to a folder of your choosing. If you want to avoid this from happening, you can remove the action. Should you want to add additional actions, such as deleting the message or flagging it, you can do so by pressing the New step button on the bottom.

Once you’re done filling in the required parameters or customizing the template, press the Save button, this is where Flow will start working its magic. The service will periodically check for any new messages (every 5 minutes in the free tier of Flow). If a new message is detected, the corresponding actions will be executed, which in our case means sending a copy of the message to the designated recipient(s). This message will be sent as the user (impersonation), from the Office 365 email servers, making it hard to distinguish from any message the user would send manually. I’ll share why this is important later in this article.

Where Flow falls short

Now that we’ve covered a somewhat lengthy introduction around the problem with Flow for Exchange Admins, let’s look at the reason behind writing this article. A recent post on the Microsoft Tech Community asked how we can prevent users from using the forwarding template. The main reason being, the organization already had controls in place to restrict forwarding to external addresses.

Without going into too much detail, none of the methods currently available for blocking external forwarding in Exchange Online will capture messages generated via this Flow template. Since Flow effectively acts as a client connecting to the mailbox and composing a new message, preventing users from configuring their forwarding options in OWA will not have any effect. Unlike messages forwarded via Outlook rules, messages forwarded via Flow do not contain the headers that allow the “message type: auto-forward” to detect them. In effect, any user that configures Flow for this purpose will be able to bypass the restrictions configured by the IT staff.

What’s increasingly concerning is that these actions will bypass the detection rules that inform admins about “regular” forwarding activities. The Flow creation itself is audited, but the level of detail presented in the log entry doesn’t reveal which exact template, triggers or actions were used. On Exchange’s side of things, the audit logs will contain no MailboxLogin events, informing that Flow has accessed the mailbox. In addition, no “send” event will be visible, as Flow basically impersonates the user and sending owner-authored messages is not audited in Exchange Online. The only event which you will be able to see in the logs is the “Moved message”, which may as well not exist if the user removed this action from the Flow.

At this point, you might be convinced that this particular Flow should be disabled in your organization. Unfortunately, Flow doesn’t do well when it comes to controlling what users can achieve by leveraging its advanced automation capabilities. Every new connector and template is made immediately available to any user in the organization, with zero admin control. There is no option to disable a specific connector or limit its use to a subset of users. Similarly, for every connector, there is zero control over triggers or actions that admins can exercise.

In effect, there are several issues: a design that bypasses the restrictions set in Exchange, lack of admin control and lack of proper auditing. Since Flow is a first-party product, customers generally expect it to respect the settings and restrictions configured in other parts of the service. This is currently not true, and the template we used as the example above is just one of many that can be abused in a similar fashion. While admins can still review, disable or delete flows created by their users via the Flow admin portal, this is a reactive approach, and many haven’t made a habit of periodically reviewing Flow usage in their organization.

Admin controls for Flow

As mentioned above, we don’t have any way to disable specific Flow connectors, triggers or actions. What’s even more annoying is that you can’t prevent users from accessing Flow altogether. Flow isn’t programmed to consider licensing and therefore allows the user to self-provision even if no SKUs that include Flow are provisioned in the tenant.

If the user has a license that includes Flow, removing it will have no effect. If the user doesn’t have a matching license, the user will still be able to access Flow and depending on the tenant configuration, the FLOW_FREE SKU might automatically be provisioned.

As an example, consider a tenant without matching SKUs. This screenshot illustrates the list of SKUs in the tenant before the first time Flow is accessed by any user, and immediately after the fact:

While we do have the option to block such ad-hoc subscription provisioning, in the case of Flow it doesn’t make a difference – users can still access Flow even if no SKU exists. This is illustrated on the screenshot below, where another tenant is used with the corresponding ad-hoc provisioning settings disabled. Despite the fact that no Flow SKU exists, the user can still access and use Flow:

Microsoft is well aware of this, as evident from the documentation and the lengthy FAQ article dedicated to clearing up the confusion around licensing Flow. The FAQ fails to answer the question “How can an admin prevent users from accessing Flow”, but we will outline a few methods in the next section.

The other set of admin controls we have for Flow revolve around restricting cross-connector data sharing. Dubbed Data Loss Prevention policies, they allow us to define which connectors can “exchange” data between them, for example, you can block a flow that gets data from Outlook and posts it to Twitter. DLP policies do not apply to scenarios where a single connector is involved however, which is the case at hand. And contrary to what the documentation says, DLP policies cannot be used to prevent a connector from accessing data, they only prevent “sharing” it.

Methods to disable or restrict Flow

Now that we’ve discussed the admin shortcomings of Flow, what can we do about it? If you want to completely disable Flow for the entire organization, disable the corresponding service principals. You can do so via the Azure AD blade, switching to the Enterprise applications tab and searching for “Microsoft Flow”. Once the entries are returned, click each of them, go to Properties and toggle the Enabled for users to sign-in control. Or you can do it via PowerShell:

This will disable both the portal application and the backend services, so users will no longer be able to access the application or run existing Flows.

Another method to disable Flow, which gives you more customizability, is to use Conditional Access. You can either create a policy that uses the “cloud app” condition and specify Flow, or alternatively configure the Locations condition, and enumerate all the Flow IP ranges for your region. Additional conditions allow you to restrict or allow the use of Flow for a specific subset of your users if needed.

So far, we’ve discussed methods that block Flow in general, however, the service itself can be very useful and even vital to business processes in the organization. Therefore, in many cases, it isn’t desirable to toggle it off completely, but instead, restrict certain functionalities. As discussed already, there is no method to disable a specific connector. But when Flow connects to Exchange Online, we do have a number of options to consider.

By looking at the connector description, we can see that Flow uses the REST API to connect to user’s mailboxes. The article also provides us with the user-agent strings that we can use to block Flow access via EWS application policy restrictions: “LogicAppsDesigner/*“,”azure-logic-apps/*“,”PowerApps/*“, “Mozilla/*“. In addition, the “REST” value should be added, as evident from the mailbox audit logs.

Another way to prevent Flow from running against Office 365 mailboxes is to configure a Client Access Rule. The below PowerShell cmdlet will create a rule targeted specifically to block one of the Flow IP addresses for Europe. A proper rule will require you to include all such IP addresses, the list can be found in the official documentation here.

If a Flow has been blocked by a Client Access Rule, you should expect to see the following error in the Body of the output received:

Another way to block Flow from running against Office 365 mailboxes is to configure a Conditional Access policy, scoped down to the Exchange Online cloud app, combined with the location’s condition. This is a variation of the policy described above, the difference is that we are only blocking Flows that connect to Office 365 mailboxes, not the entire service.

Do note that messages forwarded by Flow still traverse the transport pipeline, therefore they are subject to mail flow rules, DLP rules, RMS encryption, all of which can further help you prevent abuse.

Summary

In this article, we showed how Flow can enable users to use functionalities that might otherwise be disabled by their admins. And, how hard can be for admins to prevent users from doing so, especially if they don’t want to punish the “legitimate” use of Flow in the organization.

In all fairness, Flow is not the only way to circumvent forwarding restrictions. Any user with scripting or programming background can come up with a solution that uses EWS or the Graph API that connects to a mailbox, fetches a message and prepares a new email based on the message content and details. What Flow does is to expose this to the masses. All you need to do is fill in two boxes and you have forwarding configured, undetected and unrestrained by your IT staff.

Hopefully, this will change in the future and Microsoft will release better and more robust admin controls for Flow.