RBAC Patterns Standard
Principle
Assign the narrowest permission at the narrowest practical scope. Data access requires data-plane roles or service-native data-plane permissions, not generic management-plane roles.
Common built-in role IDs
| Role | ID | Use for |
|---|---|---|
| Key Vault Secrets User | 4633458b-17de-408a-b874-0445c86b69e6 |
Read secret values from RBAC-enabled Key Vault |
| Key Vault Reader | 21090545-7ca7-4776-b22c-e363652d74d2 |
Read Key Vault metadata only |
| Storage Blob Data Reader | 2a2b9908-6ea1-4ae2-8e65-a410df84e7d1 |
Read/list blobs |
| Storage Blob Data Contributor | ba92f5b4-2d11-453d-a403-e96b0029c9fe |
Read/write/delete blobs |
| Storage Queue Data Message Sender | c6a89b2d-59bc-44d0-9896-0f6e12d7b80a |
Add queue messages |
| Storage Queue Data Message Processor | 8a0f0c08-91a1-4084-bc3d-661d67233fed |
Peek, retrieve, and delete queue messages |
| Azure Service Bus Data Sender | 69a216fc-b8fb-44d8-bc22-1f3c2cd27a39 |
Send Service Bus messages |
| Azure Service Bus Data Receiver | 4f6d3b9b-027b-4f4c-9142-0e5a2a2247e0 |
Receive Service Bus messages |
| Azure Event Hubs Data Sender | 2b629674-e913-4c01-ae53-ef4638d8f975 |
Send Event Hubs events |
| Azure Event Hubs Data Receiver | a638d3c7-ab3a-418d-83e6-5f17a39d4fde |
Receive Event Hubs events |
| Azure Event Hubs Data Owner | f526a384-b230-433a-b45c-95f59c4a2dec |
Full Event Hubs data access; avoid unless required |
| Managed Identity Operator | f1a07417-d97a-45cb-824c-7a7467783830 |
Assign a user-assigned managed identity to a resource |
| Managed Identity Contributor | e40ec5ca-96e0-45a2-b4ff-59039f2c2b59 |
Manage user-assigned managed identity resources |
Verify current role IDs against Azure built-in roles before generating final deployment code.
Scope guidance
| Scope | Use when | Example |
|---|---|---|
| Child resource | Service needs one queue, topic, event hub, container, or database object | Service Bus sender on one queue |
| Resource | Service needs access to the whole account/namespace/vault | Blob contributor on one storage account |
| Resource group | Platform automation genuinely needs all resources in a group | Deployment pipeline for one app resource group |
| Subscription | Platform automation only | Landing-zone or policy deployment identity |
Never assign data-plane roles at subscription scope for application workloads.
Idempotent Bicep role assignment
resource role_assignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(target_resource.id, principal_id, role_definition_id)
scope: target_resource
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', role_definition_id)
principalId: principal_id
principalType: 'ServicePrincipal'
}
}Propagation handling
Azure RBAC uses eventual consistency. Application startup, health checks, and post-deployment tests must tolerate temporary 403 Forbidden responses immediately after role assignments. Use retry with exponential backoff for the first data-plane operation after deployment.
Anti-patterns
| Anti-pattern | Correct approach |
|---|---|
Owner for an app to read secrets |
Key Vault Secrets User at vault scope |
Contributor for blob reads/writes |
Storage Blob data role |
Storage Account Key Operator Service Role for app access |
Blob/Queue/Table data role and shared key disabled |
| One service principal secret shared by pipelines | Federated service connection per scope/environment |
Management-plane Cosmos DB Account Reader Role for data reads |
Cosmos DB native data-plane role assignment |
SQL Azure SQL DB Contributor for app query access |
Contained database user plus database grants |