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:

  • Azure Functions ; what is true for Azure Functions will be true for Azure Web App / Web API too
  • Azure Logic Apps ; hence we focus on the Logic Apps exposing an HTTP trigger
  • Azure Cognitive Services
  • VNET-bound Compute (e.g. AKS, App Service Environment, Virtual Machines, etc.)

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:
* Easy to implement
* Strong access mechanism

CONs:
* Coarse grain access

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:
* Easy to implement
* Strong access mechanism

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:
* Relatively easy to implement

CONs:
* With many services, lots of keys to manage (amplified when we consider key rotation)
* If key is leaked, service is compromised

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:
* Relatively easy to implement

CONs:
* With many services, lots of secrets to manage (amplified when we consider secret rotation)
* If secret is leaked or intercepted (e.g. logs), service is compromised
* Requires custom logic

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:
* Strong access control

CONs:
* Requires certificate management
* With many services, lots of certificates to manage (amplified when we consider certificate rotation)
* If certificate is leaked, service is compromised

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:
* Strong access control
* Secret doesn’t get leaked (managed service identity doesn’t expose the underlying secrets)

CONs:
* Requires configuring AAD Applications for each function (or function app, depending how we choose to implement it)
* Custom logic for authorization

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.

Advertisements

One thought on “API Management exclusive access to Azure Function

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s