Azure Lesson 7 of 137

Microsoft Entra ID Fundamentals: Tenants, Users, Groups & RBAC

In a nutshell

Picture your company’s head office. Microsoft Entra ID is two things rolled into one: the staff directory that lists everyone who works there, and the security desk in the lobby that checks IDs and prints badges. Nobody gets past the lobby without being in the directory and clearing the desk.

That last point is the whole game: who are you? (authentication, done by Entra ID) and are you allowed to do this here? (authorization, done by Azure RBAC) are different questions with different answers. Get those two ideas straight and everything below — tenants, service principals, scopes, role assignments — is just detail hanging off the frame.

Level: Beginner · Time: ~31 min · You’ll need an Azure account with a subscription and comfort opening Cloud Shell. By the end you can create a group, grant it a role at the right scope, and explain why an all-powerful Entra admin still can’t touch your Azure resources.

Every action you take in Azure — clicking a button in the portal, running an az command, an app reading a secret — is answered by two questions before anything happens: who are you? and are you allowed to do this here? The first question is authentication, and it is answered by Microsoft Entra ID (Microsoft’s cloud identity service, formerly called Azure Active Directory). The second is authorization, and it is answered by Azure RBAC (role-based access control).

Get these two right and the rest of Azure becomes safe to explore: you can hand a teammate exactly the access they need and nothing more, and you can let an application authenticate without ever pasting a password into your code. This lesson explains the building blocks in plain terms and then has you grant a real permission with the CLI — and take it back again.

Learning objectives

By the end of this lesson you can:

Prerequisites & where this fits

You need an Azure account with access to a subscription, and comfort opening Azure Cloud Shell (the browser-based shell with az pre-installed). If you have not met subscriptions and resource groups yet, read What Is Azure? first, and Working with Azure: Portal, CLI, PowerShell & Cloud Shell to get fluent with the CLI. This is Lesson 3 of the Identity module in the Azure Zero-to-Hero course — the foundation that the landing-zone and security lessons later build on.

Authentication vs authorization: the two doors

Keep these two words straight and everything else falls into place:

A useful mental model: Entra ID is the front desk that checks your ID and prints a visitor badge. RBAC is the set of door locks inside the building that decide which rooms your badge opens. The badge alone gets you in the lobby; it does not unlock anything by itself.

Microsoft Entra ID: the identity directory

A tenant is your organization’s dedicated instance of Entra ID — a private directory of identities. It has a default domain like contoso.onmicrosoft.com and a globally unique Tenant ID (a GUID). Crucially, a tenant is not a subscription:

One tenant can trust many subscriptions; every subscription trusts exactly one tenant for sign-in. The directory contains a handful of object types you will use constantly.

Users

A user is a person (or a break-glass admin account). Two flavours matter early on:

Groups

A group is a named bucket of users (and sometimes other groups). You almost never assign access to individuals — you assign it to a group and manage membership. Two types you will meet:

Group type Membership Typical use
Security group People or apps Granting Azure RBAC and app access
Microsoft 365 group People Shared mailbox, Teams, calendar

Groups can be assigned (you add members by hand) or dynamic (membership is a rule, e.g. everyone in the Finance department). For RBAC, security groups are the workhorse.

Service principals & app registrations

People are not the only things that sign in — applications do too. The plumbing has two parts:

So when a CI/CD pipeline or a script needs to deploy to Azure, it authenticates as a service principal and is authorized by the roles assigned to that principal. The catch: a classic service principal usually holds a secret or certificate — a credential you must store, rotate, and protect. Which leads to the better option.

Managed identities

A managed identity is a service principal that Azure creates and rotates for youno secret to store anywhere. You turn it on for an Azure resource (a VM, a Function App, a Container App), grant that identity an RBAC role, and the resource’s code requests tokens from a local endpoint. There is nothing to leak because there is no credential in your config. Two kinds:

Rule of thumb: for anything running inside Azure, prefer a managed identity over an app-registration-plus-secret. Eliminating long-lived secrets is one of the highest-value habits you can build, covered in depth in Eliminating Secrets: Key Vault and Workload Identity Federation.

Azure RBAC: who can do what, where

With identities sorted, RBAC decides what they may do. Every grant of access in Azure is the same three-part sentence:

<security principal> is assigned <role> at <scope>.

