Home / Azure

AzureHow-toBeginner

Azure RBAC basics: roles, scopes and your first role assignment

Learn how Azure RBAC decides who can do what. Understand principals, roles and scopes, grant access with the CLI, check what someone really has and remove access when it's no longer needed.

Deepak Bhardwaj5 min read

Applies toAzure RBAC, Azure CLI 2.x, Microsoft Entra ID

The goal

A teammate needs access to a resource group, or a script fails with AuthorizationFailed. Azure role-based access control (RBAC) answers one question: who can do what, and where? This post shows you how to read and change that safely.

The three parts

Every role assignment joins three things:

Part Question Examples
Security principal Who? User, group, service principal, managed identity
Role What? Reader, Contributor, Storage Blob Data Reader
Scope Where? Management group, subscription, resource group, resource

Scopes are inherited downward. Reader on a subscription gives Reader on every resource group and resource inside it.

Management group
  └─ Subscription
       └─ Resource group
            └─ Resource

The roles you'll use first

Role Can do Can't do
Reader View resources Change anything
Contributor Create, change and delete resources Grant access to others
Owner Everything, including granting access Nothing is held back
User Access Administrator Manage role assignments Manage the resources themselves

Those are control plane roles. They manage the resource, not always the data inside it. A Contributor on a storage account can't necessarily read blobs with Entra ID sign-in. That takes a data role such as Storage Blob Data Reader. Key Vault works the same way, with roles like Key Vault Secrets User.

Step 1: see what you already have

az ad signed-in-user show --query userPrincipalName -o tsv

az role assignment list --assignee "$(az ad signed-in-user show --query id -o tsv)" \
  --all --include-inherited --include-groups \
  --query "[].{role:roleDefinitionName, scope:scope}" -o table

--include-groups matters here, because most access should arrive through group membership.

Step 2: find the right role

Search the built-in roles before you reach for Contributor:

az role definition list --query "[?contains(roleName, 'Virtual Machine')].{name:roleName, description:description}" -o table

See exactly what a role allows:

az role definition list --name "Virtual Machine Contributor" \
  --query "[].permissions[].{actions:actions, notActions:notActions, dataActions:dataActions}" -o json

Step 3: grant access

Use a group rather than a person where you can. Then you add and remove people without touching RBAC again.

GROUP_ID=$(az ad group show --group "app-team-readers" --query id -o tsv)
RG_ID=$(az group show --name rg-app-prod --query id -o tsv)

az role assignment create \
  --assignee-object-id "$GROUP_ID" \
  --assignee-principal-type Group \
  --role "Reader" \
  --scope "$RG_ID"

To grant a data role on one storage account:

STORAGE_ID=$(az storage account show -g rg-app-prod -n stappprod01 --query id -o tsv)

az role assignment create \
  --assignee-object-id "$GROUP_ID" \
  --assignee-principal-type Group \
  --role "Storage Blob Data Reader" \
  --scope "$STORAGE_ID"

Passing --assignee-principal-type also helps avoid a lookup failure right after an identity is created.

Warning

Assign at the smallest scope that works. Owner on a subscription lets someone grant that same power to anyone else. If someone needs it only for a while, consider Privileged Identity Management. See PIM and break-glass accounts.

Step 4: check who has access

List the assignments on a scope, including inherited ones:

az role assignment list --scope "$RG_ID" --include-inherited \
  --query "[].{who:principalName, type:principalType, role:roleDefinitionName, scope:scope}" -o table

If you don't have permission to read Entra ID, principalName may be blank. You can still see principalId.

In the portal, open the resource, then Access control (IAM) and Check access. It shows the combined result for one person, including anything coming through a group.

Step 5: remove access

az role assignment delete \
  --assignee "$GROUP_ID" \
  --role "Reader" \
  --scope "$RG_ID"

Check the list again afterward. If the principal still has access, it's probably coming from a higher scope, or from another group.

Why isn't it working yet?

Symptom Likely cause Fix
Just granted, still AuthorizationFailed Changes can take a few minutes, and tokens are cached Wait, then run az logout and az login
Can see the storage account, can't read blobs No data role Add a Storage Blob Data role
Forbidden when creating an assignment You lack roleAssignments/write Ask an Owner or User Access Administrator
RoleAssignmentExists The same assignment is already there Nothing to do
Removed access, it's still there Inherited from a higher scope or another group List with --include-inherited --include-groups
Owner, but the action is still denied A policy, lock or deny assignment See policy deny and resource locks

RBAC is additive: your effective access is the sum of your assignments. The main exception is a deny assignment, which is created by Azure features rather than by you directly, and it takes priority.

For help with a specific failure, use the AuthorizationFailed cheat sheet.

Find out who changed access

Role assignment changes are recorded in the Activity Log:

az monitor activity-log list \
  --resource-group rg-app-prod \
  --offset 7d \
  --query "[?contains(operationName.value, 'roleAssignments')].{when:eventTimestamp, who:caller, what:operationName.value, status:status.value}" \
  -o table

See who changed or deleted it for more.

Prevent it next time

  • Grant to groups, not individuals.
  • Pick the narrowest role and scope, and avoid Owner except where it's truly needed.
  • For apps, use a managed identity, not a stored secret.
  • Review assignments on production subscriptions every quarter, and remove the ones nobody can explain.