Rules/ID-008.no-guests-privileged.psd1

@{
    Id          = 'ID-008'
    Title       = 'No guest accounts hold privileged directory roles'
    Area        = 'RoleAssignments'
    Severity    = 'High'
    References  = @(
        'CIS Microsoft 365 Foundations Benchmark (guest access)'
        'https://learn.microsoft.com/entra/identity/role-based-access-control/best-practices'
    )
    Rationale   = 'A guest with an admin role is privilege your tenant grants but a foreign tenant controls - its credential hygiene, MFA and lifecycle are outside your governance.'
    Remediation = 'Remove admin roles from guest accounts; if external administration is required, use dedicated member accounts in your tenant or cross-tenant access with proper governance.'
    Test        = {
        param($Snapshot)
        $privilegedRoles = @(
            'Global Administrator', 'Privileged Role Administrator', 'Security Administrator',
            'User Administrator', 'Exchange Administrator', 'SharePoint Administrator',
            'Intune Administrator', 'Application Administrator', 'Cloud Application Administrator',
            'Conditional Access Administrator', 'Helpdesk Administrator'
        )
        $hits = @($Snapshot.RoleAssignments.assignments | Where-Object {
                ($privilegedRoles -contains [string]$_._tlRoleName) -and (
                    ([string]$_._tlPrincipalUpn -match '#EXT#') -or
                    ($_.principal -and $_.principal.PSObject.Properties['userType'] -and [string]$_.principal.userType -eq 'Guest')
                )
            })
        if ($hits.Count -gt 0) {
            New-TLRuleResult -Status Fail -Evidence @($hits | ForEach-Object {
                    "{0} ({1}) holds {2}" -f $_._tlPrincipalName, $_._tlPrincipalUpn, $_._tlRoleName
                })
        }
        else {
            New-TLRuleResult -Status Pass -Evidence 'No guest account holds a privileged directory role.'
        }
    }
}