Microsoft has been gradually expanding the reach of its Conditional Access feature, while at the same time also releasing a bunch of controls that allow us to more granularly scope CA policies. Examples in this area include not just the ability to scope policies to a subset of the objects within the directory (i.e. the Guest or external users controls), but also to target objects based on dynamic rules (filter for devices) and even target specific admin actions. Now, in its latest preview, Microsoft is allowing us to also dynamically target specific applications (service principals), by means of the filter for applications feature. Let’s take a look at it.
The first thing to understand here is what “applications” mean. We are of course talking about service principals, and not the actual application object. Service principals are the representation of an Azure AD integrated application within the local directory, and effectively represent the control plane for application access. Thus, the feature can only target applications that have a “visible” service principal, which unfortunately is not the case for many “first party” Microsoft-owned applications. In addition, the feature cannot target “bundle” applications, such as the Office 365 Suite, or the recently introduced Microsoft Admin portals one.
The other important bit is that the Filter for applications feature currently only supports dynamic membership rules based only on Custom security attributes. In case you missed the news on Custom security attributes, we covered them extensively in a series of articles (here and here). Thus, configuring Custom security attributes is a prerequisite for the Filter for applications feature, and no other attributes are supported. In fact, if you have no (suitable) Custom security attributes configured within the directory, you will be greeted with the following error when trying to configure Filter for applications:
There are no custom attributes available to filter on. You will need to configure some attributes to employ this filter.
Thus, our first task is to ensure some Custom security attributes are available for assignment. Assuming you have the necessary permissions, you can navigate to the Entra ID portal > Custom Security Attributes page and hit the Add attribute set button to create a new set. You can also leverage an existing set, but in most cases it makes sense to have a separate set, specifically targeted to service principal objects. As the set name can be anything, we call it “Applications”. After creating the set, we need to add at least one custom security attribute to it, by hitting the Add attribute button. The important requirement to keep in mind is that the attribute must have a type of “string”. The actual values do not really matter – they are just labels we can filter on. It’s up to you to define a set of attributes and values that map to the intended use of applications within your organization. In the example below, we are using a schema similar to that of AIP. Another example is to map the attribute values to specific authentication requirements, as described in the official documentation.
Now that we have a Custom attribute set specifically for applications, we need to “tag” at least one of the service principals within our tenant with the corresponding attribute. To do this, navigate to the Entra ID portal > Identity > Applications > Enterprise applications. Select one of the applications you want to tag, say the Graph explorer one. On the service principal page, under Custom security attributes, hit the Add assignment button. Select the set, attribute and value as needed. Rinse and repeat for any additional applications you want to target.
At this point, we can configure a Conditional access policy with a Filter for devices condition. Our example scenario is to restrict access to specific application(s) to just the set of internal users, by means of configuring a CA policy scoped to said application(s). To create the policy, open the Entra ID portal, navigate to Identity > Protection > Conditional Access > Policies and hit the New policy button. Under the Users condition, select Include > Select users and groups > Guest or external users and check all the categories therein. Next, under the Target resources condition, select Cloud apps then select Include > Select apps > Edit filter (preview). Herein, you will be presented with the familiar “dynamic membership rules” control, where you can configure the scoping filter. Toggle the Configure control to Yes, then under Attribute, select our Applications custom security attribute set, and the AccessType attribute. Use the Equals operator and select Internal for the value. You should end up with something like this:
Now that we have targeted the CA policy to specific applications only, we can also configure the action. For our scenario, this would be a Block access action, which we can toggle under the Grant control > Block access. And with that our policy is ready to test. The test itself we can perform via one of the apps we targeted, in this case the Graph explorer tool. In order to use the tool to access another tenant, we need to append the URL with the ?tenant=tenantname.onmicrosoft.com suffix, after which we login as usual. In our case, a login coming from a Guest user is blocked, as expected:
Further drilldown into the sign-in logs reveals a sign-in error code of 53003, as expected and the corresponding “Access has been blocked by Conditional Access policies. The access policy does not allow token issuance.” failure reason. The processing of the conditional access policy is shown below:
Interestingly, performing a similar test via the Graph SDK for PowerShell resulted in a failure for the CA policy to match the application, even though the logs correctly reflected the app ID. The behavior is likely due to the different auth flow used by the SDK, or some other oddity.
Before closing the article, few words on Graph API support for the feature. While managing CA policies with raw Graph requests is not something we wanted to test, we can at least confirm that the relevant conditions and controls are correctly represented within the JSON output, when you leverage the /beta Graph API endpoint that is. As for support for custom security attributes for service principals, it works pretty much the same way as with the user’s scenario we described previously. For example here’s how to get a list of all service principals tagged by a specific custom security attribute value:
GET https://graph.microsoft.com/beta/servicePrincipals?$count=true&$select=id,displayName,customSecurityAttributes&$filter=customSecurityAttributes/Applications/AccessType eq 'Internal'
Do note that the above is an “advanced query”, so you need the relevant ConsistencyLevel=eventual header and $count operator.