Skip to main content
Azure · lesson 2 of 10
Azure beginner Lesson 2 of 10

Also part of: Cloud Security

Entra ID: Users, Roles, and RBAC

Create a role assignment scoped too narrowly, hit a real authorization error, then fix the scope and watch the same command succeed.

By SkillByExample · Updated

azure entra-id rbac identity

Azure RBAC (role-based access control) grants a principal (a user, group, or service principal) a role (a named bundle of permissions) at a scope (subscription, resource group, or single resource). Get the scope wrong and you get a real, specific authorization error — the example below deliberately triggers one.

Listing who exists and what roles are available

az ad user list --query "[].{Name:displayName, UPN:userPrincipalName}" --output table
$ az ad user list --query "[].{Name:displayName, UPN:userPrincipalName}" --output table
Name          UPN
------------  --------------------------------------
Reader User   reader@readerdemo.onmicrosoft.com
Ana Ferreira  ana.ferreira@readerdemo.onmicrosoft.com
az role definition list --name "Reader" --output table
$ az role definition list --name "Reader" --output table
DefaultParams    Name                                  RoleName    RoleType
---------------  ------------------------------------  ----------  ------------
                 acdd72a7-3385-48ef-bd42-f606fba81ae7   Reader      BuiltInRole

Reader grants read-only visibility across whatever it’s scoped to — no ability to create, modify, or delete. It’s the safest role to practice assignments with because a mistake can’t break anything.

Creating a role assignment scoped to the wrong resource group

ana.ferreira needs read access to learn-rg, created in the previous lesson. Suppose the assignment is written against a resource group that doesn’t exist yet — a typo that’s easy to make when resource groups are named freehand:

az role assignment create \
  --assignee "ana.ferreira@readerdemo.onmicrosoft.com" \
  --role "Reader" \
  --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg-prod"
$ az role assignment create --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --role "Reader" --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg-prod"
ERROR: (ParentResourceNotFound) Can not perform requested operation on nested resource. Parent
resource 'learn-rg-prod' not found.
Code: ParentResourceNotFound
Message: Can not perform requested operation on nested resource. Parent resource 'learn-rg-prod'
not found.

The command fails before it even reaches the authorization check — Azure validates that the scope resource exists first. This is the error a typo in a resource-group name produces; the fix is the resource-group name, not the role or the assignee.

Fixing the scope and creating the assignment

az role assignment create \
  --assignee "ana.ferreira@readerdemo.onmicrosoft.com" \
  --role "Reader" \
  --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg"
$ az role assignment create --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --role "Reader" --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg"
{
  "condition": null,
  "conditionVersion": null,
  "description": null,
  "id": "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg/providers/Microsoft.Authorization/roleAssignments/e8f2b1a4-9c3d-4e17-8b5f-1a6d2c9e7f40",
  "name": "e8f2b1a4-9c3d-4e17-8b5f-1a6d2c9e7f40",
  "principalId": "7c4d9e2a-1f8b-4a6c-9d3e-5b0a8f7c2d61",
  "principalName": "ana.ferreira@readerdemo.onmicrosoft.com",
  "principalType": "User",
  "resourceGroup": "learn-rg",
  "roleDefinitionId": "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",
  "roleDefinitionName": "Reader",
  "scope": "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg"
}

Same role, same assignee — only the scope changed, from a resource group that doesn’t exist to one that does. principalType: User confirms the assignee resolved to an actual Entra ID object rather than being accepted as free text.

Confirming the assignment and testing the boundary

az role assignment list --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --output table
$ az role assignment list --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --output table
Principal                                RoleAssignmentName                    Scope
---------------------------------------  ------------------------------------  --------------------------------------------------------------------------------
ana.ferreira@readerdemo.onmicrosoft.com  e8f2b1a4-9c3d-4e17-8b5f-1a6d2c9e7f40  /subscriptions/3b1f9c2a.../resourceGroups/learn-rg

Now Ana can read learn-rg but nothing outside it. If she runs a command against a different resource group she has no assignment on, she gets a permissions error of her own — AuthorizationFailed — which is the flip side of the scope mistake fixed above: that one failed because the scope target didn’t exist; this one fails because the scope target exists but she isn’t granted on it.

Practice

1. List every role assignment on the learn-rg resource group, not filtered by assignee.
az role assignment list --resource-group learn-rg --output table
$ az role assignment list --resource-group learn-rg --output table
Principal                                RoleAssignmentName                    RoleDefinitionName    Scope
---------------------------------------  ------------------------------------  --------------------  --------------------------------------------------------------------------------
ana.ferreira@readerdemo.onmicrosoft.com  e8f2b1a4-9c3d-4e17-8b5f-1a6d2c9e7f40  Reader                /subscriptions/3b1f9c2a.../resourceGroups/learn-rg