That is a role assignment, and the three parts are:

  1. Security principalwho: a user, a group, a service principal, or a managed identity.
  2. Role definitionwhat: a named collection of permitted operations (Actions/DataActions it allows, NotActions it excludes). “Reader” is a role definition.
  3. Scopewhere: the slice of Azure it applies to.

Read every assignment back as that sentence and RBAC stops being mysterious.

Scope and inheritance: the ladder

Azure resources live in a four-level hierarchy, and a role assigned at any level flows down to everything beneath it. Inheritance is the whole trick:

Microsoft Entra tenant objects and the Azure RBAC scope-inheritance ladder

The diagram shows the Entra tenant objects (users, groups, service principals, managed identities) on one side and the RBAC scope ladder on the other. Reading the ladder top to bottom:

Inheritance is additive and you cannot subtract with a deny by default — a role at a higher scope is added to whatever is granted lower down. Grant broadly and you have over-shared; grant at the lowest scope that does the job and you are practising least privilege. (Azure does support explicit deny assignments, but those are created by Azure-managed features like Blueprints/Managed Apps, not hand-authored in day-to-day work.)

The three built-in roles you must know

Azure ships dozens of built-in roles (and you can author custom ones), but three cover most situations:

Role Can it manage resources? Can it grant access to others? Use it for
Owner Yes — full control Yes A small number of administrators
Contributor Yes — create/change/delete No Engineers who build things
Reader No — view only No Auditors, dashboards, on-call read access

The decisive difference is the right to manage access (the Microsoft.Authorization/roleAssignments/write permission). Owner has it; Contributor does not. That single line is why you hand out Contributor, not Owner, by default — a Contributor can build your whole stack but cannot quietly grant themselves or others more power.

Least privilege in one sentence

Give each identity the least role at the smallest scope that still lets it do its job — and nothing more. A reporting dashboard gets Reader on one resource group, not Contributor on the subscription. When access needs are temporary or high-risk, don’t make a permanent assignment at all — elevate just in time, which is exactly what Just-in-Time Access: PIM for Azure Roles & Groups covers.

Entra roles vs Azure RBAC roles: the big mix-up

This trips up nearly everyone, so make it stick. They are two separate permission systems that govern two different things.

Entra roles (directory roles) Azure RBAC roles (resource roles)
Control The Entra directory — identities themselves Azure resources — VMs, storage, networks
Examples Global Administrator, User Administrator, Application Administrator Owner, Contributor, Reader, Storage Blob Data Reader
Scope model The tenant (with administrative units for narrower scope) Management group → subscription → RG → resource
“Who can…” …create users, reset passwords, register apps …start a VM, read a blob, deploy a network
Managed in Entra ID admin center Each resource’s Access control (IAM) blade

The classic gotcha: a Global Administrator (the most powerful Entra role) does not automatically have access to Azure resources. By default a Global Admin cannot even see your subscriptions. (There is one deliberate escape hatch — a Global Admin can toggle “access management for Azure resources” to grant themselves User Access Administrator at the root and bootstrap RBAC — but it is an explicit, audited action, not the default.) Likewise, Owner on a subscription lets you manage every resource but does not let you create users or reset passwords in the directory.

Hold the two apart: Entra roles manage identities and the directory; Azure RBAC roles manage resources.

MFA and Conditional Access (the next layer)

Issuing a token only after a correct password is no longer enough — passwords get phished and reused. Multi-factor authentication (MFA) requires a second proof of identity (an authenticator-app approval, a passkey, a hardware key) so a stolen password alone is useless. Conditional Access is the policy engine that decides when to demand that second factor and under what conditions to allow a sign-in at all — for example, “require MFA for admins,” “block sign-ins from outside our countries,” or “require a compliant device for the finance app.” Together they harden the authentication door before RBAC’s authorization locks ever come into play. We only name them here; they are explored in depth in Stopping Token Theft: Conditional Access Token Protection and across the security module.

Hands-on lab

You will create a security group, grant it the Reader role at a resource-group scope, verify the assignment, then remove everything. Everything here uses the az CLI in Azure Cloud Shell — no install required. Entra objects and role assignments are free; the empty resource group costs nothing.

Step 1 — Open Cloud Shell and confirm your context

In the Azure portal, click the Cloud Shell icon (>_) in the top bar and choose Bash. Confirm which subscription you are in:

