Back to Checks
m365

Conditional Access policy excludes Directory Synchronization Accounts to protect Entra Connect sync

entra_conditional_access_policy_directory_sync_account_excluded
Service: entraSeverity: medium
OfficialBuilt-inVerified
Categories:identity-accesse3
Resource Type:NotDefined

Conditional Access policies scoped to all users and all cloud applications are evaluated to confirm the Directory Synchronization Accounts role is explicitly excluded. The Microsoft Entra Connect Sync Account does not support multifactor authentication, so it must be excluded from restrictive policies to maintain directory synchronization.

Risk

If the Directory Synchronization Accounts role is not excluded from Conditional Access policies requiring MFA or blocking access, the Entra Connect Sync Account will be unable to authenticate. This breaks hybrid identity synchronization between on-premises Active Directory and Entra ID, potentially causing authentication failures and identity inconsistencies.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_conditional_access_policy_directory_sync_account_excluded

Recommendation

Exclude the Directory Synchronization Accounts role from all Conditional Access policies that target all users and all cloud applications. This prevents breaking Entra Connect directory synchronization while maintaining security controls for interactive users.

Remediation

Other

1Navigate to the Microsoft Entra admin center at https://entra.microsoft.com.
2Expand **Protection** > **Conditional Access** and select **Policies**.
3Open each policy that targets **All users** and **All cloud apps**.
4Under **Users** > **Exclude**, select **Directory roles** and add the **Directory Synchronization Accounts** role.
5Save the policy.

Check Code

"""Check if Conditional Access policies exclude the Directory Synchronization Account."""

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.entra.entra_client import entra_client
from prowler.providers.m365.services.entra.entra_service import (
    ConditionalAccessPolicyState,
)

# The Directory Synchronization Accounts built-in role template ID in Entra ID.
# This role is assigned to the Microsoft Entra Connect Sync service account and
# does not support multifactor authentication.
DIRECTORY_SYNC_ROLE_TEMPLATE_ID = "d29b2b05-8046-44ba-8758-1e26182fcf32"


class entra_conditional_access_policy_directory_sync_account_excluded(Check):
    """Check that Conditional Access policies exclude the Directory Synchronization Account.

    The Microsoft Entra Connect Sync Account cannot support MFA. Conditional
    Access policies scoped to all users and all cloud apps must explicitly
    exclude the Directory Synchronization Accounts role to prevent breaking
    directory synchronization.

    - PASS: The policy excludes the Directory Synchronization Accounts role.
    - FAIL: The policy does not exclude the Directory Synchronization Accounts role.
    """

    def execute(self) -> list[CheckReportM365]:
        """Execute the check for Directory Sync Account exclusion from Conditional Access policies.

        Iterates through all enabled Conditional Access policies that target
        all users and all cloud applications, verifying each one excludes the
        Directory Synchronization Accounts role.

        Returns:
            A list of reports containing the result of the check.
        """
        findings = []

        for policy in entra_client.conditional_access_policies.values():
            if policy.state == ConditionalAccessPolicyState.DISABLED:
                continue

            if not policy.conditions.user_conditions:
                continue

            if "All" not in policy.conditions.user_conditions.included_users:
                continue

            if not policy.conditions.application_conditions:
                continue

            if (
                "All"
                not in policy.conditions.application_conditions.included_applications
            ):
                continue

            report = CheckReportM365(
                metadata=self.metadata(),
                resource=policy,
                resource_name=policy.display_name,
                resource_id=policy.id,
            )

            if (
                DIRECTORY_SYNC_ROLE_TEMPLATE_ID
                in policy.conditions.user_conditions.excluded_roles
            ):
                report.status = "PASS"
                report.status_extended = f"Conditional Access Policy {policy.display_name} excludes the Directory Synchronization Accounts role."
            else:
                report.status = "FAIL"
                if policy.state == ConditionalAccessPolicyState.ENABLED_FOR_REPORTING:
                    report.status_extended = f"Conditional Access Policy {policy.display_name} reports excluding the Directory Synchronization Accounts role but does not enforce it."
                else:
                    report.status_extended = f"Conditional Access Policy {policy.display_name} does not exclude the Directory Synchronization Accounts role, which may break Entra Connect sync."

            findings.append(report)

        if not findings:
            report = CheckReportM365(
                metadata=self.metadata(),
                resource={},
                resource_name="Conditional Access Policies",
                resource_id="conditionalAccessPolicies",
            )
            report.status = "PASS"
            report.status_extended = "No Conditional Access Policy targets all users and all cloud apps, so no Directory Synchronization Accounts exclusion is needed."
            findings.append(report)

        return findings