Azure RBAC vs Entra ID Roles vs ABAC: Least Privilege by Design · CloudEngineerHub
Entra ID10 min read6 views
Azure RBAC vs Entra ID Roles vs ABAC: Least Privilege by Design
Two control planes, one least-privilege model: Azure RBAC scopes, Entra ID directory roles, ABAC conditions, and PIM just-in-time elevation — with audit-ready design patterns.
A
Anuradha Kumari
Published: August 22, 2026· Last Updated: September 24, 2026·10 min read
Azure RBAC vs Entra ID Roles vs ABAC: Least Privilege by Design
Microsoft's permission model has two planes that are constantly confused. Azure RBAC controls ARM resources (VMs, storage, networks) across management group → subscription → resource group → resource scopes. Entra ID directory roles (Global Administrator, User Administrator, Helpdesk Administrator) control the directory itself — users, groups, app registrations, licenses. A Global Administrator has zero Azure subscription rights by default, and an Azure subscription Owner has no rights to reset user passwords. Least privilege starts with respecting that boundary.
Visual Walkthrough
A
Anuradha Kumari
Author
Endpoint management specialist focused on Microsoft Intune, Windows Autopilot and modern EUC. Writes practical deployment, compliance and troubleshooting guides for IT teams.
The five-step evaluation every role assignment request passes.
Decision TreeAzure RBAC Evaluation — Union, then Deny5/5
Decision gate
Action attempted
RBAC is additive (union) until a deny assignment appears.
Assignment matched
1
Scope walk
Check assignments from resource upward: RG → subscription → MG.
2
Union of roles
All matching assignments combine — multiple roles add up.
3
PIM elevation
Eligible roles can be activated for just-in-time access.
4
Action allowed
Data/action permission verified against the role definition.
Deny or none
1
Deny assignment check
Deny assignments always win — read them first.
2
No assignment found
Scope walk came up empty; access denied by default.
3
Request elevation
PIM request or assignment via owner — never widen broadly.
4
Least privilege wins
Smallest sufficient scope is the durable answer.
Azure RBAC Evaluation — Union, then Deny. Gate: Action attempted — Assignment matched: Scope walk — Assignment matched: Union of roles — Assignment matched: PIM elevation — Assignment matched: Action allowed — Deny or none: Deny assignment check — Deny or none: No assignment found — Deny or none: Request elevation — Deny or none: Least privilege wins
Prerequisites
Roles to administer — User Access Administrator (Azure plane) and Privileged Role Administrator (Entra plane) to create assignments; Global Administrator with PIM self-elevation for emergency changes.
PIM — Microsoft Entra ID P2 for just-in-time activation, approval workflows, and access reviews.
An inventory — export current role assignments (both planes) before designing; you cannot right-size what you have not counted.
A unit model — who owns which subscriptions and resource groups, because RBAC scope design mirrors org structure whether you like it or not.
How Access Is Evaluated
When a request hits ARM or the directory, the evaluator walks every role assignment (and deny assignment) that applies at the request's scope and above, computes the union of allowed actions, subtracts explicit denies, and — for ABAC-capable roles — evaluates the condition expression against the request and resource attributes. Three practical consequences:
Inheritance is downward only — an assignment at the management group covers everything beneath; nothing propagates upward.
Deny assignments win — created by Azure Blueprints and some platform features, invisible in most portals but binding.
Conditions refine, never widen — an ABAC condition can only restrict the actions its role already grants.
Two Planes, Two Scopes
Assign Azure RBAC roles at the narrowest scope that works, and prefer job-function roles over Owner/Contributor wherever possible:
Bash
1
2
3
4
az role assignment create \
--assignee ops@contoso.com \
--role"Virtual Machine Contributor" \
--scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/rg-web
Scopes inherit downward, which cuts assignment sprawl: one Reader assignment at the management group covers every subscription beneath it. The audit-friendly ladder: Reader for auditors, job-function roles (Virtual Machine Contributor, Storage Blob Data Contributor) for teams, and subscription-level Owner reserved for platform groups activated just-in-time through Privileged Identity Management (PIM) in entra.microsoft.com → Identity Governance. PIM turns standing privilege into eligible privilege — members activate the role for a capped window (8 hours is a sane default), optionally gated by MFA, approval, and a justification that lands in the audit log. Azure RBAC roles support PIM too, so your emergency Cloud Application Administrator and your emergency subscription Contributor follow the same discipline.
When an assignment fails with the classic ARM message — the client does not have authorization to perform action Microsoft.Authorization/roleAssignments/write — you need a role containing that action at a higher scope (typically User Access Administrator), ideally granted temporarily via PIM.
Step-by-Step: Building the Role Ladder
Export both planes: Get-AzRoleAssignment across all subscriptions, plus directory role assignments from entra.microsoft.com → Roles and admins.
Map every assignment to a human team and a justification; classify as keep, narrow, or remove.
Replace Owner/Contributor standing assignments with job-function roles at resource-group scope.
Convert remaining privileged roles to PIM-eligible — no standing Owner, Contributor, or User Access Administrator assignments for humans.
Create role-assignment groups (one group per role-scope pair) so access reviews have a target and membership is delegated to the owning team.
Schedule quarterly access reviews on every privileged group; auto-remove members who do not attest.
Configuration Deep Dive: ABAC and Custom Roles
ABAC conditions layer attribute logic onto role assignments; they are generally available for the Storage blob data roles. Conditions evaluate request, resource, and principal attributes — for example, restricting a Storage Blob Data Reader assignment to a single container:
Bash
1
2
3
4
5
6
az role assignment create \
--assignee etl@contoso.com \
--role"Storage Blob Data Reader" \
--scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/rg-data/providers/Microsoft.Storage/storageAccounts/stprod \
--condition"((!(ActionMatches{'Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read'})) OR (@Resource[Microsoft.Storage/storageAccounts/blobServices/containers:containerName] StringEqualsIgnoreCase 'logs-export'))" \
--condition-version"2.2"
One conditioned assignment replaces dozens of per-container grants. The portal's Add condition editor (role assignment → Conditions) builds these expressions visually and shows the JSON behind them, so you can paste the result straight into Terraform or CLI pipelines. Principal-attribute conditions using custom security attributes let you gate access by department — powerful, but keep conditions in source control and test them, because a malformed condition silently denies everything it touches.
Custom roles are the other lever: clone the closest built-in (Get-AzRoleDefinition), trim NotActions, and keep the delta documented — custom roles that drift from their built-in cousins become unmaintainable debt.
PowerShell
1
2
3
4
5
6
7
8
9
# Inspect a built-in role's effective actions before cloning it as a custom role$role = Get-AzRoleDefinition "Storage Blob Data Contributor"$role.Actions
$role.NotActions
# Expected output: the action list (dataPlane blobs read/write/delete) and the exclusions# Grant time-bound access at resource-group scope (PIM-lite for automation identities)
New-AzRoleAssignment -ObjectId (Get-AzADServicePrincipal -DisplayName app-deploy).Id -RoleDefinitionName"Website Contributor" -ResourceGroupName rg-web
# Expected output: RoleAssignmentName/Id echoed with RoleDefinitionName : Website Contributor
Real-World Enterprise Scenario
A 12-subscription media company audited for SOC 2 and found 411 standing role assignments — 63 of them Owner. The redesign took one quarter: Owners became PIM-eligible with 4-hour activations and approval; "the contractor group" became three job-function groups at resource-group scope; auditors got a single management-group Reader assignment instead of subscription scatter. The finding that hurt most: a vendor's Contributor assignment on the wrong subscription, live for two years, discovered only because the export finally forced someone to read the list. Quarterly access reviews now auto-expire unattested memberships, and the standing-privileged count sits at eleven service-principal assignments with justified documentation.
Troubleshooting
Symptom
Likely Cause
Fix
"Authorization to perform Microsoft.Authorization/roleAssignments/write"
Assigner lacks a role with that action at or above the target scope
Activate User Access Administrator via PIM at the right scope
User sees resources but cannot act
Reader at a high scope shadows the intent; action role missing below
Add the job-function role at the resource-group scope
ABAC condition denies everything
Malformed condition expression or wrong attribute casing
Recreate via the portal condition editor; test with a single blob read
PIM activation button missing
User not eligible (only assigned) or PIM not licensed
Set the role to eligible in PIM; verify Entra ID P2 assignment
Deny assignment blocks a valid operation
Blueprint or platform-created deny assignment at a parent scope
Identify via ARM/deny-assignment listing; rework scope or request exemption from owners
Key Vault data-plane access fails with RBAC enabled
Vault switched to RBAC authorization; access policies ignored
AuthorizationFailed on roleAssignments/write — the single most common RBAC failure; scope and role discipline beats trial and error.
Assignment targets a deleted identity — orphaned assignments show GUIDs; clean them during quarterly reviews.
Condition silently evaluated as false — attribute names are case-sensitive and namespace-prefixed; one typo denies all matching actions.
PIM approval stuck — approvers are a group with no active members; make approver groups self-reviewing too.
Vault access policy written to an RBAC vault — the two authorization models are mutually exclusive; pick RBAC and stay there.
Visual Walkthrough
Resource plane vs identity plane: never confuse the two control towers.
Side-by-SideAzure RBAC vs Entra ID Roles — Scope of Power6/6
Azure RBAC
resource plane
Entra ID Roles
identity plane
Governs Azure resources (VMs, VNets, storage)
Governs directory objects (users, devices, apps)
Scopes: MG → subscription → RG → resource
Tenant-wide or administrative-unit scoped
Assignable to users/groups/SPNs/MSIs
Global Admin is NOT Azure resource access
Actions on data plane defined per role
PIM-eligible for just-in-time use
Evaluated with deny assignments + PIM
Separate audits, separate blast radius
Azure RBAC vs Entra ID Roles — Scope of Power. Azure RBAC vs Entra ID Roles. Azure RBAC: Governs Azure resources (VMs, VNets, storage) · Entra ID Roles: Governs directory objects (users, devices, apps) — Azure RBAC: Scopes: MG → subscription → RG → resource · Entra ID Roles: Tenant-wide or administrative-unit scoped — Azure RBAC: Assignable to users/groups/SPNs/MSIs · Entra ID Roles: Global Admin is NOT Azure resource access — Azure RBAC: Actions on data plane defined per role · Entra ID Roles: PIM-eligible for just-in-time use — Azure RBAC: Evaluated with deny assignments + PIM · Entra ID Roles: Separate audits, separate blast radius
Best Practices
Assign at the narrowest scope that works: resource group beats subscription; job-function roles beat Owner.
Use PIM for just-in-time activation of privileged roles instead of standing assignments — for both planes.
Group-based assignments only; individual users churn, groups do not.
Cap activations at 4–8 hours and require justification; long windows recreate standing privilege.
Review role churn weekly via Activity Log queries and run quarterly access reviews on privileged groups.
Security Considerations
Tier-0 discipline: roles that can edit role assignments (Owner, User Access Administrator) are effectively Global Administrator equivalents — gate them hardest.
Global Administrator emergency access belongs to break-glass accounts, never to daily identities.
Stream role changes to a SIEM; a standing assignment created at 3 a.m. is either an incident or a paperwork failure.
Custom security attributes used in ABAC conditions are themselves sensitive — only Privileged Role Administrators should manage them.
Watch the legacy surface: classic subscription admins and vault access policies survive in old tenants and bypass your RBAC design.
FAQ
Can a Global Administrator manage Azure subscriptions?
Yes, but only by elevating: Global Admins can self-assign User Access Administrator at the root scope via a directory switch. It is an emergency hatch, not a standing right.
Does ABAC work for roles other than Storage?
The condition feature is generally available for the Storage blob data roles; other services have conditions in preview at various times. Check the current role list before designing around it.
PIM-eligible or group-based standing?
PIM-eligible for anything that can create role assignments or touch security policy; group-based standing is acceptable for clearly job-scoped, non-privileged access.
How do I audit who activated a PIM role?
Entra ID audit logs record activation events with justification; Azure plane activations also appear against the assignment. Export both to your SIEM.
Are deny assignments visible in the portal?
Not in most blades — they are ARM-level objects. List them programmatically when a mysterious block persists across clean RBAC data.
Conclusion
Least privilege in Microsoft's stack is two disciplines: respect the boundary between the resource plane and the directory plane, and convert standing privilege into just-in-time privilege everywhere humans are involved. Do that, add ABAC conditions where role sprawl starts, and the permission model becomes auditable instead of legendary.
Comments
0No comments yet — be the first to share your thoughts.