Deploying secure communication with APIm and Functions using Managed Identity

Yes I know, not the snappiest title.
In my previous post Secure communication with APIm and Functions using Managed Identity, I showed how easy it is to setup OAUTH-based authentication in front of your Azure Functions, and how to configure an APIm policy to call that function, thereby uping the security level of your Azure Function communication.

CI/CD using ARM

I like ARM and after some serious digging I found the ARM template definition for how to secure your Azure Function. I prefer to use version V2, but you should look at V1 as well, as it has better documentation.

You can find the V2 template definition here, and here is V1.

When you deploy your function app you are using CI/CD and ARM. In order to add the functionality of the authourization setting you need to add a resourse called Microsoft.Web/sites/config and set its name to yourfunctionappname/authsettingsV2. You can either add this to your existing ARM-template or as a separate template. If you add it to your existing ARM template, do not forget to add the dependsOn property.

Minimal ARM Template

Here is my ARM-template that will deploy the settings addressed in the other post.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "appClientId": {
        "type": "string",
        "metadata": {
          "description": "The Client ID of the AppReg that the function is a part of."
        }
      },
      "sites_function_name": {
        "type": "string",
        "metadata": {
          "description": "The function app name"
        }
      },
      "tenantID": {
        "type": "string",
        "metadata": {
          "description": "The ID of the tenant providing auth token"
        }
      }
    },
    "resources": [
      {
        "name": "[concat(parameters('sites_function_name'), '/authsettingsV2')]",
        "type": "Microsoft.Web/sites/config",
        "apiVersion": "2020-12-01",
        "properties": {
          "platform": {
            "enabled": true
          },
          "globalValidation": {
            "requireAuthentication": true,
            "unauthenticatedClientAction": "Return401"
          },
          "identityProviders": {
            "azureActiveDirectory": {
              "enabled": true,
              "registration": {
                "openIdIssuer": "[concat('https://sts.windows.net/',parameters('tenantID'),'/')]",
                "clientId": "[parameters('appClientId')]"
              }
            },
            "isAutoProvisioned": false
          },
          "login": {
            "tokenStore": {
              "enabled": true
            }
          },
          "httpSettings": {
            "requireHttps": true
          }
        }
      }
    ],
    "outputs": {}
  }

I will go thru some of the properties
properties/platform/enabled This basically enables the setting. You can switch this between true or false if you, for instance, have different rules for TEST and PROD. Simply turn it off for TEST and enable it for PROD.
globalValidation/requireAuthentication Should be set to true but in some cases you might want to be able to handle unauthorized calls as well.
globalValidation/unauthenticatedClientAction Set this to Return401 if the function should be called as APIs. For other scenarios, consult the documentation.
identityProviders/azureActiveDirectory This object contains all the settings needed for the AAD type authentication.
identityProviders/azureActiveDirectory/registration/openIdIssuer This points to your tenant using its GUID. If you do not know your tenant GUID you can visit whatismytenantid.com. This setting makes sure that the authenticating token is issued by your Azure tenant.
identityProviders/azureActiveDirectory/registration/clientId This is the ID of Application Registration that was created when you setup the function authentication. If this is the first run, create an application registration first and use it with this function. I made an easy walkthru post a while back.
properties/httpSettings/requireHttps always require HTTPs.

Additional settings

Consider reading the documentation for additional settings. There are a lot of properties relating to other authentication providers, but also some settings relating to authentication and AAD that you might find useful .
jwtClaimChecks/allowedGroups If you are using claims and groups/roles, you can make sure that the caller has the right credentials (I have not validated this functionality with APIm)
allowedClientApplications Stop callers that are not APIm simply by adding the clientID of your APIm (I think, I have not tried this)
allowedAudiences Might be useful to add other clients as audiences as well. The connected Application Registration ID (the clientID in the ARM-template) is always allowed, even if it is not added as allowed.

Next step

You should now add your version of the ARM template to your CI/CD process, and let me know how it works out for you. You can find me on Twitter.

One comment

Comments are closed.