API Management exclusive access to Azure Function

[Update 05-04-2019: Erratum on the original article. Logic Apps is actually able to perform public IP filering.]

Azure API Management acts as a front door to your APIs.

Typically, we do not want users / apps to be able to access the underlying APIs directly since that would bypass the API Management policies, e.g. throttling, or even security.

In this article, we’ll look at the specific scenario of API Management fronting three types of Azure services:

We will look at the different ways we can protect those services from being accessed by anything but the API Management.

The different options are enumerated in the FAQ. We are going to add one (bearer token) and detail how to use those options.

The right answer for your architecture might be more than one option. You might opt to build Layered security so that if one mechanism fails because of some weakness in your process, another mechanism will take over. I encourage this as long as it doesn’t bring your architecture down by the weight of the mechanisms.

Public IP filtering (Functions & Logic Apps)

The low hanging fruit is the public IP filtering.

API Management exposes a stable Virtual IP (VIP) for each region. Those IPs are used as outbound IPs by the service to contact other services.

There are some circumstances when those IPs could change. This basically happen when we delete / modify the instance.

We could therefore use that public IP to restrict access to the underlying App Service.

PROs:

CONs:

Private IP filtering (VNET Bound Compute)

API Management can be bound to a Virtual Network’s subnet (one per region).

For VNET bound compute, this could be used to inform an NSG rule blocking everything but the traffic incoming from those subnets.

PROs:

Access keys (Functions, Logic Apps & Cognitive Services)

Azure Functions, Logic Apps & Cognitive Services have access keys.

We have reviewed the different HTTP authorization levels for Azure Functions in a past article.

Logic Apps also use access keys. By default, the primary key is used to build a SAS for an HTTP trigger. But with a little persuasion, we can also use the secondary key. This allows us to rotate the keys without disrupting the service.

Similarly, Cognitive Services also have a primary & secondary key.

Here we need API Management to use some secrets in order to access the services. Secrets can be stored and managed as named value within API Management. Key Vault can’t be leveraged yet as the integration between the two services is still limited at the time of this writing (end of March 2019).

PROs:

CONs:

Basic authentication (Functions, Logic Apps & VNET bound compute)

We can also have API Management sending some secrets clear text within the request, either within the URL or the payload.

This can often be implemented with the help of infrastructure (e.g. IIS). In many cases though, this would require some customization. For instance, a Logic App would validate the payload as a first step.

PROs:

CONs:

Mutual authentication with client certificate (Functions & VNET bound compute)

API Management can use a certificate to authenticate itself to an API. Key Vault can be used to store certificates.

App Service online documentation shows how to implement that. This would work for Azure Functions in particular.

PROs:

CONs:

Bearer token (Functions, Logic Apps & VNET Bound Compute)

This is the approach we add to the ones already documented online.

Here we have the proxied service (e.g. Function) be represented as an Azure AD (AAD) Application. API Management, as a client, will authenticate through that AAD Application and acquire an access token. It will then pass that token as a bearer token in the request.

In order to do so, we can leverage API Management Managed Identity. This can be done with the following policy:

<authentication-token token-type="managed-service-identity" resource-url="AAD APPLICATION ID" />

This policy will acquire a token using the service managed identity.

Custom logic can be implemented for authorization. For App Service, the ClaimsPrincipal can be used to retrieve principal’s identity. We could then check membership to a group for example.

PROs:

CONs:

Summary

Here is a summary of the different options we have to secure access to different services:

Functions Logic Apps Cognitive Services VNET Bound Compute
Public IP filtering X X
Private IP filtering X
Access keys X X X
Basic authentication X X X
Mutual authentication with client certificate X X
Bearer token X X X

We gave some pros and cons for each method.

As mention in introduction, more than one method can be used at the same time. For instance, we could implement both a private IP filtering on VNET bound compute in order to block access. We could then also use a bearer token or a basic authentication to make sure the caller is who we think it is. This way if the NSG gets broken by some human error, the service isn’t wide open.


Leave a comment