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.
Build the required trigger expression
Instead of writing the trigger condition manually, let Power Automate build it for you. Create a compose action in your flow that evaluates to true or false and copy the code into the trigger condition.

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" } }
I hope this helps, if you have any clever ideas to add to this method, please let me know!
estevao santos says
Just to point out that the trigger condition should be `@equals(triggerOutputs()?[‘headers’]?[‘runKey’],’FSgWPsAEBDP6epQZ’)` with a question mark before headers and runkey. Or else the flow will respond with an error that exposes your secret key.
ps says
Be careful how you do that.
If you only do a validation on the VALUE and not the presense of the key the VALUE is sent back in the Response along with the Response from the Trigger.
In Mine I check to see the value of a header parameter api-key
@equals(triggerOutputs()[‘headers’][‘api-key’],”)
If I send a request with an invalid key I get a 202 Accepted with no body (Flow never ran)
If I send a request with NO Key, PowerAutomate will tell me what the key is…..
{
“error”: {
“code”: “InvalidTemplate”,
“message”: “The template language expression evaluation failed: ‘The template language expression ‘equals(triggerOutputs()[‘headers’][‘api-key’],”)’ cannot be evaluated because property ‘api-key’ doesn’t exist, available properties are ‘Cache-Control, Connection, Accept, Accept-Encoding, Host, User-Agent, Postman-Token, Content-Length, Content-Type’. Please see https://aka.ms/logicexpressions for usage details.’.”
}
}
If you are going to use this approach be sure to have a prior condition that checks to see if the header key actually exists
Like this.
@contains(triggerOutputs()[‘headers’],’api-key’)