Background
Sections
IntroductionFoundations1. Resource Hierarchy2. Resource Manager3. Identity and RBAC4. Regions and Availability5. Naming and TaggingVirtual Machines1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetVirtual Network1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetBlob Storage1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure SQL Database1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Kubernetes Service1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Container Registry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetMicrosoft Entra ID1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure RBAC1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Functions1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAPI Management1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure App Configuration1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Machine Learning1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure Monitor1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and CheatsheetAzure AI Foundry1. What and Why2. Core Concepts3. Architecture4. Getting Started5. Deployment6. Integrations7. Production8. Interview Questions9. Glossary and Cheatsheet

1. What and Why

10 min read

One sentence. Azure RBAC is the always-on, free authorisation system built into Azure Resource Manager that decides whether a given identity may perform a given operation on a given resource, by evaluating role assignments — a triple of principal, role definition, and scope.

Analogy. Think of a large office building. Microsoft Entra ID is the pass office: it knows every employee and contractor, issues the badges, and decides how hard a badge is to obtain. Azure RBAC is the set of card readers on individual doors. Each reader has been programmed with a rule of the shape "badges belonging to this group may open this door, and every door inside it." The pass office manager can print any badge in the building and still can't open the server room, because nobody programmed that reader to accept her badge. Nothing about being able to make identities implies being able to use them.

Technically. Every request to management.azure.com carries an OAuth 2.0 bearer token signed by Entra ID. ARM extracts the principal's object ID from the oid claim, resolves the group memberships in the token, gathers every role assignment applying at or above the target resource's scope, unions the operation strings those roles permit, and tests the requested operation against that set. Allowed requests proceed to the resource provider. Denied ones return HTTP 403 with an AuthorizationFailed body naming the principal, the action, and the scope evaluated.

[Image Prompt: 2D minimalistic diagram showing where Azure RBAC sits between upstream identity sources — users, groups, service principals, and managed identities from Microsoft Entra ID — and downstream Azure resources across management groups, subscriptions, resource groups, and individual resources, with the role assignment shown as the connecting object, flat design, clean vector art style, white background, labelled boxes and arrows]


The problem before it existed

Azure's original model was the classic or "Azure Service Management" one, and it had exactly three roles at the subscription level: Account Administrator, Service Administrator, and Co-Administrator. That's it. There was no way to say "this team may manage the web tier and nothing else", so every engineer who needed to deploy anything became a Co-Administrator of the whole subscription.

The two failure modes that produces are both bad and both common:

Everyone is an administrator. Someone runs a cleanup script against the wrong subscription and deletes production. The postmortem action item is "be more careful", because there is no technical control available to write down.

Nobody has access. The organisation reacts to the first outcome by removing everyone and routing all changes through a small platform team. Deployment becomes a ticket queue, lead times go from minutes to days, and engineers start keeping a shadow subscription on a personal credit card.

RBAC dissolves the choice by making a grant narrow along three axes at once, independently:

Axis Question Mechanism
Who Which identity holds this? A security principal — and ideally a group, so membership is the thing that changes
What Which operations does it permit? A role definition — hundreds of built-in ones, or a custom one
Where Over which resources? A scope — management group, subscription, resource group, or a single resource

The important property is that these compose. "The payments on-call group may restart virtual machines, but only in rg-payments-prod" is one assignment, expressible without writing a policy document, without a naming convention, and without trusting anyone to be careful.


Where it sits in the Azure catalogue

Azure RBAC is not a service you deploy. There is nothing to provision, no SKU to choose, and no meter attached to it. It is a capability of ARM itself, surfaced through the Microsoft.Authorization resource provider and visible in the portal as the Access control (IAM) blade that appears on every scope. Its assignments are ARM resources, which is the whole reason Terraform and Bicep can manage them.

Four neighbours account for nearly all the confusion. Separating them is the most useful thing this page does.

Entra directory roles — a different system with similar names

Global Administrator, User Administrator, and Application Administrator are directory roles. They govern the tenant: users, groups, app registrations, licences, domains, tenant-wide settings. They are assigned through Entra ID, stored in the directory, and evaluated by Microsoft Graph — not ARM.

Azure roles (Owner, Contributor, Reader, Storage Blob Data Reader) govern Azure resources. They are assigned through ARM at a resource scope.

The two sets are almost entirely disjoint. Use directory role and Azure role as distinct terms and refuse to say "Azure AD role", which means neither reliably. Full comparison in Core Concepts.

Azure Policy — asks what, not who

RBAC decides whether you may create a virtual machine. Azure Policy decides whether that virtual machine is permissible: which sizes, which regions, which tags, whether a public IP may be attached. Policy applies regardless of the caller's identity — an Owner is denied by policy exactly like everyone else.

The practical tell: a policy denial returns RequestDisallowedByPolicy and names the policy assignment. No role will fix it, and granting a broader role is the classic wasted afternoon.

They are complements, not alternatives. RBAC without Policy means a Contributor can build anything, anywhere, untagged. Policy without RBAC means the shape is constrained but anyone can change anything.

Resource locks — blunt, and they outrank Owner