az account show --output table

Expected output (your values will differ):

Name              CloudName    SubscriptionId                        State    IsDefault
----------------  -----------  ------------------------------------  -------  ---------
Visual Studio...  AzureCloud   00000000-0000-0000-0000-000000000000  Enabled  True

Capture your subscription ID into a variable — we will build scopes from it:

SUB_ID=$(az account show --query id --output tsv)
echo "$SUB_ID"

Step 2 — Create a resource group to scope the grant

az group create \
  --name rg-rbac-lab \
  --location eastus \
  --output table

Expected:

Location    Name
----------  -----------
eastus      rg-rbac-lab

Step 3 — Create a security group in Entra ID

az ad group create \
  --display-name "rbac-lab-readers" \
  --mail-nickname "rbac-lab-readers" \
  --output table

Grab the group’s object ID — this is the security principal we will assign the role to:

GROUP_ID=$(az ad group show --group "rbac-lab-readers" --query id --output tsv)
echo "$GROUP_ID"

If az ad group create returns Insufficient privileges or Authorization_RequestDenied, your tenant restricts who can create groups. See troubleshooting below — you can still do the role-assignment steps against your own user instead.

Step 4 — Assign Reader at the resource-group scope

This is the core command. Notice the three parts of the sentence — --assignee (who), --role (what), --scope (where):

az role assignment create \
  --assignee "$GROUP_ID" \
  --role "Reader" \
  --scope "/subscriptions/$SUB_ID/resourceGroups/rg-rbac-lab" \
  --output table

Expected (abridged):

Principal                             Role    Scope
------------------------------------  ------  ------------------------------------------------
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  Reader  /subscriptions/.../resourceGroups/rg-rbac-lab

The group — and therefore every member you ever add to it — can now read everything in rg-rbac-lab, and nothing outside it. That is least privilege in action.

Step 5 — Verify the assignment

List role assignments scoped to the resource group and confirm Reader is there:

az role assignment list \
  --scope "/subscriptions/$SUB_ID/resourceGroups/rg-rbac-lab" \
  --query "[].{principal:principalName, role:roleDefinitionName, scope:scope}" \
  --output table

You should see a row with Reader for your group. The --query flag is JMESPath, trimming the verbose JSON to just the fields that matter.

Step 6 — Remove the role assignment

Take the permission back — same three coordinates, delete instead of create:

az role assignment delete \
  --assignee "$GROUP_ID" \
  --role "Reader" \
  --scope "/subscriptions/$SUB_ID/resourceGroups/rg-rbac-lab"

Re-run the Step 5 list command; the Reader row is gone. Removing an assignment does not delete the role definition (Reader still exists for everyone) or the group — it only severs the who-what-where link.

Cleanup

Delete the group and the resource group so nothing lingers:

az ad group delete --group "rbac-lab-readers"

az group delete --name rg-rbac-lab --yes --no-wait

--no-wait returns immediately; deletion finishes in the background.

Cost note: free. Entra groups and RBAC assignments carry no charge, and the resource group held no billable resources.

Going deeper

The concepts above are enough to work safely. This section is for when you want to know why things are built the way they are — the internals, the sharp edges, and the vocabulary that shows up in real designs and interviews. Skim it now; come back after the lab and it will click.

Entra ID is not Active Directory (and why that matters)

The old name — Azure Active Directory — caused a decade of confusion, because Microsoft Entra ID is not a cloud-hosted copy of on-premises Active Directory Domain Services (AD DS). They solve different problems with different protocols:

On-prem Active Directory (AD DS) Microsoft Entra ID
What it is A domain controller on your network A cloud identity provider (IdP) reached over HTTPS
Protocols Kerberos, NTLM, LDAP OpenID Connect, OAuth 2.0, SAML, WS-Fed
Structure Forests, domains, OUs A flat tenant of users, groups, and apps
Policy Group Policy (GPO) Conditional Access policies
Machine trust Domain join Entra join / Entra registration