--resource-group filters by scope rather than by principal — the query to run before granting a new assignment, so you can see what access already exists.

2. Try assigning a role using a display name instead of a user principal name and observe what happens.
az role assignment create --assignee "Ana Ferreira" --role "Reader" --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg"
$ az role assignment create --assignee "Ana Ferreira" --role "Reader" --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg"
ERROR: Cannot find user or service principal in graph database for 'Ana Ferreira'.

--assignee needs a user principal name, object ID, or application ID — not a display name. Display names aren’t guaranteed unique across a tenant, so the CLI refuses to guess.

3. Grant Ana Contributor instead of Reader, scoped only to one storage account rather than the whole resource group.
az role assignment create \
  --assignee "ana.ferreira@readerdemo.onmicrosoft.com" \
  --role "Contributor" \
  --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg/providers/Microsoft.Storage/storageAccounts/learnstorage482"
$ az role assignment create --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --role "Contributor" --scope "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg/providers/Microsoft.Storage/storageAccounts/learnstorage482"
{
  "principalName": "ana.ferreira@readerdemo.onmicrosoft.com",
  "roleDefinitionName": "Contributor",
  "scope": "/subscriptions/3b1f9c2a-6d4e-4a7b-9c11-2f5e8a0b7d33/resourceGroups/learn-rg/providers/Microsoft.Storage/storageAccounts/learnstorage482"
}

Same assignee now has two assignments at two different scopes: Reader on the whole resource group, Contributor on one storage account inside it. RBAC is additive — Azure evaluates the union of every assignment that covers the resource being accessed.

4. Remove the resource-group-level Reader assignment and confirm it's gone.
az role assignment delete --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --role "Reader" --resource-group learn-rg
az role assignment list --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --output table
$ az role assignment delete --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --role "Reader" --resource-group learn-rg
$ az role assignment list --assignee "ana.ferreira@readerdemo.onmicrosoft.com" --output table
Principal                                RoleAssignmentName                    RoleDefinitionName    Scope
---------------------------------------  ------------------------------------  --------------------  --------------------------------------------------------------------------------
ana.ferreira@readerdemo.onmicrosoft.com  f3a7c8e1-2b6d-4e94-8a1c-9f5d0b3e6c72  Contributor           /subscriptions/3b1f9c2a.../storageAccounts/learnstorage482

az role assignment delete prints nothing on success. Only the narrower Contributor assignment on the storage account remains.

5. List Entra ID directory roles (not Azure RBAC roles) held by your own account.
az rest --method get --url "https://graph.microsoft.com/v1.0/me/memberOf" --query "value[].displayName"
$ az rest --method get --url "https://graph.microsoft.com/v1.0/me/memberOf" --query "value[].displayName"
[
  "Global Administrator"
]

This hits Microsoft Graph directly via az rest, because directory roles live in Entra ID, not in the Azure Resource Manager API that az role assignment talks to — two separate permission systems queried through two separate endpoints.

Next: Virtual Machines — creating one, opening a port with a network security group, and connecting over SSH.

Frequently Asked Questions

What is Entra ID and how does it relate to Azure AD?
Entra ID is the current name for what was Azure Active Directory — Microsoft renamed the product in 2023, but the underlying service, its APIs, and its object model (users, groups, service principals, app registrations) are unchanged. Documentation and CLI output from before the rename still say 'Azure AD' in places.
What is the difference between an Entra ID role and an Azure RBAC role?
Entra ID roles (like Global Administrator or User Administrator) control access to identity-management tasks — creating users, resetting passwords, managing the tenant. Azure RBAC roles (like Contributor or Reader) control access to Azure resources — VMs, storage accounts, resource groups. They are separate systems with separate role lists; having one does not grant the other.
What does 'scope' mean in a role assignment?
Scope is the boundary the permission applies to: a management group, a subscription, a resource group, or a single resource, in that order from broadest to narrowest. The same role (say, Contributor) grants very different power depending on whether it's assigned at the subscription or at one resource group inside it — always assign at the narrowest scope that does the job.
Why did my role assignment not take effect immediately?
Azure RBAC changes typically propagate within a few seconds but can take up to a few minutes worldwide, since role assignments are cached at various points in Azure's control plane. If a command still fails with an authorization error right after assigning a role, wait a short interval and retry before assuming the assignment itself is wrong.