Azure · 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 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.