This chapter covers Custom RBAC Roles in Azure, a critical topic for the AZ-500 exam where you must demonstrate the ability to design and implement fine-grained access control. Understanding custom roles is essential because built-in roles often provide too much or too little permission, forcing you to create tailored roles. Approximately 15-20% of exam questions touch on RBAC, with custom roles being a common focus. By the end of this chapter, you will understand the structure, creation, assignment, and troubleshooting of custom roles, including the nuances of AssignableScopes, Actions, NotActions, DataActions, and the difference between role definitions and role assignments.
Jump to a section
Think of Azure RBAC like a corporate building with many floors and rooms. Built-in roles are like standard badges: 'Visitor' (Reader) lets you enter the lobby only, 'Employee' (Contributor) lets you access your office floor and common areas, and 'Security Guard' (Owner) can open every door and even reprogram the badge system. But what if you need a badge that lets a contractor access only the server room on floor 3 between 9 AM and 5 PM, and only to read temperature logs? That's a custom role. You define exactly which doors (actions) are allowed (e.g., 'Microsoft.Compute/virtualMachines/read'), which are denied (e.g., 'Microsoft.Compute/virtualMachines/start/action'), and at what scope (floor, room, or even a specific rack). The badge system (Azure Resource Manager) checks every door access attempt against the badge's permissions. If the badge says 'allow read on floor 3 server room' but the person tries to enter floor 2, the system denies it. The key is that custom roles are built from the same atomic permissions (Actions, NotActions, DataActions, NotDataActions) that built-in roles use, but you compose them exactly as needed. Just as a badge can be assigned to many people, a custom role is assigned to users, groups, or service principals via role assignments at a specific scope.
What Are Custom RBAC Roles?
Custom RBAC roles are user-defined sets of permissions that you create to meet specific access control requirements that built-in roles cannot satisfy. In Azure, every action a user or service principal can perform is governed by role-based access control (RBAC). Built-in roles like Owner, Contributor, and Reader cover common scenarios, but they are often too broad. For example, the Contributor role allows full management of all resources in a scope, but you might want a role that only allows restarting virtual machines and nothing else. Custom roles let you define exactly which actions are allowed and denied.
How Custom Roles Work Internally
A custom role is a JSON document that defines a set of permissions. When a user attempts an action, Azure Resource Manager (ARM) evaluates the effective permissions by checking all role assignments at the relevant scope. The role definition contains:
Name: A friendly name (e.g., "VM Operator").
Description: A description of the role's purpose.
Actions: A list of allowed control plane operations (e.g., Microsoft.Compute/virtualMachines/read).
NotActions: A list of operations excluded from Actions (e.g., Microsoft.Compute/virtualMachines/delete).
DataActions: A list of allowed data plane operations (e.g., Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read).
NotDataActions: Exclusions from DataActions.
AssignableScopes: The scopes (management groups, subscriptions, or resource groups) where the role can be assigned. This prevents the role from being used outside intended scopes.
Azure computes effective permissions as: (Actions - NotActions) + (DataActions - NotDataActions). The subtraction means if an action is allowed in Actions but denied in NotActions, it is denied. For example, if Actions includes Microsoft.Compute/virtualMachines/* and NotActions includes Microsoft.Compute/virtualMachines/delete, the role allows all VM operations except delete.
Key Components, Values, and Defaults
Actions and NotActions: These are strings in the format {Provider}/{ResourceType}/{Action}. Wildcards are allowed: * at the end covers all child resource types and actions. For example, Microsoft.Compute/virtualMachines/* covers all operations on virtual machines. Microsoft.Compute/* covers all compute operations.
DataActions and NotDataActions: Used for data plane permissions, such as reading blobs or writing to a queue. These are crucial for services like Storage, Key Vault, and SQL Database. Without DataActions, a role might allow managing the storage account but not reading the blobs inside.
AssignableScopes: This is an array of scope IDs. A common mistake is leaving this empty or setting it to a scope that is too narrow. If you set AssignableScopes to a single subscription, the role can only be assigned within that subscription. To allow assignment at any scope, you can use a management group or set it to / (root scope), but root scope requires elevated access. The default when creating via portal is the scope of the current context.
Maximum number of custom roles per directory: 5,000 (as of 2025).
Maximum number of role assignments per subscription: 4,000.
Maximum number of actions per role: 1,024 actions (including wildcard expansions).
Configuration and Verification Commands
You can create custom roles using the Azure portal, Azure CLI, Azure PowerShell, or ARM templates.
Azure CLI example:
az role definition create --role-definition '{
"Name": "Virtual Machine Operator",
"Description": "Can start, stop, and restart virtual machines",
"Actions": [
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/read"
],
"NotActions": [],
"DataActions": [],
"NotDataActions": [],
"AssignableScopes": ["/subscriptions/12345678-1234-1234-1234-123456789abc"]
}'Azure PowerShell example:
$roleDefinition = @{
Name = "Virtual Machine Operator"
Description = "Can start, stop, and restart virtual machines"
Actions = @(
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/powerOff/action",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/read"
)
NotActions = @()
DataActions = @()
NotDataActions = @()
AssignableScopes = @("/subscriptions/12345678-1234-1234-1234-123456789abc")
}
New-AzRoleDefinition @roleDefinitionVerification:
List custom roles: az role definition list --custom-role-only true
Show a specific role: az role definition show --name "Virtual Machine Operator"
List role assignments for a role: az role assignment list --role "Virtual Machine Operator"
Interaction with Related Technologies
Custom roles interact with:
Azure Policy: Policy can enforce that only custom roles meeting certain criteria can be created (e.g., require certain NotActions).
Azure Blueprints: Blueprints can include custom role definitions and assignments as part of environment deployment.
PIM (Privileged Identity Management): Custom roles can be made eligible for activation via PIM, providing just-in-time access.
Azure AD Conditional Access: While Conditional Access does not directly check RBAC roles, it can enforce MFA for users who have certain role assignments (using the Directory Roles condition).
Management Groups: Custom roles can be assigned at management group scope, and the AssignableScopes can include management groups, allowing the role to be used across multiple subscriptions.
Understanding Scope and Inheritance
Role assignments are inherited from the scope they are assigned at down to child scopes. For example, if you assign a custom role at the subscription scope, it applies to all resource groups and resources in that subscription. However, the role definition itself must have the assignable scope set to that subscription or above. If you try to assign a custom role at a resource group scope but the role's AssignableScopes only includes the subscription, the assignment will fail.
DataActions vs Actions
A critical distinction on the exam: Actions control management plane operations (Azure Resource Manager API), while DataActions control data plane operations (service-specific APIs). For example:
Microsoft.Storage/storageAccounts/listKeys/action is an Action (management plane) that allows listing storage account keys.
Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read is a DataAction that allows reading blob content.
If you assign a role with only Microsoft.Storage/storageAccounts/read (Action), the user can see storage account properties but cannot read blobs. To read blobs, you need the DataAction. Built-in roles like Storage Blob Data Reader include DataActions. Custom roles must explicitly include DataActions for data plane access.
Role Definitions vs Role Assignments
Role Definition: The JSON document that defines the permissions (the "template").
Role Assignment: The attachment of a role definition to a security principal (user, group, service principal) at a specific scope. You can have one role definition assigned to many principals at many scopes.
Update and Delete Considerations
Updating a custom role: Use az role definition update or Set-AzRoleDefinition. Changes take effect immediately for all current assignments.
Deleting a custom role: Use az role definition delete or Remove-AzRoleDefinition. If the role has active assignments, the deletion will fail unless you use the --force flag (CLI) or -Force (PowerShell). After deletion, existing assignments become orphaned and will be ineffective.
Common Patterns
Deny assignments: Azure also supports deny assignments (via Azure Blueprints or managed applications) that override role assignments. Custom roles do not directly create deny assignments; deny assignments are separate.
Least privilege: Custom roles are the primary tool for implementing least privilege. You should start with the minimum actions needed and add more only as required.
Exam Tip: Wildcards and NotActions
The exam loves to test understanding of wildcards and NotActions. For example, a role that includes Microsoft.Compute/virtualMachines/* and Microsoft.Compute/virtualMachines/delete in NotActions allows all VM operations except delete. However, if a new VM operation is added by Microsoft (e.g., Microsoft.Compute/virtualMachines/evacuate), the role automatically allows it because of the wildcard. If you want to deny all future operations except a specific set, you would use Microsoft.Compute/* in Actions and then list specific NotActions, but that can become unmanageable. The exam expects you to know that wildcards expand to all current and future actions under that resource type.
Identify Required Permissions
Start by determining the exact actions the role needs to allow. For example, a role for a helpdesk operator might need to reset VM passwords, restart VMs, and view VM status. List these as Azure resource provider operations. Use the Azure CLI command `az provider operation show --namespace Microsoft.Compute` to find the exact action strings. Also consider whether data plane permissions are needed (e.g., reading blobs). Document the actions, not actions, data actions, and not data actions. This step is critical because missing an action will cause access failures, and including too many violates least privilege.
Define the Role JSON
Create a JSON document with the role definition. Use the structure: Name, Description, Actions, NotActions, DataActions, NotDataActions, AssignableScopes. Ensure AssignableScopes includes at least one scope (management group, subscription, or resource group). If you plan to assign the role at multiple scopes, include all those scopes. For example, if the role will be used in two subscriptions, add both subscription IDs. The JSON can be created in a file or inline. Validate the JSON syntax to avoid errors during creation.
Create the Custom Role
Use Azure CLI, PowerShell, or the portal to create the role. In CLI: `az role definition create --role-definition @role.json`. In PowerShell: `New-AzRoleDefinition -InputFile role.json`. The portal provides a guided wizard. After creation, the role is available for assignment. Verify the role exists with `az role definition list --custom-role-only true`. Note that custom roles are stored in Azure AD (now Microsoft Entra ID) and are visible across the entire directory, but their AssignableScopes limit where they can be assigned.
Assign the Custom Role
Assign the role to a security principal (user, group, or service principal) at a specific scope. Use CLI: `az role assignment create --assignee user@domain.com --role "Custom Role Name" --scope /subscriptions/sub-id/resourceGroups/rg1`. The scope must be within one of the AssignableScopes defined in the role. If the scope is not in AssignableScopes, the assignment fails. Role assignments are inherited down the hierarchy. For example, assigning at subscription scope applies to all resource groups. Use `az role assignment list` to verify.
Test and Validate Permissions
Have the assigned user or service principal attempt the allowed actions. For example, try to restart a VM using Azure CLI: `az vm restart --resource-group rg1 --name vm1`. If the role only includes start and read, the restart should fail. Use `az role assignment list --assignee user@domain.com --include-inherited` to see effective permissions. You can also use the Azure portal's "Check access" tab for a resource to see what permissions a user has. If permissions are not working, check the role definition for missing actions or incorrect scopes.
Enterprise Scenario 1: Developer Sandbox Environment
A large enterprise gives developers access to a sandbox subscription where they can create and manage resources but cannot delete resource groups or modify networking components. Built-in Contributor allows deletion, which is too risky. The security team creates a custom role called "Sandbox Developer" with actions like Microsoft.Compute/*, Microsoft.Storage/*, Microsoft.Network/networkInterfaces/*, but with NotActions including Microsoft.Resources/subscriptions/resourceGroups/delete and Microsoft.Network/virtualNetworks/*. The role is assigned at the subscription scope with AssignableScopes limited to that sandbox subscription. This prevents the role from being used in production. Common misconfiguration: forgetting to add Microsoft.Resources/subscriptions/resourceGroups/write which is needed to create resources in a resource group. Without it, developers cannot create VMs because creating a VM requires writing to the resource group.
Enterprise Scenario 2: Storage Blob Reader for External Auditors
External auditors need read-only access to specific storage account containers for a compliance review. Built-in Storage Blob Data Reader gives read access to all blobs in the storage account, but the auditors should only access a specific container. The team creates a custom role with DataAction Microsoft.Storage/storageAccounts/blobServices/containers/blobs/read and restricts the AssignableScopes to the specific container resource ID: /subscriptions/.../resourceGroups/rg1/providers/Microsoft.Storage/storageAccounts/account1/blobServices/default/containers/audit-container. However, the role assignment must be at the container scope, not the storage account. This granularity is only possible with custom roles. A common pitfall: the role definition must include the container scope in AssignableScopes, and the assignment must be made at that scope. If the assignment scope is the storage account, the role will not work because the role's AssignableScopes does not include the storage account.
Enterprise Scenario 3: Service Principal for Automated Backups
A service principal needs to perform automated backups of virtual machines and SQL databases. It requires permissions to list VMs, read disk snapshots, and write to a backup storage account. The team creates a custom role "Backup Operator" with actions: Microsoft.Compute/virtualMachines/read, Microsoft.Compute/disks/read, Microsoft.Compute/snapshots/beginGetAccess/action, Microsoft.Storage/storageAccounts/listKeys/action, and DataAction Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write. They assign the role to the service principal at the resource group scope containing the VMs and storage account. They also ensure the storage account firewall allows access from the service principal's IP or uses a managed identity. Misconfiguration: forgetting the listKeys action, which is needed to get the storage account key for backup tools that use key-based authentication.
What AZ-500 Tests on Custom RBAC Roles
AZ-500 objective 1.1 includes "Configure custom RBAC roles." The exam expects you to:
Understand the difference between Actions, NotActions, DataActions, and NotDataActions.
Know how to create a custom role using Azure CLI, PowerShell, or portal.
Understand AssignableScopes and how they restrict where a role can be assigned.
Be able to identify the correct JSON syntax for a role definition.
Know the maximum limits (5,000 custom roles per directory, 4,000 role assignments per subscription, 1,024 actions per role).
Understand inheritance and scope.
Know that custom roles are stored in Microsoft Entra ID (formerly Azure AD) and are visible across the directory.
Common Wrong Answers and Why Candidates Choose Them
Choosing DataActions when Actions are needed: Candidates often confuse management plane and data plane. For example, they might try to allow reading a blob by adding Microsoft.Storage/storageAccounts/read (an Action) instead of the DataAction. Wrong because read on the storage account only shows properties, not blob content.
Omitting AssignableScopes or setting it incorrectly: A candidate might create a custom role without AssignableScopes, which causes the creation to fail, or set it to a scope that is too narrow, preventing assignments at the desired scope. The exam may present a scenario where a role cannot be assigned at a resource group because AssignableScopes only includes the subscription. The correct fix is to add the resource group scope to AssignableScopes.
Thinking NotActions override Actions in all cases: Actually, NotActions only remove permissions from Actions. If an action is not in Actions, adding it to NotActions has no effect. Candidates might think adding an action to NotActions denies it even if it's not in Actions, but that's incorrect.
Assuming custom roles can be assigned at any scope regardless of AssignableScopes: The exam tests that AssignableScopes is a hard limit. If you try to assign a custom role at a scope not in its AssignableScopes, the assignment fails. Candidates might forget this and choose an assignment that violates the scope.
Specific Numbers, Values, and Terms
5,000 custom roles per directory (Azure AD).
4,000 role assignments per subscription.
1,024 actions per role definition (including wildcard expansions).
AssignableScopes must be specified; cannot be empty.
DataActions are required for data plane access.
Wildcards: * at the end of an action string matches all actions under that resource type.
Edge Cases and Exceptions
Classic subscription administrators (Service Admin, Co-Admin) have equivalent access to Owner at subscription scope, but they are not RBAC roles. Custom roles cannot replicate classic admin privileges.
Deny assignments (from Azure Blueprints or managed applications) can override custom role permissions. The exam may include a scenario where a deny assignment blocks an action even though a custom role allows it.
Custom roles with DataActions but no Actions: You can create a role that only has DataActions, like a pure data reader for blobs. This is valid.
Role definitions are immutable in terms of versioning: Updating a role definition overwrites the existing one. There is no version history.
How to Eliminate Wrong Answers
If the question involves reading data (blobs, queues, tables, key vault secrets), look for DataActions in the role definition. If only Actions are present, it's likely wrong.
If the question mentions that a role cannot be assigned at a certain scope, check the AssignableScopes. The problem is likely that the scope is not listed.
If the question tests wildcards, remember that Microsoft.Compute/virtualMachines/* includes all current and future VM operations. NotActions can exclude specific ones.
If the question involves a service principal, remember that role assignments for service principals work the same as for users.
Custom roles are defined by a JSON document with Actions, NotActions, DataActions, NotDataActions, and AssignableScopes.
AssignableScopes restricts where the role can be assigned; it must include the scope(s) where you plan to assign the role.
DataActions are required for data plane access (e.g., reading blobs, writing to queues); Actions alone do not grant data plane permissions.
NotActions only subtract from Actions; they cannot deny actions not in Actions.
Maximum 5,000 custom roles per directory, 4,000 role assignments per subscription, and 1,024 actions per role definition.
Custom roles can be updated in place; changes apply immediately to all assignments.
Role assignments are inherited from parent scopes to child scopes.
Custom roles are stored in Microsoft Entra ID and are visible across the directory, but their usage is limited by AssignableScopes.
These come up on the exam all the time. Here's how to tell them apart.
Custom RBAC Roles
Fully customizable: you define exact Actions, NotActions, DataActions, NotDataActions.
Must specify AssignableScopes; cannot be assigned outside those scopes.
Maximum 5,000 per directory.
Can include DataActions for data plane permissions.
Requires explicit creation and maintenance; no automatic updates from Microsoft.
Built-in RBAC Roles
Predefined by Microsoft; cannot be modified.
Assignable at any scope without restrictions (no AssignableScopes property).
Approximately 70+ built-in roles (as of 2025).
Some built-in roles include DataActions (e.g., Storage Blob Data Reader).
Automatically updated by Microsoft with new actions when services evolve.
Mistake
Custom roles can be assigned at any scope without restrictions.
Correct
Custom roles have an AssignableScopes property that limits where the role can be assigned. If you try to assign a role at a scope not listed in AssignableScopes, the assignment fails. You must include the desired assignment scope in AssignableScopes when creating the role.
Mistake
DataActions and Actions are interchangeable; both control access to resources.
Correct
Actions control management plane operations (Azure Resource Manager), while DataActions control data plane operations (service APIs). For example, reading a blob requires a DataAction, not an Action. They are not interchangeable.
Mistake
NotActions can deny actions that are not in Actions.
Correct
NotActions only subtract from Actions. If an action is not included in Actions, adding it to NotActions has no effect. To deny an action, you must first include it in Actions (or use a wildcard) and then add it to NotActions.
Mistake
Custom roles are scoped to a single subscription and cannot be used across subscriptions.
Correct
Custom roles are stored in Microsoft Entra ID and can be assigned across multiple subscriptions as long as those subscriptions are included in the AssignableScopes. You can include multiple subscription IDs or a management group ID in AssignableScopes.
Mistake
Updating a custom role requires deleting and recreating it.
Correct
You can update a custom role using Azure CLI (`az role definition update`) or PowerShell (`Set-AzRoleDefinition`). Changes take effect immediately for all assignments. No need to delete and recreate.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
A role definition is the set of permissions (the JSON document) that defines what actions are allowed. A role assignment is the attachment of a role definition to a security principal (user, group, or service principal) at a specific scope. You can have one role definition used in many role assignments. For example, you create a custom role 'VM Operator' (definition) and then assign it to Alice at subscription scope and to Bob at resource group scope (assignments).
Yes, but you need to use DataActions. The action to read a secret is `Microsoft.KeyVault/vaults/secrets/read` which is a DataAction. You must include it in the DataActions array. Additionally, you may need management plane actions like `Microsoft.KeyVault/vaults/read` to list vaults. Also, Key Vault has its own access policies that can override RBAC; you need to ensure the vault uses RBAC permissions (Azure RBAC for Key Vault data plane) or grant access via access policies.
By default, deletion will fail if there are active assignments. You must use the `--force` flag (CLI) or `-Force` parameter (PowerShell) to delete the role definition even with assignments. After deletion, the assignments become orphaned and no longer grant any permissions. The assignments still exist but are ineffective. You can remove them manually or they will remain until cleaned up.
Yes, but only if the custom role's AssignableScopes includes that management group or a parent scope (e.g., root `/`). If AssignableScopes only includes a subscription, you cannot assign the role at the management group that contains that subscription. You must add the management group ID to AssignableScopes.
Use Azure CLI: `az provider operation show --namespace Microsoft.Compute` to list all operations for that provider. You can also use the Azure portal: go to the resource provider in the subscription blade, or use the Azure Resource Manager documentation. The action strings follow the pattern `{Provider}/{ResourceType}/{Action}`.
Yes, you can export a built-in role definition to JSON, modify it, and create a custom role. Use `az role definition list --name "Reader" > reader.json`, edit the JSON, remove the `AssignableScopes` property (or set it), and then create the custom role. Note that you cannot use the same name as a built-in role.
Maximum 5,000 custom roles per Azure AD directory. Maximum 4,000 role assignments per subscription. Maximum 1,024 actions (including wildcard expansions) per role definition. There is no limit on the number of role definitions per scope, but the 5,000 directory limit applies.
You've just covered Custom RBAC Roles in Azure — now see how well it sticks with free AZ-500 practice questions. Full explanations included, no account needed.
Done with this chapter?