Securing your HTTP triggered flow in Power Automate

This is a quick post for giving a response to a question that comes out in our latest Microsoft’s webcast about creating cloud-based workflows for Dynamics 365 Business Central.

In this training I’ve talked a lot about the “When an HTTP request is received” action in Power Automate (and on Azure Logic Apps too) and how it’s extremely important on many scenarios, first of all for starting a workflow from your Dynamics 365 Business Central extensions by simply raising an HTTP call to the flow endpoint.

During the demo, I’ve created a simple HTTP triggered workflow that receives a POST request with a JSON body containing the destination address, the subject and the body of the email and then sends an email. The workflow in Power Automate was created like the following:

The problem here is that the endpoint is “public”, that means that everyone that knows that endpoint can trigger your workflow. The endpoint is something like https://prod-104.westeurope.logic.azure.com/workflows/7cd766d123e84c16a9a8b6c423aeb70a/triggers/manual/paths/invoke?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=rG_OM6yEnEvX8UeEpvZG-8ywZURGon9HU7WJiqn12aa , so not easy to obtain, but that is. As standard, you don’t have the possibility to use “authorization keys” like you can do for example with Azure Functions.

Question was: can I control who can use my Power Automate workflow?

The answer is yes and you have at least three possibilities:

  1. Use trigger conditions in the “When an Http request is received” trigger
  2. Use your security token in the url
  3. Passing a security token in the header of the HTTP call
  4. Use Azure API Management

Point 1 above can be solved by placing the following trigger condition:

equals(triggerOutputs()['headers']?['secretkey'],'secretValue')

where secretKey and secretValue are the secret key name and the corresponding secret value that the flow caller need to pass in the request header.

To use a security token (like Authorization Keys on Azure Functions) you can also change your flow as follows:

As a first step, add a relative path to your HTTP trigger action and here insert a token variable (here called SecurityToken):

Then check the condition of the SecurityToken variable, that must match with your defined authorization key:

If the condition is YES (the incoming caller has passed the right security token) the email is sent and you will receive HTTP status 200. If the condition is not matching (wrong security token) you can return a HTTP 401 error as response (with a custom body message).

What happens now?

The url of your HTTP triggered workflow is changed in this way: https://prod-104.westeurope.logic.azure.com/workflows/7cd766d123e84c16a9a8b6c423aeb70a/triggers/manual/paths/invoke/SendMail/{SecurityToken}?api-version=2016-06-01&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=rG_OM6yEnEvX8UeEpvZG-8ywZURGon9HU7WJiqn12aa

If you pass a valid security token, the workflow completes successfully:

If instead you’re passing an invalid security token, the workflow fails:

and you have an HTTP 401 error as response:

The second possible way is to pass the authorization key to the request header when calling your workflow.

In this case, you can do like the following:

Here, I parse the JSON header of the incoming request in order to extract the SecurityToken parameter and than act as in the previous sample.

The third way is using Azure API Management. This is in my opinion the most “production-ready” way of work. You can create an instance of Azure API Management and then import your Power Automate workflow (HTTP endpoint) by selecting Add a new API and then select Blank App. In the Create a blank API page, past the endpoint URL of your workflow:

When the endpoint is imported on Azure API Management, you can control everything for your HTTP-triggered workflow (you can analyze the incoming request, specify policies for authentication and access restriction and also define custom authentication policies):

14 Comments

  1. How are the first 2 options that different from the original http request without token?
    Not using a token, provides public exposure to the API in case the endpoint is known.

    Include an additional fixed security token in the url / header, wouldn’t that result in a similar risk if one would know the endpoint with the – unencrypted – token?

    I struggle with the same issue when using Azure Functions too. If the admin / host keys are known (since these are not encrypted either), you’re function is available to anyone with the endpoint too.

    Like

    1. Absolutely agree with you. While keys provide a default security mechanism, you may want to consider additional options to secure an HTTP endpoint in production. App Service authentication or API Management offers more robust security mechanisms for example.

      Like

  2. How does the third option secure the endpoint further? The original endpoint is still available, unless you can configure it to only be called by the API Management service.

    Like

    1. Yes. But normally when you create an Http Triggered flow you need to provide the flow url to your end users. In this case, you send them not the flow url but the API Management url where you can apply filters, authentication and so on. The flow endpoint will never be known.
      Obviously if you want more than this you need to mix things (API Management + authentication token in flow).

      Liked by 1 person

  3. Im getting bellow error for method 3. I have not set up any authentication/authorization as well
    {
    “error”: {
    “code”: “AuthorizationFailed”,
    “message”: “The authentication credentials are not valid.”
    }
    }

    Like

  4. I have implemented the 3rd option exactly the way you explained and adding an inbound rule based on allowing IPs. However it does work for me, I still can call the API from any IP.
    Am I missing something ?
    Thanks in advance.

    Like

      1. I didn’t realized that I needed to use the APIM URL + subscription key.
        All good now !
        Thanks for this great article.

        Like

  5. Thanks for the article. As others mentioned, I’m not happy either for prod-envs as long as the PA endpoint is still exposed to the internet. MS really needs to add an option to make the endpoints only callable by APIM.

    Like

    1. Yes, in this case the Power Automate direct url is never exposed to callers. But obviously if someone knows it because you’ve shared it previously, the flow can be triggered.

      Like

  6. Amey & ItsBradMorgan: Were you able to work around this issue? I am seeing exactly the same behavior

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.