top of page
Sep 22
8 min read

Updated: Sep 23

azure administrator series


Lab 01 — Scoped Azure RBAC: Assign, Diagnose, and Recover


Lab 01 — Scoped Azure RBAC. Right role. Wrong scope. azure administrator series.

An application can authenticate successfully and still be unable to read an Azure resource. In this first Azure Workshopz lab, you will give a managed identity Reader access, prove the boundary, diagnose a scope mistake, and restore access using Azure CLI, native Azure PowerShell, and the Azure Portal.


The task is deliberately small: read a resource group and its storage-account metadata, but do not change either. That makes the relationship between identity, role, and scope visible without building an application stack first.



1. What you will learn


By the end, you will be able to identify the three parts of an Azure role assignment, distinguish direct from inherited access, diagnose a wrong-scope assignment, and prove the result with requests made by the affected identity.


This lab maps to these AZ-104 objectives: manage built-in Azure roles; assign roles at different scopes; interpret access assignments; and manage resource groups. It is an independent community workshop.


Level: foundational administrator. Allow 90–120 minutes, including propagation and investigation. The scripts target West Europe and use PowerShell 7 as the local shell. Azure CLI performs setup; native Azure PowerShell performs inspection and repair; the Portal provides visual checkpoints.


2. Before you start: access, cost, and context


Install PowerShell 7.2+, Azure CLI, Az.Accounts, and Az.Resources. Use an enabled subscription where you can create a resource group and resources and manage role assignments at that scope. Contributor alone does not permit assigning Reader. Owner, or suitable resource and RBAC administration permissions, must cover the lab operation. Delegation conditions can further restrict the permitted principals or roles.


The normal run targets less than EUR 0.50. Preflight fetches current West Europe retail prices in EUR and calculates six hours of one sequential 1-vCPU/1-GB probe plus a EUR 0.05 storage contingency. This is a planning estimate, not a bill or a spending cap. Your offer may differ. Expiry tags do not delete resources. Finish the exercise after five hours at the latest and clean up before six hours.


The lab creates one resource group, one user-assigned managed identity, one Standard_LRS storage account, and one short-lived ACI probe per test phase. It uses no VM, public inbound endpoint, application secret, or blob data. The storage public network endpoint is disabled; all storage checks are management-plane metadata reads through Azure Resource Manager.


Sign in to both command tools and choose the same subscription. These commands run in PowerShell 7:


az login
az account set --subscription 'YOUR SUBSCRIPTION NAME'
Connect-AzAccount
Set-AzContext -Subscription 'YOUR SUBSCRIPTION NAME'

The Portal must use the same directory. Keep account IDs, tokens, private state, and unredacted logs out of shared screenshots and downloads.


3. Understand the boundary


Azure RBAC joins a principal, a role definition, and a scope. In this lab the principal is a managed identity, the role is Reader, and the intended scope is the lab resource group. An assignment at that group also applies to child resources. An assignment on one storage account does not grant access to its parent resource group.


Azure RBAC roles govern Azure resources. Microsoft Entra directory roles govern directory administration. Granting Reader here does not make the managed identity a directory administrator.


Administrator: creates and manages the disposable lab
    Resource group
        Managed identity ← used by short-lived ACI probe
        Storage account  ← management metadata only
        Reader assignment → intended scope: resource group

Probe identity → ARM read group: allowed
Probe identity → ARM read storage: allowed
Probe identity → ARM write tag: denied

4. Run preflight and create the lab


Extract the bundle and open PowerShell in its folder. Put the run manifest outside the extracted download. It contains the exact resource and assignment IDs required for recovery and cleanup; do not publish it.


$state = Join-Path (Split-Path $PWD -Parent) 'lab01-private/state.json'
./Start-Az104Lab01.ps1 -StatePath $state -Stage Preflight -SubscriptionName 'YOUR SUBSCRIPTION NAME'

Preflight performs no Azure writes. It checks that both contexts match, required providers are registered, and the current price estimate is within the lab target. Azure Policy, available quota, and regional capacity can still reject a deployment; the state file makes partial cleanup possible. Resolve an unregistered provider deliberately rather than hiding registration in preflight.


Deploy the healthy environment:


./Start-Az104Lab01.ps1 -StatePath $state -Stage Deploy -SubscriptionName 'YOUR SUBSCRIPTION NAME' -Execute -AcknowledgeCost

