Flows created with the “When a HTTP request is received” trigger can be executed by anyone that knows the URL. This post covers details how to secure the HTTP trigger by using a trigger condition.
I have created a simple two step flow that sends me an email when the flow is triggered:
Using a condition within the flow to compare a value passed in the HTTP works, but will consume a flow run.
Secure the Trigger with a condition to evaluate if the flow should execute
A better method is to use the Trigger Conditions functionality to test if a flow should execute. Trigger conditions must evaluate to true or false, there is a good introduction to trigger conditions here. I will demonstrate the basic premise with an example.
First, access the trigger settings by clicking on the ellipses of the HTTP Trigger:
Set a condition for the trigger, if this condition does not evaluate to true, the flow will not run:
I am passing the header “runKey” to the HTTP Request and testing to see if it matches a random string. Here is the code:
equals(triggerOutputs()['headers']?['runKey'],'FSgWPsAEBDP6epQZ')
The advantages of trigger conditions are:
- It does not execute at all if the condition is not met.
- The flow executes faster as there is no condition within the flow.
- Your run history is cleaner (it only shows if the condition was met).
- The flow is less complicated.
Testing the security with PowerShell
I tested execution of the HTTP trigger in Powershell with the following code:
$flowURI = "https://prod-31.westeurope.logic.azure.com:443/workflows/..." $messageSubject = "Testing HTTP Security Trigger" $messageBody = "Execution test from Powershell" $params = @{"messageSubject"="$messageSubject";"messageBody"="$messageBody"} $headers = @{'runKey' = 'FSgWPsAEBDP6epQZ'} Invoke-WebRequest -Uri $flowURI -Method POST -Headers $headers -ContentType "application/json" -Body ($params|ConvertTo-Json)
In my run history I can see all of the data that PowerShell transferred:
{ "headers": { "Expect": "100-continue", "Host": "prod-31.westeurope.logic.azure.com", "User-Agent": "Mozilla/5.0,(Windows NT; Windows NT 10.0; en-GB),WindowsPowerShell/5.1.18362.752", "runKey": "FSgWPsAEBDP6epQZ", "Content-Length": "115", "Content-Type": "application/json" }, "body": { "messageSubject": "Testing HTTP Security Trigger", "messageBody": "Execution test from Powershell" } }
Important Note
Make sure your trigger condition includes a question mark for your key value, like this:
equals(triggerOutputs()['headers']?['runKey'],'FSgWPsAEBDP6epQZ') Not like: equals(triggerOutputs()['headers']['runKey'],'FSgWPsAEBDP6epQZ')
If you do not include the question mark then anyone that posts to the unique URL will receive the error message back from flow, which will be something like:
equals(triggerOutputs()['headers']['runKey'],'FSgWPsAEBDP6epQZ')' cannot be evaluated because property 'runKey' doesn't exist, available properties are 'Connection,Expect, Host, User-Agent, Content-Length, Content-Type'.
Which as you can see, contains the key that secures the trigger! So be sure to include the question mark, which will simply make that property return null.
I hope this helps, if you have any clever ideas to add to this method, please let me know!
Alan Evans says
Thanks for this, been following your guides
Do you know how to trigger this with Curl, I’m having some issues with the runkey part in CURL
Presumably it’s two headers, but it doesn’t seem to be triggering
Christoper Mcvey says
How would you call a flow as a child with such security? Is there way way to query for the header value when you call the child?
Manish Jain says
I have repeated all the steps as mentioned but I am getting the same error as you mentioned for the headers, do I need to add some more settings/ parameters in it ?
Mark S says
Thank you for this guidance. When the trigger condition fails I assumed that some type of error code would be returned to the calling application. But it appears that a 202 code is returned. If you are calling the HTTP flow from another flow, that makes it very hard for the calling flow to recognize that an error occurred.
I could build my own version of this where I include the key in the body of the POST call, retrieve it in the HTTP flow and check the value passed against the expected value and return an error code in a Response step. It takes more effort but it allows me to return the error code.
Is there any way to use trigger conditions AND return an error code?
Angel Perez says
There is a typo in the code to copy. It is missing the leading @ (at least that was my problem when I copy/paste and did not work) in the picture can be see that it needs that leading @
I am passing the header “runKey” to the HTTP Request and testing to see if it matches a random string. Here is the code:
dipali says
“Important note” did a real magic. Thanks !!