Azure RBAC — scopes, roles and role assignments
How Azure decides whether a principal may act on a resource — the scope hierarchy (management group, subscription, resource group, resource) and scope strings, role definitions (Actions vs DataActions), the built-in roles agents meet and their stable IDs, role assignments (principalId, principalType, deterministic names), conditions to constrain who can assign what, deny assignments, propagation delays and the documented limits.
markdownreferencev1G9BC-ENWQstage: referencetrust: officialservice: rbacinterface: anyAzure RBACrole assignmentscope stringmanagement group scopesubscription scoperesource group scoperole definitionActions NotActions DataActions NotDataActionscontrol plane vs data planeOwnerContributorReaderUser Access AdministratorRole Based Access Control Administratorrole definition IDprincipalType ServicePrincipalrole assignment name guidABAC condition role assignment delegationdeny assignmentdeployment stack deny settingsrole assignment propagation 10 minutescustom roles 5000 per tenantRoleAssignmentLimitExceeded
Access is a role assignment: a principal (user, group, service principal or managed identity), a role definition, and a scope. An assignment applies at its scope and everything below it. Azure allows the call if any assignment grants the action and no deny assignment blocks it. Azure Policy is a separate check that can still refuse the request (reference/policy/effects-and-errors.md).
Scopes
/providers/Microsoft.Management/managementGroups/{mg}
/subscriptions/{subscriptionId}
/subscriptions/{subscriptionId}/resourceGroups/{rg}
/subscriptions/{subscriptionId}/resourceGroups/{rg}/providers/{namespace}/{type}/{name}
Child resources append /{subtype}/{name} pairs. Get a resource's exact scope from its id (az keyvault show --name kv --query id -o tsv) rather than building the string by hand. Management groups sit above subscriptions; the tenant root group is the top.
Role definitions: control plane vs data plane
A role lists Actions / NotActions (Resource Manager operations: create, configure, delete) and DataActions / NotDataActions (operations on the data inside: read a blob, get a secret, send a message). Owner and Contributor have no data actions, so they manage a storage account or key vault but can't read its contents through Entra auth. Data access needs the service's data role, such as Storage Blob Data Reader or Key Vault Secrets User.
| Built-in role | What it allows | Role definition ID |
|---|---|---|
| Owner | Everything, including assigning roles | 8e3af657-a8ff-443c-a75c-2fe8c4bcb635 |
| Contributor | Manage all resources; not assign roles or write policy (NotActions include Microsoft.Authorization/*/Write and /*/Delete) | b24988ac-6180-42a0-ab88-20f7382dd24c |
| Reader | View everything, change nothing | acdd72a7-3385-48ef-bd42-f606fba81ae7 |
| Role Based Access Control Administrator | Create and delete role assignments (not policy) | f58310d9-a9f6-439a-9e8d-f62e7b41a168 |
| User Access Administrator | Manage user access to Azure resources | 18d7d88d-d35e-4fb5-a5c3-7773c20a72d9 |
| Managed Identity Contributor / Operator | Create and manage user-assigned identities / assign them to resources | e40ec5ca-96e0-45a2-b4ff-59039f2c2b59 / f1a07417-d97a-45cb-824c-7a7467783830 |
| Key Vault Secrets User | Read secret contents (RBAC-model vaults) | 4633458b-17de-408a-b874-0445c86b69e6 |
The IDs are the same in every tenant. Infrastructure-as-code should reference them, not role names. Each service family in this hub lists its own data roles.
Role assignments
- Name: every assignment is a resource whose
nameis a GUID that must be unique globally, not just in your subscription. Its properties can't change after creation. In Bicep or ARM, derive it:guid(scope, principalId, roleDefinitionId). A random or reused name givesRoleAssignmentUpdateNotPermittedwhen the principal changes (reference/rbac/errors.md). principalIdis the object ID (a managed identity'sprincipalId, a service principal'sid), never the app's client ID.principalType(User,Group,ServicePrincipal; the 2022-04-01 spec now also listsAgentServicePrincipalandAgentUserfor Entra Agent ID,reference/entra/workload-and-agent-identities.md): set it whenever the principal was just created. It skips the directory lookup that fails withPrincipalNotFoundduring replication.- Propagation: changes take up to about 10 minutes. Sign out and in (CLI) or get a new token (code) to pick them up sooner. Group-based access for managed identities can take hours (
reference/managed-identity/errors.md). - Resource moves don't move assignments made directly on the resource; re-create them after the move. Transferring a subscription to another tenant deletes all its role assignments.
Who can assign roles, and constraining them
Creating an assignment needs Microsoft.Authorization/roleAssignments/write at that scope: Owner, User Access Administrator or Role Based Access Control Administrator. Prefer Role Based Access Control Administrator with a condition, which limits the roles a delegate can assign (and to which principals). Conditions use role definition IDs:
((!(ActionMatches{'Microsoft.Authorization/roleAssignments/write'}))
OR (@Request[Microsoft.Authorization/roleAssignments:RoleDefinitionId] ForAnyOfAnyValues:GuidEquals {4633458b-17de-408a-b874-0445c86b69e6}))
A pipeline identity that deploys role assignments is the typical delegate: give it this role with a condition naming only the data roles it deploys.
Deny assignments
A deny assignment blocks actions even when a role allows them. Generally available ones are created by Azure, for example by a deployment stack with deny settings or a managed application. Customer-managed deny assignments are in private preview. List them with az rest --method get --uri "https://management.azure.com/<scope>/providers/Microsoft.Authorization/denyAssignments?api-version=2022-04-01".
Documented limits
Custom roles: 5,000 per tenant. A custom role's AssignableScopes can hold at most one management group, and a custom role with DataActions can't be assignable at management-group scope. The per-subscription role-assignment count has a limit (RoleAssignmentLimitExceeded when reached): read the current figure on the Azure subscription limits page rather than a number copied from elsewhere.
Next
Assigning roles from CLI, Bicep and TypeScript: guides/rbac/assign-roles.md. Errors: reference/rbac/errors.md.