A guest account holding an Entra ID admin role puts your tenant's security in the hands of another organisation's password policy, MFA and leaver process. Entra ID lets you add a guest to any directory role, and guests arrive in privileged roles through routes that a portal search misses: eligible PIM assignments, role-assignable groups, administrative unit scopes, Azure resource roles, and external members whose user type says Member. This runbook finds all of them with Microsoft Graph and Azure CLI read-only calls, then shows how to decide, remove with a rollback, and keep the number at zero. It is for identity and cloud security engineers. For the wider guest lifecycle, see the Entra ID Cross-Tenant Access and B2B Guest Governance Guide and How to Audit Guest and External Users.
This is an independent guide from NHI Mgmt Group, based on Microsoft's public documentation as of November 2026. It is not sponsored or reviewed by Microsoft. APIs and portal paths change, so confirm each call against Microsoft's current documentation.
Key takeaways
- userType alone is not enough. Microsoft says userType describes the relationship to your organisation, not how the user signs in. External members (userType Member, identity
ExternalAzureAD) authenticate in another tenant just like guests. - Check four assignment routes. Active assignments (
/roleManagement/directory/roleAssignments), eligible PIM assignments (/roleEligibilityScheduleInstances), membership of role-assignable groups, and assignments scoped to administrative units. - Azure roles are a separate system. A guest who is Owner or User Access Administrator on a subscription never appears in an Entra role report; list Azure role assignments with
az role assignment list --all. - Move rather than delete. Most privileged guests are contractors or partner staff doing real work. Give them a member account in your tenant with your MFA and PIM controls, or narrow the role, then remove the guest assignment.
- Keep it at zero with a review and an alert. A recurring PIM access review of privileged roles removes denied guests automatically, and an audit log alert catches new ones on the day.
When you need this
- Audit or certification: privileged access reviews under ISO/IEC 27001, SOC 2 or NIST SP 800-53 AC-6(7) expect you to know every privileged external account.
- After a partner or MSP incident: a guest's home tenant controls its authentication. If that tenant is breached, the guest's role in yours is exposed. If your provider administers your tenant, see the Compromised MSP Playbook.
- After a merger, divestiture or cross-tenant synchronisation rollout: large numbers of external accounts appear at once, some as members.
- When guests were given "same as member" access: the tenant setting for guest permissions changes what any guest can read, and makes role assignment to guests more likely to go unnoticed.
Before you start
| Permission or tool | Used for | Notes |
|---|---|---|
RoleManagement.Read.Directory | Active role assignments | Least privileged Graph permission; delegated callers also need Directory Readers, Global Reader or Privileged Role Administrator |
RoleEligibilitySchedule.Read.Directory | Eligible PIM assignments | Delegated callers need Global Reader, Security Reader, Security Operator, Security Administrator or Privileged Role Administrator |
User.Read.All, GroupMember.Read.All | User type, identities, invitation state; group members | Read-only |
| Azure CLI with Reader on the management group root | Azure resource role assignments | Without root scope you only see subscriptions you can read |
| Privileged Role Administrator (eligible) | Change steps only | Also needed to create access reviews of Entra roles |
How to recognise an external account
| Signal | Example value | What it tells you |
|---|---|---|
userType | Guest | Invited as a guest; the most common case |
userPrincipalName | john_contoso.com#EXT#@fabrikam.onmicrosoft.com | B2B object; the original email with @ replaced by an underscore |
identities issuer | ExternalAzureAD, MicrosoftAccount, mail, google.com | Authenticates outside your tenant, whatever the userType says |
externalUserState | PendingAcceptance | Invitation not redeemed; a privileged role on an unredeemed invitation can be claimed by whoever redeems it |
userType Member with an external identity | Cross-tenant synchronisation or a converted guest | External member: the case a Guest filter misses |
Microsoft's own advice is to use these signals together rather than rely on userType.
Step-by-step
1. Build the list of external accounts
GET https://graph.microsoft.com/v1.0/users?$filter=userType eq 'Guest'&$select=id,displayName,userPrincipalName,userType,identities,externalUserState,createdDateTime,accountEnabled
Then pull all users with identities selected and keep, client side, any whose identity issuer is not your own domain. Identity filtering is awkward in $filter, so doing this in the script is simpler. The union of both lists is your external set, keyed by object ID.
2. Find active role assignments held by external accounts
List all directory role assignments with the principal expanded:
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?$expand=principal
In PowerShell the cmdlet is Get-MgRoleManagementDirectoryRoleAssignment with -All and -ExpandProperty principal. For each row keep principalId, roleDefinitionId and directoryScopeId, and match principalId against the external set. The expanded principal includes userType for users, which catches guests directly; external members are caught by the match against step 1. A directoryScopeId of / means tenant-wide; /administrativeUnits/{id} means the role applies only inside that administrative unit, which still matters for roles such as User Administrator or Helpdesk Administrator.
To work through the most sensitive roles first, filter by role template ID, for example Global Administrator:
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleAssignments?$filter=roleDefinitionId eq '62e90394-69f5-4237-9190-012177145e10'&$expand=principal
3. Find eligible PIM assignments
A guest who is only eligible holds no role today but can activate one. List eligibility instances:
GET https://graph.microsoft.com/v1.0/roleManagement/directory/roleEligibilityScheduleInstances
Match principalId against the external set and record roleDefinitionId, directoryScopeId, memberType, startDateTime and endDateTime. An eligibility with no end date is permanent eligibility. See the Privileged Identity Management (PIM) Guide.
4. Expand role-assignable groups
When the principal in steps 2 or 3 is a group, list its members with GET /groups/{id}/members and match them against the external set. Role-assignable groups (isAssignableToRole true) cannot contain other groups, so one level is enough for them. Record the group's owners too: Microsoft notes that owners can manage membership, so an external owner of a role-assignable group can add anyone, including themselves, to the role. Check PIM for Groups eligibility on these groups as well, since membership itself can be eligible.
5. Check Azure resource roles
az role assignment list --all --include-inherited --output json
Run it per subscription, or with --scope /providers/Microsoft.Management/managementGroups/<id> at the root management group, and match the principal IDs against the external set. Prioritise Owner, User Access Administrator, Contributor and Key Vault data roles. A guest with User Access Administrator on a subscription can grant itself anything in that subscription.
6. Score and decide
| Finding | Risk | Recommended action (ours) |
|---|---|---|
| External account in Global Administrator, Privileged Role Administrator or Privileged Authentication Administrator | Tenant takeover if the home account is compromised | Remove. Issue a member account in your tenant under your phishing-resistant MFA and PIM if the person still needs the role |
| External account in another privileged role tenant-wide (for example User Administrator, Application Administrator, Exchange Administrator, Security Administrator) | Escalation paths and data access | Narrow to the least role, scope to an administrative unit, make it eligible with approval and a time limit, or replace with a member account |
Privileged role on an invitation still PendingAcceptance | Whoever redeems the invitation gets the role | Remove the assignment immediately; re-invite only after confirming the recipient |
| Guest owns a role-assignable group | Can add any member to the role | Remove ownership; owners of these groups should be Tier 0 member accounts |
| Guest from a managed service provider using GDAP or a partner relationship | Partner relationships give admin rights without a guest object | Review those separately in the partner relationships view; this runbook does not cover them |
| Guest with Azure Owner or User Access Administrator | Full control of resources and access in that scope | Reduce to a specific role on the specific resource group, or move to a member account |
7. Remove with a rollback
- Export the full assignment record (role, scope, eligibility or active, start and end dates, group route) for each finding. This is your rollback data.
- Agree the change with the account's sponsor; the B2B
Sponsorattribute records the inviter when it is populated. - Remove active assignments with
DELETE /roleManagement/directory/roleAssignments/{id}, eligibility through PIM (an admin remove request on the eligibility schedule), and group membership withDELETE /groups/{id}/members/{memberId}/$ref. - Remove Azure role assignments with
az role assignment delete, giving the assignee, role and scope from your export. - Rollback is re-creating the assignment from the export. Make any restored assignment eligible, time-bound and approval-gated rather than permanent and active.
8. Keep it at zero
- Access review: in Privileged Identity Management, under Microsoft Entra roles, Access reviews, create a recurring review of privileged roles covering active and eligible assignments, with Auto apply results to resource enabled. Microsoft states that denied guest users always lose access in Entra and Azure role reviews. This needs Microsoft Entra ID P2 or ID Governance and the Privileged Role Administrator role.
- Alert: in
AuditLogs, alert on role assignment operations (for exampleAdd member to roleand PIM eligibility additions) where the target user's UPN contains#EXT#or appears in the external set. - Guest permission level: read
guestUserRoleIdfromGET /beta/policies/authorizationPolicy/authorizationPolicy.a0b1b346-4d3e-4e8b-98f8-753987be4970means same as member users;10dae51f-b6af-4016-8d66-8c2a99b929b3is the default limited access;2af84b1e-32c8-42b7-82bc-daa82404023bis restricted access. - Policy: write down that privileged roles are not assigned to external accounts, with a named exception process. See the Access Reviews Guide.
Small tenant or large organisation
- Small tenant (one subscription, a handful of admins): the portal is enough for a first pass. In the Entra admin center open Roles and administrators, check each privileged role's assignments on both the eligible and active tabs, and compare names with the guest list under Users filtered by user type. Run the Graph calls once a quarter to catch administrative unit scopes and external members, which the role pages do not label.
- Large tenant (hundreds of roles and subscriptions, cross-tenant synchronisation): script steps 1 to 5 under an application with read-only permissions, write the joined result to your log workspace, and run it daily. Join it to sign-in data so each finding carries the account's last sign-in; a privileged external account that has not signed in for 90 days is an easy removal.
- Multi-tenant organisations: where sister tenants synchronise users as external members, agree a rule across tenants that privileged roles are held only by accounts homed in the tenant they administer. Cross-tenant access settings can require MFA and compliant devices from the home tenant, but that trust is still inherited, not owned. See the Conditional Access Guide for policies that target guest and external user types.
Detecting new privileged guests
A query against AuditLogs in Log Analytics catches active role additions where the target is a B2B object:
AuditLogs
| where TimeGenerated > ago(1d)
| where Category == "RoleManagement"
| where OperationName has "member to role"
| mv-expand Target = TargetResources
| where tostring(Target.userPrincipalName) contains "#EXT#"
| project TimeGenerated, OperationName,
Actor = tostring(InitiatedBy.user.userPrincipalName),
Target = tostring(Target.userPrincipalName), Result
The #EXT# test misses external members, so join the target object ID against the external set from step 1 as well. Treat a privileged role granted to an external account outside a change window as a possible persistence step (ATT&CK T1098.003 Additional Cloud Roles) and confirm with the actor before closing.
Verify it worked
- Re-running steps 2 to 5 returns no external principals in privileged roles, or only documented exceptions.
- Each exception is eligible rather than active, time-limited, and appears in the next access review.
- The audit alert fires when you add a test guest to a low-risk role in a test tenant or administrative unit.
- Replacement member accounts can activate their roles through PIM and the work owners confirm nothing broke.
Common failure patterns
- Filtering on userType eq 'Guest' only. External members from cross-tenant synchronisation or converted guests hold roles and pass the filter.
- Reading only active assignments. Eligible guests, and guests in role-assignable groups, do not show as role holders until they activate.
- Ignoring Azure RBAC. The guest who has no Entra role but owns the production subscription is the bigger risk.
- Permanent "temporary" access. A partner engineer given Global Administrator for a migration is still there two years later, because nobody owns the guest.
- Deleting without a replacement. The work was real, so the role is re-added the next week with no controls. Offer the member account route first.
Metrics and mapping
| Metric | Target |
|---|---|
| External accounts with active Entra privileged roles | Zero, or documented exceptions only |
| External accounts with eligible Entra privileged roles | Falling; all time-limited |
| External owners or members of role-assignable groups | Zero |
| External accounts with Owner or User Access Administrator on Azure scopes | Zero |
| Privileged assignments on unredeemed invitations | Zero |
| Days from a new external privileged assignment to alert triage | Under one |
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev 5 | AC-2(7) Privileged User Accounts; AC-6(5) Privileged Accounts; AC-6(7) Review of User Privileges; AC-3(7) Role-based Access Control | Restrict and review privileged roles, including those held by external users |
| NIST CSF 2.0 | PR.AA-05; DE.CM-03 | Review permissions; monitor account activity |
| MITRE ATT&CK | T1199 Trusted Relationship; T1078.004 Cloud Accounts; T1098.003 Additional Cloud Roles | Partner access as an entry route; abuse of cloud accounts; roles added for persistence |
| CIS Controls v8.1 | 5.4 Restrict Administrator Privileges to Dedicated Administrator Accounts; 6.8 Define and Maintain Role-Based Access Control | Admin rights only on dedicated, governed accounts |
Practitioner checklist
- Build the external set from userType, identities and the #EXT# UPN pattern.
- Match it against active role assignments, including administrative unit scopes.
- Match it against eligible PIM assignments and record end dates.
- Expand members and owners of role-assignable groups.
- List Azure role assignments from the root management group.
- Remove privileged roles on unredeemed invitations at once.
- Export every assignment before removal so it can be restored.
- Offer member accounts under your MFA and PIM controls where the work is real.
- Run a recurring PIM access review with auto apply enabled.
- Alert on any role assignment to an external account.
Standards and references
- Microsoft Graph: List unifiedRoleAssignments
- Microsoft Graph: List roleEligibilityScheduleInstances
- Microsoft Learn: Properties of a Microsoft Entra B2B collaboration user
- Microsoft Learn: Use Microsoft Entra groups to manage role assignments
- Microsoft Learn: Create an access review of Azure resource and Microsoft Entra roles in PIM
- Microsoft Learn: List Azure role assignments using Azure CLI
- Microsoft Learn: Restrict guest access permissions in Microsoft Entra ID
- MITRE ATT&CK: T1199 Trusted Relationship
Related NHI Mgmt Group resources: Entra ID Cross-Tenant Access and B2B Guest Governance Guide · How to Audit Guest and External Users · Privileged Identity Management (PIM) Guide · How to Audit the entra connect sync account