Every resource name contains a new run suffix, and supported resources carry Lab, RunId, and expiry tags. An existing state file is not silently reused for a second deployment. To continue this run, use its stage scripts. To start another, clean up this run and choose a new state path.


Here are the core CLI operations used inside setup, shown for explanation. The deployment script has already executed them; do not run this excerpt again:


az group create --name $rg --location westeurope --tags Lab=az104-01-scoped-rbac RunId=$run
az identity create --name $identityName --resource-group $rg --location westeurope
az role definition list --name $readerRoleId
az role assignment create --assignee-object-id $principalId --assignee-principal-type ServicePrincipal --role $readerRoleId --scope $resourceGroupId

Using the principal object ID avoids a name lookup in Microsoft Graph. Explicit ServicePrincipal type helps when the managed identity is newly created. The implementation resolves the Reader role ID and stores the resulting assignment ID before fault injection.


5. Portal checkpoint: direct and inherited Reader


Open Resource groups and search for the exact name reported by setup. Confirm that it contains the identity and storage account and that the ownership tags match the run.


Open the group's Access control (IAM), choose Role assignments, and filter for the lab identity. Reader should be assigned at this resource-group scope. Then open the storage account's Access control (IAM) and find the same identity. Its group-level Reader is inherited by the storage account.


The Portal is showing the assignment, but you are still signed in as the administrator. Your ability to open a blade is not proof that the managed identity can access it. The next stage tests as the actual application identity.


Genuine Azure Portal capture: disposable lab resource inventory.

Live validation: the isolated lab resource inventory. Cropped to exclude account details.


6. Prove the healthy baseline


./Test-Az104Lab01.ps1 -StatePath $state -Phase Baseline -Execute

The test runner creates an ACI group with the managed identity and no inbound IP configuration. The container requests a managed-identity token internally, calls ARM, writes only status codes and sanitized error codes, and exits. Credentials and response bodies are never printed.


The required outcomes are resource-group metadata HTTP 200, storage metadata HTTP 200, and tag write HTTP 403 with AuthorizationFailed. A successful read alone would not establish the tested write boundary. The tag attempt is a harmless lab-only marker, so even an unexpected permission error cannot alter production data.


Each phase uses a new execution marker. Bounded retries allow authorization changes to converge. A new token or container does not promise instant propagation. A sign-in error, network failure, or image-pull failure is not an acceptable substitute for an authorization denial.


7. Troubleshooting challenge


Once Baseline passes, introduce the prepared lab fault and run the affected application's checks:


./Set-Az104Lab01Fault.ps1 -StatePath $state -Execute
./Test-Az104Lab01.ps1 -StatePath $state -Phase Fault -Execute

The identity previously read the resource group. Now a new execution returns an authorization failure for that group, although authentication works and one resource remains readable. Diagnose why the outcomes differ. Restore only the access required by the resource-group inventory task and prove that writing is still denied.


Before reading the solution, write down the failed action, the target scope, and your hypothesis. Inspect Access control (IAM) at both the group and storage resource. Capture what changed in the assignment's scope and inheritance.


Resource-group IAM filtered to the lab identity during the wrong-scope fault: no results.

Fault checkpoint: the resource-group IAM list has no assignment covering the lab identity.


Use Azure CLI to inspect the affected principal. Keep the resulting private identifiers out of public evidence:


$s = Get-Content -LiteralPath $state -Raw | ConvertFrom-Json
az role assignment list --assignee-object-id $s.PrincipalId --all --include-inherited --query '[].{role:roleDefinitionName,scope:scope}' -o table

Then compare with native Azure PowerShell:


Get-AzRoleAssignment -ObjectId $s.PrincipalId |
    Select-Object RoleDefinitionName, Scope

Both tools should describe the same assignment. A blank display name can be a directory lookup limitation; inspect the recorded principal ID and assignment fields rather than assuming the identity was deleted.


8. Hints — use one at a time


  1. Separate authentication from authorization. Which step succeeded?

  2. Compare the group metadata request with the storage metadata request. Neither is a blob download.

  3. Inspect the assignment Scope column and whether it is direct or inherited at each level.

  4. Permissions flow down from a parent scope. Does the current assignment cover the failed request's parent resource group?


9. Solution and native PowerShell repair


