Back to Checks
m365

A dynamic membership group for guest users exists

entra_dynamic_group_for_guests_created
Service: entraSeverity: low
OfficialBuilt-inVerified
Categories:identity-accesse3
Resource Type:NotDefined

Microsoft Entra groups are evaluated for dynamic membership that includes only users with userType -eq "Guest".

The finding indicates whether a guest-targeted dynamic group exists to centrally scope policies and governance.

Risk

Without a dedicated dynamic guest group, guests may evade consistent Conditional Access and least-privilege controls. This threatens confidentiality via excess data access, weakens integrity through unauthorized changes, and leaves stale external accounts that enable lateral movement.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_dynamic_group_for_guests_created

Recommendation

Establish a dynamic group limited to users with userType -eq "Guest" and use it to scope Conditional Access, least-privilege roles, and access reviews.

Segment guests by risk into separate groups, enforce lifecycle policies, and regularly audit membership and policy coverage.

Remediation

CLI

New-MgGroup -DisplayName 'Dynamic Guest Users' -MailNickname 'DynGuestUsers' -MailEnabled $false -SecurityEnabled $true -GroupTypes 'DynamicMembership' -MembershipRule '(user.userType -eq "Guest")' -MembershipRuleProcessingState 'On'

Terraform

resource "azuread_group" "example" {
  display_name     = "<example_resource_name>"
  security_enabled = true

  dynamic_membership {
    enabled = true  # critical: enables dynamic membership
    rule    = "user.userType -eq \"Guest\""  # critical: includes only guest users
  }
}

Other

1Sign in to Microsoft Entra admin center (https://entra.microsoft.com/)
2Go to Identity > Groups > All groups > New group
3Set Group type: Security; Membership type: Dynamic User
4Click Add dynamic query and set the rule: user.userType -eq "Guest"; click Save
5Click Create

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_dynamic_group_for_guests_created(Check):
    """
    Check if a dynamic group for guest users is created in Microsoft Entra.

    This check verifies that a dynamic group exists for guest users in Microsoft Entra.
    A dynamic group for guest users should have the group type 'DynamicMembership' and a membership rule
    that restricts membership to users with a userType equal to 'Guest'. This configuration enables
    automated enforcement of conditional access policies and reduces manual management of guest access.
    """

    def execute(self) -> List[CheckReportM365]:
        """
        Execute the dynamic group for guest users check.

        Iterates over the groups retrieved from the Microsoft Entra client and generates a report
        indicating whether at least one dynamic group exists with a membership rule targeting guest users.

        Returns:
            List[CheckReportM365]: A list containing a single report with the result of the check.
        """
        findings = []
        if entra_client.groups:
            dynamic_group = None
            for group in entra_client.groups:
                if "DynamicMembership" in group.groupTypes and group.membershipRule:
                    if 'user.userType -eq "Guest"' in group.membershipRule:
                        dynamic_group = group
                        break

            report = CheckReportM365(
                self.metadata(),
                resource=dynamic_group if dynamic_group else {},
                resource_name=dynamic_group.name if dynamic_group else "Group",
                resource_id=dynamic_group.id if dynamic_group else "group",
            )
            report.status = "FAIL"
            report.status_extended = (
                "No dynamic group for guest users was found in Microsoft Entra."
            )

            if dynamic_group:
                report.status = "PASS"
                report.status_extended = (
                    "A dynamic group for guest users is created in Microsoft Entra."
                )

            findings.append(report)
        return findings