Back to Checks
m365

Default app management policy enforces credential restrictions on applications and service principals

entra_default_app_management_policy_enabled
Service: entraSeverity: medium
OfficialBuilt-inVerified
Categories:e3
Resource Type:NotDefined

Microsoft Entra ID default app management policy is verified to have the required credential restrictions configured for applications: block password addition, restrict max password lifetime, block custom passwords, and restrict max certificate lifetime.

Risk

Without the required credential restrictions, applications and service principals can use insecure credential configurations, including long-lived secrets, custom passwords, or unrestricted certificates, increasing the risk of credential compromise and unauthorized access.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_default_app_management_policy_enabled

Recommendation

Configure the default app management policy with all required credential restrictions: block password addition, restrict max password lifetime, block custom passwords, and restrict max certificate lifetime. These restrictions prevent applications from using insecure or long-lived credentials.

Remediation

Other

1Navigate to the **Microsoft Entra admin center** (https://entra.microsoft.com/).
2Go to **Identity** > **Applications** > **App management policies**.
3Select the **Default app management policy**.
4Under **Password restrictions**, enable: **Block password addition**, **Restrict max password lifetime**, and **Block custom passwords**.
5Under **Certificate restrictions**, enable: **Restrict max certificate lifetime**.
6Save the changes.

Check Code

from typing import List

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.entra.entra_client import entra_client


class entra_default_app_management_policy_enabled(Check):
    """
    Check if the default app management policy has the required credential restrictions configured.

    This check verifies that the tenant-wide default app management policy enforces
    the required credential restrictions on applications: block password addition,
    restrict max password lifetime, block custom passwords, and restrict max certificate lifetime.
    """

    REQUIRED_PASSWORD_RESTRICTIONS = {
        "passwordAddition": "Block password addition",
        "passwordLifetime": "Restrict max password lifetime",
        "customPasswordAddition": "Block custom passwords",
    }
    REQUIRED_KEY_RESTRICTIONS = {
        "asymmetricKeyLifetime": "Restrict max certificate lifetime",
    }

    def execute(self) -> List[CheckReportM365]:
        """
        Execute the default app management policy check.

        Verifies that the required credential restrictions are configured
        and not disabled in the application restrictions of the policy.

        Returns:
            List[CheckReportM365]: A list containing the check report.
        """
        findings = []
        policy = entra_client.default_app_management_policy

        if policy:
            report = CheckReportM365(
                self.metadata(),
                resource=policy,
                resource_name="Default App Management Policy",
                resource_id=policy.id or entra_client.tenant_domain,
            )

            if not policy.is_enabled:
                report.status = "FAIL"
                report.status_extended = (
                    "Default app management policy is not enabled, "
                    "credential restrictions are not enforced."
                )
            else:
                app_restrictions = policy.application_restrictions

                enabled_pwd_types = set()
                enabled_key_types = set()

                if app_restrictions:
                    for cred in app_restrictions.password_credentials:
                        if cred.state != "disabled":
                            enabled_pwd_types.add(cred.restriction_type)
                    for cred in app_restrictions.key_credentials:
                        if cred.state != "disabled":
                            enabled_key_types.add(cred.restriction_type)

                missing = []
                for rtype, name in self.REQUIRED_PASSWORD_RESTRICTIONS.items():
                    if rtype not in enabled_pwd_types:
                        missing.append(name)
                for rtype, name in self.REQUIRED_KEY_RESTRICTIONS.items():
                    if rtype not in enabled_key_types:
                        missing.append(name)

                if not missing:
                    report.status = "PASS"
                    report.status_extended = (
                        "Default app management policy has all required credential "
                        "restrictions configured: block password addition, restrict "
                        "max password lifetime, block custom passwords, and restrict "
                        "max certificate lifetime."
                    )
                else:
                    report.status = "FAIL"
                    report.status_extended = (
                        "Default app management policy is missing the following "
                        f"credential restrictions: {', '.join(missing)}."
                    )

            findings.append(report)

        return findings