It’s common to hear news about sophisticated attacks which are patiently planned and executed, but looking at the big picture – they’re largely the exception. In fact, many breaches are only possible because of a single key element – the human factor, and one of its inherent qualities – laziness. Developers are certainly not the exception here. Ignoring best practices and coding standards for the sake of convenience has become a fact of life, even when it comes to storing application “secrets.”
A recent study shows just how widespread this issue is, with thousands upon thousands of API keys and cryptographic secrets leaked on public code repositories. In turn, this represents an attack vector that even the most inexperienced “script kiddie” can take advantage of.
Microsoft 365 is not exempt. For years, people have stored credentials for automated tasks and workflows in plain text. The advent of multi-factor authentication, conditional access policies, and security defaults help address this problem to an extent. While admins have tools to enforce modern authentication methods for tasks running in the context of a user, on the service principal/application front things remain bleak, as up to now, these authentication flows are not subject to the same controls.
To address the problem, Microsoft is ready to release a set of features to help. In this article, we introduce you to Azure AD application authentication method policies, one of the features in the set.
What are Azure AD App Authentication Method Policies?
In a nutshell, Azure AD app authentication method policies are configuration objects to control the authentication methods used by application and service principal objects within your tenant. The policies do not cover any aspect of the application creation process, nor does it affect the permissions granted to the application – these are covered by different controls already available.
Two types of app authentication method policies are available: a default, tenant-wide policy covering all application and service principal objects (once enabled), and a set of custom policies administrators can create and assign to specific objects. The type of restrictions currently available include passwordAddition, which prevents the creation of new client secrets, and passwordLifetime, which restricts the maximum validity duration for a client secret. For both types of restrictions, you can additionally configure an enforcement date, limiting the scope to only objects created after the specified date-time.
Read more: Achieving Passwordless Authentication in Azure AD
Configuring the Default App Authentication Method Policy
Currently, app authentication method policies are configured using the Graph API. The default tenant-wide policy is pre-created in each tenant. However, it is disabled, and no restrictions are configured. To check the current configuration, you must query the /beta/policies/defaultAppManagementPolicy Graph API endpoint, with the Policy.Read.All permissions being sufficient. Figure 1 shows the default state of the tenant-wide policy using the Graph Explorer tool:
Only a single defaultAppManagementPolicy object can exist in the tenant. The applicationRestrictions and servicePrincipalRestrictions sections define the restrictions applicable to all application or service principal objects within the directory respectively. Both types are represented by an appManagementConfiguration object, which in turn contains a passwordCredentialConfiguration object, detailing the restrictions and related properties.
To update the configuration, you use the Graph API to PATCH the policy. This operation needs which Policy.ReadWrite.ApplicationConfiguration permission. Figure 2 shows the command to enable the default policy and prevents the addition of new password credentials (client secrets) for all application objects created after August 2021:
Testing the Default Policy Configuration
After executing the PATCH request, you should review the policy settings to confirm the changes. In Figure 3, we can see that the tenant-wide policy is now enabled with a restriction of type passwordAddition configured for any application object created after August 2021. In effect, this configuration will prevent the addition of client secrets to any newly created application. At the same time, this policy doesn’t affect third-party apps (service principals) as we didn’t configure any servicePrincipalRestrictions*:
*Another interesting thing to note is that the policy now has a random GUID “id” value generated, compared to the “null” value seen in Figure 1.
So how does the policy affect our apps? Because the policy has an enforcement date, it doesn’t apply to any apps created before this date. For any newly created applications, the policy blocks the addition of client secrets. Instead, developers must use the more secure certificate credential method. The block is flagged by a warning banner in the Azure AD admin portal and the New client secret button is disabled:
Going Granular with App Authentication Method Management Policies
The default tenant-wide policy applies to all application and service principal objects within the organization. This is a terrific way to ensure a basic level of compliance. However, in some cases, you might need a more granular approach. To address the requirement, Microsoft supports custom “resource” policies, which you can assign to specific apps or service principals to override the tenant-wide policy.
No custom policies exist in the tenant by default, as you can verify by querying the /beta/policies/appManagementPolicies endpoint. To create a custom policy, you issue a POST request against the /beta/policies/appManagementPolicies endpoint, with Policy.ReadWrite.ApplicationConfiguration permissions. The request should contain displayName, description and restrictions elements, with the latter defining the controls to enforce. For example, Figure 5 shows how to use the Graph Explorer to create a new policy configured with a restriction on the maximum lifetime allowed for a client secret:
Once created, our custom policy is nothing more than a placeholder. To apply the restrictions, the policy must be assigned to specific object(s), by issuing a POST request against the corresponding /applications or /serviceprincipals endpoint, referencing the policyId (seen in Figure 5 as part of the response for the creation of the policy) in the appManagementPolicies. For example, to assign the newly created policy to an application object App1, we can use the command shown in Figure 6:
After assigning the policy, we can verify its effect by navigating to the Certificates & secrets page for the app in the Azure AD admin center (Figure 7). Since the custom policy takes precedence over the tenant-wide policy, the first thing you will notice here is that we can add a new client secret.
However, we are only able to configure a lifetime for the secret in accordance with the policy restrictions, displayed on top of the Add a client secret pane. Values that conflict with the policy are grayed out:
Additional Details and Summary
So far, we haven’t covered how app authentication method policies apply to service principal objects. This is an important scenario, as most applications your organization use are likely third-party ones, represented via service principal objects within your directory.
Defining a set of servicePrincipalRestrictions within the tenant-wide policy or creating custom policies and assigning them to service principal objects as needed allow organizations to assert some control over the quality of authentication methods used with third-party applications. In turn, this will drive ISVs to adopt best practices faster!
While application authentication method policies are an excellent feature, it’s important to note that they are still in public preview, and as such there might be some rough edges. We already mentioned that currently, all configuration is done via the Graph API, which might be off-putting to some admins. Once the feature reaches GA however, it should be able to configure these controls in the Azure AD admin center.
Going forward, Microsoft plans to add additional controls and thus address the limited scope of the current version of the feature. These controls will likely include key credentials (certificate) restrictions, such as limiting the lifetime or issuer. Some other ideas have been floated, such as the ability to limit the number of credentials configurable for a given application or more exotic things such as preventing credential reuse across multiple applications.
In summary, application authentication method policies will help Microsoft 365 customers adhere to best practices for managing application credentials, as well as asserting some pressure on ISVs to do the same. Going forward we can expect this to turn into a standard configuration, enforced across many organizations.
It is also worth mentioning that this is just one of multiple features Microsoft is planning to launch in this space. These include the already available app governance, sign-ins for service principals, support for scoped permissions in SharePoint Online, conditional access-like controls for the client credentials flow, and more.
Although one can argue that most of these features are long overdue, we cannot overstate their importance and the effect they will have on improving the threat landscape, at least when it comes to Azure AD integrated applications.
In the meanwhile, Microsoft has added support for restricting certificate (keycredentials) lifetime, via the asymmetricKeyLifetime property, and restricting usage of symmetric keys (symmetricKeyAddition/symmetricKeyLifetime, both under passwordCredentials).