Skip to main content
emnode
Compliance High severity MCSB IM-1

Microsoft Defender for Cloud · Subscription / RBAC

Guest accounts with write permissions on Azure resources should be removed

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Guest accounts with write permissions on Azure resources should be removed" check?

Audits Azure role assignments at subscription scope and flags any external (guest) identity that holds a role carrying write permissions, for example Contributor, or a scoped writer role such as Storage Blob Data Contributor. A guest is recognised as a principal provisioned outside your Microsoft Entra tenant, typically with a userType of Guest or a home tenant that differs from yours. It only inspects Azure resource (control plane) RBAC assignments. It does not cover guest accounts holding read-only or owner roles, which are separate recommendations, and it does not examine Entra ID directory roles, app or workload identities, or data accessed through shared keys and SAS tokens.

Why does "Guest accounts with write permissions on Azure resources should be removed" matter?

Guest accounts are invited from outside your organisation and are rarely governed to the same standard as employee identities: they often sit outside your joiner-mover-leaver process, may skip your conditional access and MFA baselines, and keep access long after a project ends. A guest with write permissions can deploy resources, alter configuration, exfiltrate or destroy data, and create persistence that your own offboarding never touches. If the partner organisation is breached, the attacker inherits that standing access into your subscription. The business consequence is an unmonitored path to production owned by a third party you cannot fully audit or revoke through your own HR systems.

How do I fix "Guest accounts with write permissions on Azure resources should be removed"?

  1. List external assignments to confirm scope: in the portal open Subscriptions, then Access control (IAM), then Role assignments and filter Type to 'User' to spot guest principals, or query the recommendation under Defender for Cloud's identity and access recommendations to see every flagged account.
  2. Remove the write role from each guest that should not have it: az role assignment delete --assignee "[email protected]" --role "Contributor" --scope "/subscriptions/<subscription-id>". For guests that genuinely need ongoing access, prefer onboarding them as a member of your tenant and granting the least-privileged role through a privileged-access workflow instead.
  3. Surface recurrence by assigning the audit policy at the management group so any new guest write assignment is flagged: pid=$(az policy definition list --query "[?displayName=='Guest accounts with write permissions on Azure resources should be removed'].name" -o tsv); az policy assignment create --name audit-guest-write --policy "$pid" --scope <management-group-id>. The built-in policy only supports AuditIfNotExists and cannot deny, so it gives you detection, not prevention. For actual prevention, gate any future guest write access behind time-bound, approval-required assignments in Entra Privileged Identity Management so the access expires automatically.

Remediation script · bash

# Remove the highest-impact stale grants first: external/guest identities holding Owner.
SCOPE="/subscriptions/00000000-0000-0000-0000-000000000000"
az role assignment list --scope "$SCOPE" --all --include-inherited \
    --query "[?contains(principalName, '#EXT#') && roleDefinitionName=='Owner'].principalId" -o tsv |
while read -r oid; do
  az role assignment delete --assignee-object-id "$oid" --scope "$SCOPE"
  echo "$oid: external Owner assignment removed"
done

# Find blocked/deprecated (disabled) accounts that still hold a role on this scope.
for oid in $(az role assignment list --scope "$SCOPE" --all \
    --query "[?principalType=='User'].principalId" -o tsv | sort -u); do
  enabled=$(az ad user show --id "$oid" --query accountEnabled -o tsv 2>/dev/null)
  if [ "$enabled" = "false" ]; then
    echo "$oid is disabled in Entra but still holds a role - remove its assignment"
  fi
done

# Keep it shut: assign the built-in deprecated-owner policy by its exact display name
# (look the id up at runtime - never hardcode a policy GUID).
pid=$(az policy definition list \
  --query "[?displayName=='Deprecated accounts with owner permissions should be removed from your subscription'].name" -o tsv)
az policy assignment create \
  --name audit-deprecated-owners \
  --policy "$pid" \
  --scope "$SCOPE"

Full walkthrough (console steps, edge cases and verification) in the lesson Remove stale and external Azure identities.

Is "Guest accounts with write permissions on Azure resources should be removed" a false positive?

A guest that is a managed external collaborator on a tightly scoped resource group, granted a least-privileged write role through Privileged Identity Management with a defined expiry and conditional access, can still be flagged because the policy audits the assignment, not your intent. Document the business justification and the review date, and treat the finding as confirmation that the access is visible and governed rather than as something to silence.