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"?
- 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.
- 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.
- 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.
More Subscription / RBAC controls
- Azure overprovisioned identities should have only the necessary permissions
- Blocked accounts with owner permissions on Azure resources should be removed
- Blocked accounts with read and write permissions on Azure resources should be removed
- Deprecated accounts with owner permissions should be removed from subscriptions
- External accounts with read permissions should be removed from subscriptions
- External accounts with write permissions should be removed from subscriptions
- Guest accounts with owner permissions on Azure resources should be removed
- Guest accounts with read permissions on Azure resources should be removed
- Permissions of inactive identities in your Azure subscription should be revoked
- Privileged roles should not have permanent access at the subscription and resource group level
- Service Principals should not be assigned with administrative roles at the subscription and resource group level
- There should be more than one owner assigned to subscriptions