Authenticating Requests to a Logic App

One of my Logic Apps originally had just three steps:

    1. HTTP trigger
    1. Deserialise HTTP request JSON payload
    1. Send objects from the request payload to a Service Bus queue

Another Logic App would read the objects from the Service Bus queue, use them to query another source for data, then send a email to whatever address was in the initial request. I used this approach because there could be more requests than a Logic App can handle concurrently, and it made sense, therefore, to queue the requests. The problem with that is it would have been trivial for someone to hammer the Logic App with requests containing arbitrary email addresses, and those requests would have been queued, preventing legitimate requests being read. This would be a form of Denial of Service attack.

A firewall configuration that allowed requests only from intended applications should have mitigated this risk, but that causes no end of problems when dealing with ‘microservices’. Instead, I needed to assume the firewall would be disabled, and redesign the Logic App to authenticate the HTTP requests it does receive, before the payload is processed.

My solution here is very basic - the client application sends an API key value with its requests, and the Logic App simply checks that against a predetermined value. If both match, the request payload is deserialised and sent to the Service Bus queue. If they don’t match, the Logic App terminates. Basically it’s an if-then statement thing. I think this is good enough, if the API key is sent in the request header, if the requests are sent over HTTPS, and if both the requesting application and the Azure Resource Group store the secret value relatively securely.

Key Vault

The API key should be stored in the Azure Key Vault, instead of as a Logic App parameter. A Key Vault, as I’ve described elsewhere, is a storage method that uses a combination of firewall and identity-based authentication to protect secrets. Logic App parameters might not have that degree of protection.

Getting the API Key From the Request Header

Add an ‘Initialize variable’ step to the Logic App. I’ve added it directly after the HTTP trigger, and have named it ‘GetReceivedAPIKey’.

The following custom expression is needed to drill down into the request header for the token:

"value": "@{triggerOutputs()['headers']?['Postman-Token']}"

The Final Design

The Logic App now does the following:

    1. HTTP trigger.
    1. Extract payload from HTTP request.
    1. Read secret from Key Vault.
    1. Read API key from the HTTP request header.
    1. If the Key Vault secret and the API key are the same, send the request payload to the service bus.

The only thing that bothered me a little was the authentication isn’t performed at the earliest stage of the Logic App after the HTTP trigger. As it happens, there’s very little processing involved before the check, aside from extracting the payload, and the authentication method will prevent arbitrary requests being queued and fully processed.