Entra ID has no LDAP endpoint, no Kerberos, no Group Policy. An app that expects to bind to LDAP or authenticate a service account with a Kerberos ticket cannot talk to Entra ID directly. Instead, modern apps redirect the browser to Entra’s sign-in page and receive a signed token (OIDC for “who you are,” OAuth 2.0 for “what this app may call on your behalf”). That is why “lift-and-shift” of a legacy app that genuinely needs domain services uses Microsoft Entra Domain Services (formerly Azure AD DS) — a managed domain that does speak LDAP/Kerberos/NTLM/GPO — while everything cloud-native uses Entra ID’s token protocols.

Most enterprises run both worlds: on-prem AD for domain-joined machines, synchronized up to Entra ID by Microsoft Entra Connect (or the lighter Entra Cloud Sync agent) so the same username works everywhere. That hybrid sync is what lets priya@contoso.com sign in to both the on-prem file server and the Azure portal with one identity.

The tenant is a hard security boundary

A tenant is not just a container — it is an isolation boundary. Objects in one tenant cannot see or be assigned to another tenant’s resources except through explicit invitation (B2B guests) or app consent. You cannot merge two tenants, and you cannot move a user from one tenant to another — you re-create or invite them. That is why tenant design is a mostly one-way decision, and why most organizations run exactly one production tenant.

Every tenant starts with a *.onmicrosoft.com domain you can never delete, but you almost always add a verified custom domain (contoso.com) by creating the DNS TXT record Entra gives you and clicking Verify. Once verified, users sign in as you@contoso.com. A single tenant can hold many custom domains; any given domain can be verified in only one tenant.

Control plane vs data plane — the RBAC gotcha nobody warns you about

Here is the single most surprising thing about Azure RBAC: managing a resource and using the data inside it are two different permission planes.

The classic trap: a user with Contributor on a storage account can create containers, change settings, even delete the account — but downloading a blob with their own Entra identity is denied, because Contributor grants control-plane Actions and no blob DataActions. To read blob data you assign a data role such as Storage Blob Data Reader. (The escape hatch that confuses people: Contributor can call listKeys to fetch the storage account key and then use that key to reach the data, bypassing RBAC entirely — which is exactly why you disable shared-key access on sensitive accounts.) Key Vault is another special case: it supports both the legacy per-vault access policy model and Azure RBAC, and new vaults should use RBAC data roles like Key Vault Secrets User.

Rule of thumb: if a role name contains the word Data (Storage Blob Data Reader, Cosmos DB Built-in Data Contributor), it is a data-plane role. Owner/Contributor/Reader are control-plane roles.

What a role definition actually is

A role is just JSON. Peel back “Reader” and you find a role definition — permission lists plus the scopes it may be assigned at:

{
  "roleName": "Restart VMs Only",
  "description": "View and restart virtual machines; nothing else.",
  "assignableScopes": ["/subscriptions/00000000-0000-0000-0000-000000000000"],
  "permissions": [
    {
      "actions": [
        "Microsoft.Compute/virtualMachines/read",
        "Microsoft.Compute/virtualMachines/instanceView/read",
        "Microsoft.Compute/virtualMachines/restart/action"
      ],
      "notActions": [],
      "dataActions": [],
      "notDataActions": []
    }
  ]
}

