Self Hosted Conditional Access Service

In order to consume our AiTM feed directly into your conditional access policies you can take one of two approaches:

  1. Take advantage of our hosted service (which is a 5 second point and click exercise)

  2. Host your own service (which is a little more complicated, but documented here)

There are multiple advantages to #1 so, if the required permissions allow, we would advise taking this route. If not then #2 will achieve essentially the same outcome, but does come with some added complexity.

 

Overview

There are a couple of options for hosting your own application. The first is to fire up an IDE and write the code. Another is to take advantage of some workflow automation tooling. We are going to focus on the latter in this post. Specifically we are going to cover how to automate the updating of your conditional access policy named locations using Azure Logic Apps.

This is really a two stage process:

  1. Create an app registration within Microsoft Azure - the app registration is used in order to provide the required authentication and permissions within your environment (we are basically replicating what exists for the Lab539 hosted service, but within your own environment)

  2. Build an Azure Logic App - this app is what will both obtain the latest fee data and create/update your named location accordingly.

If you’re interested in why we made some of the decisions (which in some cases may seem sub-optimal) then jump to the Design Decisions section at the end and we’ll explain.

 

Creating an app registration within Microsoft Azure

This video takes you through the process of creating an app registration and setting up permissions so that it can be used to periodically update a named location. This stage is essential if you want your logic app to work:

If you’re already an app registration ninja then all you really need to know is that:

  1. You need to set up a client secret

  2. You need to set the required API permissions and grant admin consent:

 

Building an Azure Logic App

When you have an app registration created the next thing to do is to create the Logic App which will use this registration in order to create and update a named location for you. We have already created a template which you can download the ARM template from here. And here is a video showing how you can import and run this within your environment:

If you are a Logic App ninja, or hate watching videos, the main points are:

  1. Import this template into Azure

  2. Edit the following fields to match those in the app registration you just created

    • TenantID

    • ApplicationID

    • Secret

  3. Set the following field to use your Lab539 API key

    • APIKey

If everything is set up well then you’ll see success messages in your logic app and you’ll also see a named location created for you within Azure.

 

Modifications

Once things are running you may wish to modify the logic app to make it more efficient:

  • Currently it searches your named locations for an expected name. Looking in your logic app output you can embed this in your app and avoid pulling a list of named locations each time. Essentially removing the “Get named locations” call and the “For each” loop, BUT jumping straight to the “true” statement (we very much recommend making this change this change). To do this you will need to hardcode the ID of your named location into the app.

  • The logic app is designed to create the initial named location for you. Once this is done a lot of the app functionality is no longer needed (unless you happen to delete the named location and it needs recreating). Therefore, unless you want to automatically recreate the entire named location if it gets inadvertently deleted you can delete the entire “If no existing named location is found” functionality.

If you use the hosted service, we create the initial named location for you and then populate it. This means that we always know the ID of that named location, as it is returned to us when we first create the named location. This means we don’t need to loop through named location names in order to identify the one we want to update. In the logic app this is not the case because we want the app to work the first time and also on future runs without creating a new named location each time. Therefore we do recommend you modify the logic app as described above.

 

Design Decisions

This section is not essential reading, but if you are interested in why we’ve taken some of the approaches that we have it may be of interest.

Webhook vs Polling the API

We really wanted to use webhooks in order to provide real time updates, but because new data often comes in batches, and because logic app workflows run in parallel, we’d have to do something to maintain state so that you were not suddenly hit with 20 concurrent updated to your named location, which inevitably would cause issues. It’s doable with some backend storage, but that suddenly made things quite complicated.

POST vs PATCH

In the logic app, the first time the named location is created we populate it with 127.0.0.1/32 and then update it. The reason for this is that, for some reason, there is a much stricter limit on the size of POST requests within logic apps than there is with PATCH requests. As a result the POST request required to create the initial named location will fail if there is too much data within the named location (which there often is). The same does not appear to be true of the update request, which is identical to the create request other than the use of PATCH instead of POST. Therefore, it’s much more reliable to create a very small named location and then immediately update it in order to populate it with data. We filed that one under “Azure quirks”!

Partial vs Full Update

The approach this app takes doesn’t really update a named location with new data, rather it overwrites it with the most up to date data (this is the same approach that we take with the hosted service too). The reason for this is that we want to ensure that if an update fails in your environment, for whatever reason, that you will not miss out on having that infrastructure added to your named location. Updating in full each time ensures you never miss historical data. Whilst not quite as documented by Microsoft, this approach also means that old infrastructure is removed from your named locations without deleting and creating a new named location, which would invariably mean a need to update your conditional access policies to use the new named location.

Azure Logic App vs Power Automate

You could easily create something quite similar to this using power automate. We went down the logic app route because the feedback we got from you was that this was your preference. It also felt more suited to the task and Microsoft make querying the MS Graph API a premium feature in power automate, in logic apps it’s not, so it’s also a cheaper option.

App registration vs managed identity

We couldn't find a way to set the relevant MS Graph permissions using a managed identity, hence have gone down the app registration route.

Next
Next

File Hosting Services Used for Identity Phishing