The fault removed the run's resource-group Reader assignment and created Reader on only the storage account. The role name is still correct, but its scope is too narrow for the application task. The storage metadata read remains authorized; the parent group read is not.


Restore Reader at the original resource-group scope. Do not grant Contributor or Owner and do not broaden the assignment to the subscription.


./Restore-Az104Lab01.ps1 -StatePath $state -Execute
./Test-Az104Lab01.ps1 -StatePath $state -Phase Recovery -Execute

The repair script uses native Azure PowerShell. This excerpt explains the essential operation; the script has already performed it and retained the returned assignment ID:


New-AzRoleAssignment -ObjectId $s.PrincipalId -ObjectType ServicePrincipal -RoleDefinitionId $s.ReaderId -Scope $s.ResourceGroupId

The script finds and removes only the saved fault assignment. Recovery is complete when a new probe reads both metadata targets and its tag write is still denied. The script retains enough state to retry restoration after an interrupted run.


Recovery IAM row: managed identity, Reader, this resource.

Recovery checkpoint: Reader is back at the resource-group scope. This crop excludes private object identifiers.


10. Expected proof and release evidence


Request as the managed identity

Baseline

Fault

Recovery

Read resource-group metadata

200

403

200

Read storage-account metadata

200

200

200

Write a tag

403

403

403


The release's actual observations, timestamps, tested tool versions, and cleanup status are recorded in live-test-report.md and evidence/live-results.json in the bundle. A phase passes only when it produces its own expected status and error codes. The expected table above is not a substitute for those results.


11. Troubleshooting reference


Symptom

Check

Response

CLI and PowerShell disagree

Tenant/subscription context

Align both contexts before changing assignments

Role assignment creation is denied

RBAC write permission and delegation conditions

Have the appropriate administrator supply the required lab-scope access

PrincipalNotFound just after identity creation

Principal ID and replication

Use explicit ServicePrincipal type and bounded retries

Read still works immediately after removal

Authorization propagation

Wait within the bounded test window and preserve timestamps

ACI does not start

Regional capacity, quota, image and container events

Treat as an infrastructure failure; stop and clean up

Removal refuses an extra resource

Manifest and ownership tags

Inspect the unexpected item; never broaden deletion to a name prefix


12. Clean up and prove absence


Preview the exact cleanup boundary, then execute it:


./Remove-Az104Lab01.ps1 -StatePath $state
./Remove-Az104Lab01.ps1 -StatePath $state -Execute
./Get-Az104Lab01Evidence.ps1 -StatePath $state -OutputDirectory './my-evidence'

Cleanup checks ownership, removes recorded role assignments before removing the identity, deletes the recorded resource group, waits for its absence, and searches for resources tagged with the exact RunId and remaining assignments for the probe principal. It retains private state for audit. A deletion still in progress is not a clean result.


If you abandon the exercise during the fault, run the cleanup command with the original state file. It can remove the disposable lab directly; it does not need to restore access just to delete the environment. In the Portal, refresh Resource groups and confirm that the exact lab group no longer appears.


13. Apply the lesson in administration


Start with the operation the application needs and choose the smallest scope that covers it. Reader on a storage account is appropriate for inspecting that account; Reader on the group is appropriate for this group's inventory task. The answer depends on the required boundary, not on making the error disappear.


In an organization, separate human administration from workload identity, review inherited assignments, and use groups and eligible privileged access where appropriate. Those are production design topics beyond this small exercise. The managed identity here receives no secret and no storage data role.


14. Knowledge check


  1. Which three elements define a role assignment?

  2. Why does Contributor not necessarily permit assigning Reader?

  3. Can Reader on one storage account authorize its parent group read?

  4. Does management Reader permit downloading blobs?

  5. Why use a separate identity for the probe?

  6. Why repeat the denied-write test after recovery?

  7. Does a new container guarantee immediate RBAC propagation?

  8. Which observations prove cleanup?


Answers: principal/role/scope; role-assignment administration is a separate permission; child permissions do not flow upward; management access is distinct from data access; the administrator's broad access could mask the fault; recovery must preserve the tested write boundary; authorization caches can still delay convergence; and the group, tagged resources, and principal assignments must all be absent. Detailed explanations are included in the bundle.


References and series navigation





Next in the azure administrator series: Lab 02 — Microsoft Entra Identity Lifecycle

 
 
 

Comments


bottom of page