Azure ships hundreds of built-in roles; reach for a custom role only when no built-in fits. Custom roles are defined once and can be assigned anywhere inside their assignableScopes; a single tenant can hold up to 5,000 of them. Wildcards are allowed (Microsoft.Compute/*/read), and NotActions subtracts from Actions (it is a scoping tool, not a deny). You create the role above with az role definition create --role-definition ./restart-vms.json.

How authorization is actually evaluated

When you attempt an operation, ARM gathers every role assignment that applies to you at the target scope and every scope above it, takes the union of their allowed actions, removes anything listed in NotActions, and permits the operation if it survives. There is no ordinary “deny” role — you cannot subtract access with a lower-scope assignment. The only true block is a deny assignment, and those are created only by Azure-managed features (Blueprints, Managed Applications, deployment stacks), never hand-authored; when present, they win over role assignments. This is why “just narrow it later” fails: a broad assignment high up cannot be clawed back by a narrow one below.

App identities, one layer down

Putting it together: how a deployment pipeline authenticates

Watch the primitives cooperate in the most common real scenario — a GitHub Actions workflow that deploys to Azure with no stored secret:

  1. You create an app registration in your tenant (the pipeline’s blueprint); this also creates its service principal, the identity that will actually hold access.
  2. You add a federated credential to that registration, trusting GitHub’s OIDC issuer for your specific repo and branch (workload identity federation — no client secret anywhere).
  3. You grant that service principal Contributor at the resource-group scope it deploys into — least privilege: it can build the app’s resources and nothing outside that RG.
  4. At runtime the workflow requests a short-lived OIDC token from GitHub, Entra exchanges it for an Azure access token (authentication), and ARM checks the service principal’s Contributor assignment (authorization) before creating each resource.

Every idea from this lesson is in those four steps: a directory identity, a scoped role assignment, the authentication/authorization split, and secret-free credentials. Swap GitHub for an Azure VM and steps 1–2 collapse into a managed identity; the rest is identical.

Groups, deeper: dynamic rules and role-assignable groups

Dynamic groups replace manual membership with a rule evaluated automatically — for example (user.department -eq "Finance") adds every Finance hire to the group the moment their attribute is set, and removes them when they transfer. Dynamic membership requires Entra ID P1. The same engine powers group-based licensing (assign a licence to a group; members inherit it).

To assign an Entra directory role (not an Azure RBAC role) to a group, the group must be created as role-assignable (isAssignableToRole = true) — a special, immutable flag set at creation time. That lets you make, say, “IT Helpdesk” eligible for the Helpdesk Administrator directory role through PIM, instead of naming people one by one.

Administrative units: narrowing directory roles

By default an Entra role applies to the whole tenant. Administrative units (AUs) let you scope a directory role to a slice of the directory — for example, granting a regional admin User Administrator over only the users and groups in the “EMEA” AU, so they can reset passwords for their region but not for headquarters. AUs are the directory-side answer to “least privilege,” parallel to how RBAC scopes narrow resource access.

PIM: privilege you check out and hand back

Privileged Identity Management (PIM) turns standing admin rights into eligible rights. Instead of being a permanent Global Administrator, you are eligible to activate it: when you need it you request activation — optionally passing MFA, a business justification, and an approval step — and you hold the role for a time-boxed window (say two hours), after which it drops automatically. Every activation is logged. PIM covers both Entra directory roles and Azure RBAC roles (and role-assignable groups). It requires Entra ID P2 and is the backbone of just-in-time access; the mechanics get a full lesson later.

Licensing: what Free, P1, and P2 unlock

Every Azure subscription includes a Free tier of Entra ID (users, groups, security-group RBAC, SSO, basic MFA). The paid tiers add governance and protection:

Tier Representative capabilities it unlocks
Free Users, groups, RBAC, single sign-on, security-defaults MFA
Entra ID P1 Conditional Access, dynamic groups, group-based licensing, self-service password reset with writeback, Entra Connect Health
Entra ID P2 Everything in P1 plus PIM, Identity Protection (risk-based sign-in), and access reviews

P1/P2 are bundled into various Microsoft 365 plans (P1 with Microsoft 365 E3, P2 with E5), which is why many orgs already own them. Feature availability is gated by the licences assigned to the users who use the feature — not merely by what appears in the portal.

The Azure AD → Microsoft Entra ID rename

In 2023 Microsoft renamed Azure Active Directory to Microsoft Entra ID. It was a branding change, not a re-architecture — the service, APIs, and identifiers are identical. The practical facts to hold onto:

You will still hear “Azure AD,” “AAD,” and “the directory” in the wild — they all mean Entra ID.

Practice challenges

Six exercises, easy to hard. Try each before opening the solution. Commands use the az CLI in Cloud Shell; every GUID shown is a placeholder — substitute your own.

1. Read the sentence (beginner). Someone runs the command below. Say out loud who gets what where, and one thing this principal still cannot do.

az role assignment create \
  --assignee 11111111-1111-1111-1111-111111111111 \
  --role "Contributor" \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-app"

<details> <summary>Solution</summary>

The principal 1111… (a user, group, or service principal) is granted Contributor at the rg-app resource group. It can create, change, and delete resources in rg-app — but it cannot grant access to anyone else (no roleAssignments/write) and cannot touch resources in other resource groups. Why: every assignment is principal + role + scope, and Contributor deliberately lacks the manage-access permission. </details>

2. Find your own identity (beginner). Print your signed-in object ID and your tenant ID — the two GUIDs you paste into most identity commands.

<details> <summary>Solution</summary>

az ad signed-in-user show --query id --output tsv
az account show --query tenantId --output tsv

Why: --assignee expects an object ID, not your email address; the tenant ID identifies your directory when you script against more than one tenant. </details>

3. Grant yourself Reader at a resource group (intermediate). In a single command, give your own user the Reader role on a resource group named rg-lab, using command substitution so you never copy-paste a GUID.

<details> <summary>Solution</summary>

az role assignment create \
  --assignee "$(az ad signed-in-user show --query id -o tsv)" \
  --role "Reader" \
  --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/rg-lab"

Why: nesting az calls builds the who and part of the where dynamically — exactly how CI pipelines assemble scopes without hard-coded IDs. </details>

4. Diagnose surprise power (intermediate). You gave a colleague Reader on rg-lab, yet they just deleted a VM inside it. Nothing is broken — explain it, and give the command that reveals the real cause.

<details> <summary>Solution</summary>

They inherit Contributor or Owner from a higher scope (the subscription or a management group); RBAC is additive, so the broader grant wins. List assignments including inherited ones:

az role assignment list \
  --scope "/subscriptions/$(az account show --query id -o tsv)/resourceGroups/rg-lab" \
  --include-inherited \
  --query "[].{who:principalName, role:roleDefinitionName, scope:scope}" -o table

Why: effective access is the union of every assignment at and above the scope — a narrow Reader can never subtract an inherited Contributor. </details>

5. A custom role that can only restart VMs (advanced). No built-in role means “restart a VM and nothing else.” Write the JSON and the command to create it in your subscription.

<details> <summary>Solution</summary>

{
  "roleName": "VM Restart Operator",
  "description": "View and restart VMs; no create or delete.",
  "assignableScopes": ["/subscriptions/00000000-0000-0000-0000-000000000000"],
  "permissions": [{
    "actions": [
      "Microsoft.Compute/virtualMachines/read",
      "Microsoft.Compute/virtualMachines/instanceView/read",
      "Microsoft.Compute/virtualMachines/restart/action"
    ],
    "notActions": [], "dataActions": [], "notDataActions": []
  }]
}
az role definition create --role-definition ./vm-restart-operator.json

Why: custom roles exist precisely for “narrower than Contributor, broader than Reader” needs; /restart/action is the one operation that matters, and read lets the operator find the VM. </details>

6. Contributor still can’t read the blob (advanced). A teammate has Contributor on a storage account, but their app (using its Entra identity) gets AuthorizationPermissionMismatch when downloading a blob. Name the fix, and the reason Contributor wasn’t enough.

<details> <summary>Solution</summary>

Assign a data-plane role — Storage Blob Data Reader (or …Data Contributor to write) — at the storage-account or container scope:

az role assignment create \
  --assignee "<app-object-id>" \
  --role "Storage Blob Data Reader" \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-data/providers/Microsoft.Storage/storageAccounts/mystorage"

Why: Contributor grants control-plane Actions (manage the account) but no blob DataActions; reading blob content with an Entra identity needs a role whose name contains Data. (Contributor could instead fetch the account key and bypass RBAC — which is why you disable shared-key access on sensitive accounts.) </details>

Common beginner mistakes

These are misconceptions — wrong mental models — rather than error messages (those live in the troubleshooting table below).

Common mistakes & troubleshooting

Symptom Likely cause Fix
az ad group createAuthorization_RequestDenied Your tenant blocks non-admins from creating groups, or your user lacks the Entra role Ask an admin, or skip the group and assign the role to your own user: --assignee $(az ad signed-in-user show --query id -o tsv)
az role assignment createAuthorizationFailed You lack Owner / User Access Administrator at that scope (Contributor cannot grant access) Have an Owner run it, or get User Access Administrator on the RG
Assignment “succeeds” but the user still cannot act Token issued before the assignment; RBAC changes can take a few minutes to propagate Sign out/in to refresh the token, or wait a few minutes
--assignee errors with “directory object not found” You passed a display name where an object ID is expected, or hit replication lag Use the object ID (GUID); for a fresh principal add --assignee-object-id with --assignee-principal-type
Granted Reader but the user can still change things They also inherit Contributor/Owner from a higher scope (subscription or MG) List assignments and check all inherited scopes — inheritance is additive
Global Admin cannot see any subscriptions Entra roles ≠ Azure RBAC; directory power is not resource power Grant an Azure RBAC role at the needed scope

Best practices

Security notes

Identity is the real perimeter of a cloud estate, so treat these as non-negotiable. Protect every privileged account with phishing-resistant MFA, and gate admin sign-ins with Conditional Access. Keep Owner and Global Administrator counts minimal, and maintain two break-glass (emergency access) accounts that are excluded from Conditional Access but heavily monitored. For sensitive roles, use just-in-time elevation (PIM) instead of standing access, so privilege is granted for a window and logged. Finally, eliminate long-lived secrets wherever you can — managed identities and federated credentials remove the credential that attackers most want to steal.

Quick check

  1. What is the difference between a tenant and a subscription?
  2. State the three parts of every Azure RBAC role assignment.
  3. A user has Contributor at the subscription scope and Reader at a resource group inside it. What can they do in that resource group?
  4. Which built-in role can manage resources but cannot grant access to others?
  5. Does a Global Administrator automatically have access to Azure resources? Why or why not?

Answers

  1. A tenant is your Entra ID directory of identities (users, groups, apps); a subscription is a container for resources and the billing boundary. One tenant can be trusted by many subscriptions.
  2. Security principal (who) + role definition (what) + scope (where).
  3. They can manage (create/change/delete) resources there — the subscription-level Contributor inherits down and is additive, so it outranks the narrower Reader.
  4. Contributor — it has full management rights but lacks the permission to write role assignments.
  5. No. Global Administrator is an Entra (directory) role; access to Azure resources requires an Azure RBAC role at the relevant scope. The two systems are separate.

Exercise

Imagine a small team: a data analyst who needs to read one project’s resources, and a developer who builds the same project. Create a resource group rg-team-lab, plus two security groups (team-readers, team-builders). Assign Reader to team-readers and Contributor to team-builders, both scoped to rg-team-lab. Verify with az role assignment list, then write one sentence explaining why neither group should be scoped at the subscription level. Tear it all down with the cleanup commands when done.

Interview questions

  1. What is the difference between authentication and authorization in Azure, and which service handles each? Authentication proves who you are and is handled by Microsoft Entra ID, which issues a token. Authorization decides what you may do and is handled by Azure RBAC, which Azure Resource Manager evaluates against your role assignments.

  2. Explain RBAC scope inheritance. Roles are assigned at management group, subscription, resource group, or resource scope, and a role assigned at a higher level flows down to everything beneath it. Inheritance is additive, so effective access is the sum of all assignments at and above a given scope.

  3. Owner vs Contributor — what is the practical difference? Both can fully manage resources, but only Owner can manage access (write role assignments). You default to Contributor so engineers can build without being able to escalate privileges for themselves or others.

  4. Entra roles vs Azure RBAC roles? Entra roles (e.g. Global Administrator) govern the directory — users, groups, app registrations. Azure RBAC roles (e.g. Owner, Reader) govern Azure resources. They are independent: directory power is not resource power.

  5. Service principal vs managed identity — when would you use each? A service principal is an app’s identity that typically carries a secret/certificate you must manage. A managed identity is a service principal that Azure creates and rotates for you with no stored secret. For workloads running in Azure, prefer a managed identity; use an app registration with federated credentials for external systems like GitHub Actions.

  6. How do you apply least privilege with RBAC? Assign the lowest-privilege role at the smallest scope that still gets the job done — for example Reader on one resource group instead of Contributor on the subscription — assign to groups for manageability, and use just-in-time (PIM) elevation for high-risk, occasional access.

Certification mapping

Exam Objective area this supports
AZ-900 (Azure Fundamentals) Describe Azure identity, access, and security — Entra ID, MFA/Conditional Access concepts, and Azure RBAC.
AZ-104 (Azure Administrator) Manage identities and governance — manage Entra users and groups, and manage access to Azure resources via built-in roles and role assignments at the correct scope.

Glossary

Next steps

Continue the Identity module with Identity & Access Management for an Azure Landing Zone — how these primitives become an enterprise identity baseline. Then go deeper with:

AzureEntra IDRBACIdentitySecurity
Need this built for real?

Vinod is a Senior Cloud Architect (22+ yrs) — available for Azure / AWS / GCP architecture, landing zones, and migrations.

Work with me

Comments