A lock (CanNotDelete or ReadOnly) applied to a resource, resource group, or subscription blocks the corresponding operations for every principal, Owner included. It's the right tool for "this one production database must not be deleted by accident", because RBAC's only equivalent would be removing delete permission from the whole team.

Locks inherit downward like assignments do, and a lock on a resource group is a common source of mysterious failures in resources inside it. The error is ScopeLocked, which reads like a permissions problem and isn't one.

Data-plane authorisation — the parallel system that routes around you

Many services shipped their own authorisation model before RBAC reached their data plane, and most still support both:

Service The RBAC path The parallel path that bypasses it
Storage Storage Blob Data Reader and friends Account keys, SAS tokens
Key Vault Key Vault Secrets User (RBAC permission model) Vault access policies (the legacy model)
Azure SQL Entra authentication + database roles SQL logins and passwords
Service Bus Azure Service Bus Data Sender Shared Access Signature policies
AKS Azure RBAC for Kubernetes authorisation Kubernetes RBAC with the cluster admin kubeconfig

Where a service offers a switch — allowSharedKeyAccess = false on a storage account, RBAC rather than access policy on a Key Vault, disableLocalAccounts on AKS — flipping it is what makes your RBAC design load-bearing rather than aspirational. Otherwise you have written a careful permission model and left the side door unlocked.


The AWS analogue, and where it breaks

Rough analogue: AWS IAM policies plus IAM's evaluation logic.

What transfers. Principals. Permission strings that name a service and an operation. The idea that a grant can be limited to specific resources. Short-lived credentials as the correct pattern for workloads.

Where it breaks — four places, each of which will bite:

1. There is no explicit deny. This is the big one. AWS evaluation is deny-by-default with explicit-deny-wins, which makes patterns like "Administrator except for these tagged resources" natural. Azure RBAC computes the pure union of every role assignment at or above the scope. Nothing subtracts. notActions exists and looks like a deny, but it only removes permissions from that one role definition — a second assignment granting the same action wins. Platform deny assignments exist, are created by Azure managed applications, and cannot be authored by you.

The design consequence: breadth is permanent until removed at its source. You cannot compensate for an over-broad assignment further down the tree.

2. There are no permission boundaries or SCPs at the RBAC layer. AWS uses SCPs at the organisation level as a ceiling on what accounts can do. Azure's equivalent guardrail is Azure Policy assigned at a management group — a different system with different semantics (deny effects on request shapes, not permission subtraction). If you're looking for "the SCP equivalent", it's Policy, not RBAC.

3. The grant is an object, not a document attached to an identity. An IAM policy hangs off a user, group, or role. An Azure role assignment is a standalone ARM resource with its own GUID name, living at the scope, referencing the principal and the role. So the question "what can this person do" is answered by querying assignments across the tree (az role assignment list --assignee <oid> --all), not by reading an attached document. And deleting a principal leaves its assignments behind as orphans pointing at a dead object ID.

4. The control plane and the data plane are authorised separately, by different evaluators. In AWS, s3:CreateBucket and s3:GetObject live in the same policy, evaluated by the same engine. In Azure, managing a storage account (actions, evaluated by ARM) and reading a blob (dataActions, evaluated by blob.core.windows.net) are separate concerns, and most built-in management roles carry only the former. Owner does not let you read a blob. Nothing in an AWS mental model prepares you for this, and it is the most frequent 403 in Azure.


When NOT to reach for RBAC

To enforce a configuration standard. Region restrictions, required tags, allowed SKUs, "no public IPs" — all Azure Policy. Attempting them as permissions produces a custom role that has to be maintained forever as Azure adds operations, and it still fails, because a Contributor can create a compliant resource and then modify it.

To protect one resource from deletion. Use a CanNotDelete lock. Removing delete permission via RBAC removes it from the whole team for the whole scope.

To express "everyone except X". No deny, no exceptions. Reshape the grant to be narrow from the outset.

As the only control while a key-based path exists. Disable shared-key access, migrate Key Vault to the RBAC permission model, disable AKS local accounts. Until then, RBAC is one of two doors.

As a substitute for network controls. RBAC governs who is authorised. Private endpoints and firewall rules govern who can reach the endpoint at all. An estate needs both; neither implies the other.

To achieve per-object granularity in services that don't support conditions. ABAC conditions on blob index tags and path prefixes are real and useful, but coverage is service-by-service and incomplete ⚠️ verify current coverage against current Azure docs. Where conditions don't reach, splitting the data across containers or accounts so the scope boundary matches the permission boundary is usually the honest answer — proliferating custom roles is not.

For standing highly-privileged access, in any form. Not because RBAC can't express it, but because it shouldn't be the answer. The number of accounts that need permanent Owner is close to zero; the rest should activate through PIM with justification and an expiry, or be a documented, alarmed break-glass account. Production covers both.


What you should be able to say after this page

  • Azure RBAC authorises operations on Azure resources; Entra directory roles authorise operations on the tenant. Global Administrator and Owner are different jobs.
  • A grant is exactly principal + role + scope, and it is an ARM resource.
  • Assignments inherit downward and union with no deny, so scope choice is consequential and irreversible from below.
  • RBAC and Azure Policy answer different questions; locks outrank everyone; and the data plane is authorised separately from the control plane.

Next: Core Concepts →

← Back to the Azure RBAC overview