Lab Setup
Complete these steps before starting the exercise to deploy the resources and seed the role assignment used by the access review scenario:
-
Open the Azure portal at
https://portal.azure.comand sign in with User1. -
Select the Cloud Shell icon (>_) in the portal top bar. If prompted, select Bash.
-
Copy the username provided for User3. In Cloud Shell, replace
<User3-UPN>with that username and run:az ad user show --id '<User3-UPN>' --query id --output tsv -
Copy the returned object ID. You will provide it to the deployment template.
-
Register the Microsoft.PolicyInsights resource provider required for on-demand policy scans:
az provider register --namespace Microsoft.PolicyInsights --wait az provider show --namespace Microsoft.PolicyInsights --query registrationState -o tsvConfirm the output is
Registeredbefore continuing. -
In the portal search bar, find and open Deploy a custom template.
-
Select Build your own template in the editor, then select Load file.
-
Select 1D-lab-env.json from the F:\AllFiles\Lab-1D folder on the lab VM, then select Save.
-
On the deployment page, configure the following values:
Setting Value Region East US, unless your lab environment recommends another region | User3 Object ID | Paste the object ID returned by the Cloud Shell command |
-
Select Review + create, then select Create.
Note: Deployment normally completes in under two minutes. It creates
sc500-lab1d-rg, an untagged storage account and virtual network for policy evaluation, and an explicit Contributor assignment for User3 on the lab subscription. -
When deployment succeeds, close Cloud Shell and continue to the exercise.
===
Configure Azure Policy and Role-Based Access Control
A compliance audit of your organization's AI platform environment has identified two governance gaps. First, no policy exists to enforce required resource tagging — resources in the subscription have no consistent Environment tag, making cost allocation and security boundary tracking unreliable. Second, a team member who moved off the AI platform team nine months ago still holds a standing Contributor assignment on the lab subscription, giving them full management access to resources they no longer work with.
Your task is to close both gaps. You will assign a built-in tagging policy to surface non-compliant resources, then deploy a custom policy via Infrastructure as Code to extend tag enforcement to resource groups. You will create a scoped custom role for security reviewers — granting read access to Defender for Cloud posture data and role assignments without elevating them to administrators — and then use an Entra ID Access Review to formally evaluate and remove the unnecessary Contributor access. Finally, you will apply a resource lock to protect the platform's storage account from accidental deletion.
In this lab, you will:
- Assign a built-in Azure Policy and review policy compliance results
- Deploy a custom tag-enforcement policy definition via Bicep using Cloud Shell
- Create a custom Azure role and assign it to a designated security reviewer
- Evaluate and remediate an overprivileged role assignment using an Entra ID Access Review
- Apply a CanNotDelete resource lock and verify it prevents deletion
This exercise should take approximately 60 minutes to complete.
Note: This lab uses the provided account aliases and baseline subscription permissions: User1 has owner-level access, User2 has contributor-level access, and User3 has read-only access. The Lab Setup deployment adds a built-in Contributor assignment for User3 on the lab subscription; the access review removes that assignment while preserving User3's baseline read-only access. Use the credentials provided for all three accounts.
Assign a built-in compliance policy
Azure Policy evaluates resources against defined rules and reports compliance without requiring changes to existing resources. A Deny effect policy blocks new non-compliant resources from being created; existing resources that already violate the policy appear as Non-compliant in the compliance report. You will assign the built-in Require a tag on resources policy to sc500-lab1d-rg, which will flag the pre-provisioned storage account (name starts with sc500lab1d) and sc500-lab1d-vnet virtual network as non-compliant because neither resource has an Environment tag.
-
Sign in to the Azure portal
https://portal.azure.comusing your User1 credentials. -
In the search bar, search for and select
Policy. -
In the left menu, under Authoring, select Assignments.
-
Select Assign policy.
-
On the Basics tab, configure the following:
Setting Value Scope Select the ellipsis (...), then select your subscription and sc500-lab1d-rg as the resource group. Select Select. Exclusions Leave blank Policy definition Select the ellipsis (...), search for Require a tag on resources, select the result, then select Add.Assignment name sc500-require-env-tag Policy enforcement Enabled -
Select the Parameters tab.
-
In the Tag Name field, enter
Environment. -
Select Review + create, then select Create.
Note: Policy assignments can take up to 30 minutes to fully propagate before compliance evaluation reflects the new assignment. You will trigger an on-demand scan in the next step rather than waiting.
-
Select the Cloud Shell icon (>_) in the Azure portal top bar. If prompted to select a shell type, select Bash. On the Getting started page, select No storage account required, select the lab subscription, and then select Apply.
-
Run the following command to trigger an on-demand compliance evaluation for the resource group:
az policy state trigger-scan --resource-group sc500-lab1d-rgThe command displays an IN-PROGRESS indicator while the scan runs and returns your Bash prompt only when the scan is complete. This typically takes 5+ minutes but can take longer depending on subscription load. You don't need to wait for the Scan to finish. Wait a minute or two, then proceed to the next Note and Steps.
Note: If the compliance state still shows Not started or 0 non-compliant resources after the command completes, wait 2–3 additional minutes and select Refresh in the portal. Compliance state updates are written asynchronously after the scan finishes.
-
In the Azure portal, return to Policy and select Compliance from the left menu.
-
In the scope filter at the top of the page, select
sc500-lab1d-rgto narrow results to this resource group. -
Locate the sc500-require-env-tag assignment in the compliance list.
-
Confirm that the storage account (name starts with
sc500lab1d) and sc500-lab1d-vnet virtual network appear in the non-compliant resources list.Note: Both resources were deployed without an
Environmenttag and therefore violate the policy. The policy assignment also prevents any future resource deployments insc500-lab1d-rgfrom omitting theEnvironmenttag. Existing resources remain operational — compliance evaluation is non-destructive.
Deploy a custom policy using Infrastructure as Code
The built-in policy you assigned enforces tag requirements on individual resources. A complementary policy at the resource group level ensures that any new resource groups created in the subscription are also tagged from the start. Rather than configuring this policy in the portal, you will deploy a pre-written Bicep template that defines and assigns the custom policy at the subscription scope. Deploying governance policy through Infrastructure as Code ensures it is version-controlled, repeatable, and auditable.
The sc500-lab1d-policy.bicep file is provided in the F:\AllFiles\Lab-1D folder. It defines a custom Deny policy that requires an Environment tag on all resource groups and creates a subscription-scope assignment.
-
Open a Cloud Shell (Bash), if it is not already open.
-
Select the Manage file button in the menu at the top of your Bash window.
-
Select Upload.
-
Browse to the F:\AllFiles\Lab-1D folder on the lab VM, then select sc500-lab1d-policy.bicep file.
-
Select Open to upload the file. Wait for the Successfully uploaded file message.
-
In the Cloud Shell (Bash) session, run the following command to deploy the custom policy to the subscription scope:
az deployment sub create \ --name sc500-tag-policy \ --location eastus \ --template-file ~/sc500-lab1d-policy.bicepThe deployment typically completes in under one minute. A JSON output block appears in the terminal when it succeeds.
Note: The
--location eastusflag specifies the region for the deployment metadata record, not where resources are created. Subscription-scope Bicep deployments must specify a location for the ARM metadata even when the resources they create (like policy definitions) are globally scoped. -
In the Azure portal, navigate to Policy and select Definitions from the left menu.
-
In the Type filter, select Custom.
Confirm that a custom policy definition for requiring a Require Environment tag on resource groups policy appears in the list. This is the definition deployed by the Bicep template.
Note: This step demonstrates the Infrastructure as Code approach to policy governance. The same Bicep template can be committed to a repository, reviewed through a pull request, and deployed consistently across multiple environments — ensuring that governance rules are applied uniformly without relying on manual portal configuration.
-
Select Assignments from the left menu.
Confirm that an assignment for the custom tag policy appears in the list, scoped to your subscription. The Bicep template deployed both the policy definition and the assignment in a single operation.
-
Close the Cloud Shell.
Create a custom security reviewer role
Built-in Azure roles such as Reader grant broad read access across all resource types in a scope. When a role is needed for a specific governance function — such as reviewing Defender for Cloud security posture data and role assignments — a custom role with the minimum required permissions is a better fit. You will create a role named sc500-Security-Reviewer that grants read access to Microsoft Defender for Cloud data and Azure authorization objects only, then assign it to User2.
-
In the Azure portal search bar, search for and select Resource groups.
-
Select sc500-lab1d-rg.
-
In the left menu, select Access control (IAM).
-
Select + Add, then select Add custom role.
-
On the Basics tab, configure the following:
Setting Value Custom role name sc500-Security-ReviewerDescription Read-only access to Defender for Cloud security posture data and role assignments. Scoped to the sc500-lab1d-rg resource group.Baseline permissions Start from scratch -
Select Next to proceed to the Permissions tab.
Note: The Permissions tab provides a searchable card-based interface for adding individual operations. Adding wildcard permissions — such as
Microsoft.Security/*/read— requires editing the role's JSON directly, which you will do on the JSON tab. -
Select Next to proceed to the Assignable scopes tab.
Confirm that sc500-lab1d-rg is listed as an assignable scope. Because you opened the custom role wizard from the resource group's IAM page, the scope is pre-populated. If it is not listed, select Add assignable scopes, expand your subscription, select sc500-lab1d-rg, then select Add.
-
Select Next to proceed to the JSON tab.
-
Select Edit to open the JSON editor.
-
Locate the
"actions": []line inside the"permissions"array. Replace the empty array with the following:"actions": [ "Microsoft.Security/*/read", "Microsoft.Authorization/*/read" ],The completed
"permissions"block should look like this:"permissions": [ { "actions": [ "Microsoft.Security/*/read", "Microsoft.Authorization/*/read" ], "notActions": [], "dataActions": [], "notDataActions": [] } ]Note:
Microsoft.Security/*/readgrants read access to all Defender for Cloud and Azure Security Center data — security assessments, recommendations, alerts, and secure score.Microsoft.Authorization/*/readgrants read access to all role assignments, policy assignments, and role definitions, which allows the reviewer to audit who has access to what without having any write or delete permissions. -
Select Save to apply the JSON changes.
-
Select Review + create, then select Create.
Wait for the custom role to be created. This typically takes a few seconds.
-
On the Access control (IAM) page for
sc500-lab1d-rg, select + Add, then select Add role assignment. -
On the Role tab, select Custom roles from the Type filter dropdown, then select sc500-Security-Reviewer. Select Next.
-
On the Members tab, confirm Assign access to is set to User, group, or service principal.
-
Select + Select members, search for and select User2, then select Select.
-
Select Review + assign, then select Review + assign again to save.
Note: The
sc500-Security-Reviewerrole itself grants only the defined read permissions. In this lab environment, User2 also has baseline contributor-level access on the subscription, so User2's effective permissions are broader than this custom role. The exercise demonstrates custom-role definition and assignment; in production, assign this role to a principal without a broader inherited role. User2 is also the designated reviewer in the next section.
Evaluate and remediate overprivileged access
User3 holds an active Contributor role assignment directly on the lab subscription. The Contributor role grants full management access—the ability to create, modify, and delete resources—without permission to manage role assignments. User3 no longer has a business need for this access.
A Microsoft Entra access review provides a structured, auditable process for deciding whether an existing role assignment remains appropriate. You will verify the seeded assignment, onboard the lab subscription to Privileged Identity Management (PIM), designate User2 as the reviewer, submit a denial, and confirm that the Contributor assignment is removed. If the tenant does not include the required ID Governance capability, you will use the direct-remediation fallback instead.
-
In the Azure portal, search for and select Subscriptions, and then select the subscription used for this lab.
-
Select Access control (IAM), and then select the Role assignments tab.
-
Search for User3 and confirm that User3 has both the Contributor assignment and a baseline read-only assignment with scope This resource.
Important: If the Contributor assignment is missing, stop here. The Lab Setup deployment did not receive the correct User3 Object ID, and there is no assignment to review. This is a setup issue, not role-assignment propagation.
-
Navigate to the Microsoft Entra admin center.
-
In the portal search bar, search for Privileged Identity Management, and then select Privileged Identity Management Browse.
-
On the Browse page, under Subscriptions, select the lab subscription.
-
Confirm the Current selection shows the lab subscription, and then select Manage resource.
Note: Onboarding opens the subscription's PIM overview and grants the PIM service principal the access it needs to manage privileged assignments.
-
Under Manage, select Access reviews.
Important: Azure resource role access reviews require Microsoft Entra ID P2 or Microsoft Entra ID Governance. The user creating the review must also have Owner or User Access Administrator permissions. In this lab, User1 has the required subscription permissions. If the page displays You don't have access, waiting for role propagation will not resolve the message. Skip to Fallback: remove the assignment directly.
Create and complete the access review
Complete this subsection only if the Access reviews page opens successfully.
-
Select New.
-
On the Create an access review page, configure the review details:
Setting Value Review name sc500-contributor-reviewDescription Review of Contributor access on the lab subscriptionStart date Today's date Frequency One time Duration (in days) 3 -
Under Users scope, select Users.
-
Under Review role membership, select Contributor.
-
For Assignment type, select Active assignments only.
-
Under Reviewers, select Selected user(s) or group(s), and then select Select reviewers.
-
Select User2, and then confirm the selection.
Important: If the Select reviewers pane remains blank after 10 seconds, close the pane and skip to Fallback: remove the assignment directly. This is a hosted-tenant picker issue; waiting for role propagation does not populate the pane.
-
Expand Upon completion settings and configure:
Setting Value Auto apply results to resource Enable If reviewers don't respond No change -
Select Start to create and activate the access review.
-
Open a new InPrivate or Private browser window and sign in to
https://entra.microsoft.comusing the credentials provided for User2. -
Browse to ID Governance > Privileged Identity Management > Review access.
-
Select sc500-contributor-review. Select the entry for User3, choose Deny, enter
No current business need for Contributor accessas the reason, and submit the decision. -
Close the InPrivate window and return to the User1 session.
-
Return to Privileged Identity Management Browse, select the lab subscription, select Manage resource, and then select Access reviews.
-
Select sc500-contributor-review, select Stop, and confirm the action.
-
Refresh the review until its status changes from Completed or Applying to Applied. This normally takes a few minutes.
-
Skip to Verify the remediation.
Fallback: remove the assignment directly
Complete this subsection if the Access reviews page displays You don't have access or if the Select reviewers pane is blank.
-
Return to the lab subscription in the Azure portal.
-
Select Access control (IAM) > Role assignments.
-
Search for User3, select the selection box for the Contributor assignment with scope This resource, and then select Delete on the command bar. Confirm the deletion.
Note: Direct removal remediates the overprivileged access but does not create the access-review audit record. In production, enable the required Microsoft Entra ID Governance licensing and use recurring access reviews for formal access certification.
Verify the remediation
-
In the lab subscription, return to Access control (IAM) > Role assignments. Refresh the page and search for User3.
-
Confirm that User3 no longer has the Contributor role. The baseline read-only assignment remains and is expected.
Note: If you completed the access-review path, the completed review preserves an auditable, timestamped record of the reviewer, decision, justification, and resulting access change.
Apply a resource lock
Resource locks prevent accidental or unauthorized deletion of critical resources. A CanNotDelete lock allows all read and write operations on a resource but blocks delete operations — even for users with the Owner role. You will apply a lock to the pre-provisioned storage account in sc500-lab1d-rg and verify that the lock prevents deletion.
Note: The
sc500-lab1d-rgresource group contains exactly one storage account, and its name begins withsc500lab1dfollowed by an 8-character suffix unique to your lab subscription. Select it whenever the lab refers to it.
-
In the Azure portal search bar, search for and select Storage accounts.
-
Select the storage account whose name starts with
sc500lab1d(there is only one insc500-lab1d-rg). -
In the left menu, under Settings, select Locks.
-
Select + Add.
-
Configure the following:
Setting Value Lock name sc500-storage-lockLock type Delete Notes Prevents accidental deletion of the AI platform storage account. -
Select OK.
-
In the left menu, select Overview.
-
Select Delete.
-
In the confirmation dialog, type the storage account name to confirm, then select Delete.
Confirm that an error message appears indicating the resource is locked and cannot be deleted:
Note: The
CanNotDeletelock is enforced by Azure Resource Manager regardless of the requestor's role. An Owner or subscription administrator cannot delete this resource while the lock is in place — you must explicitly remove the lock first. This creates deliberate friction that prevents automated scripts or misconfigured pipelines from destroying critical resources.ReadOnlylocks are stricter: they block all write and delete operations, but can interfere with platform operations that legitimately need to update resource metadata.CanNotDeleteis the recommended choice for most production resource protection scenarios. -
Close the delete confirmation dialog.
Summary
In this lab, you applied governance controls across four dimensions: policy compliance, Infrastructure as Code policy deployment, custom role creation, and access certification.
You assigned the built-in Require a tag on resources policy to surface existing non-compliant resources missing an Environment tag, and triggered an on-demand compliance scan to observe results immediately rather than waiting for the standard evaluation cycle. You then deployed a complementary custom policy at the subscription scope using a pre-written Bicep template — demonstrating that governance rules, like application code, can be version-controlled and deployed repeatably through Infrastructure as Code.
You created a custom Azure role — sc500-Security-Reviewer — whose definition contains only the read permissions needed for a security auditor function. You assigned it to User2 and distinguished the permissions granted by the custom role from User2's broader baseline contributor-level access on the lab subscription.
Where the tenant supported Entra ID Governance, you used an Entra ID Access Review to formally evaluate User3's standing Contributor assignment. That review path created an auditable record of the reviewer, justification, decision, and resulting action. Where access reviews were unavailable, you used Azure RBAC to remove the assignment directly and documented why formal access certification requires the additional governance capability. Finally, you applied a CanNotDelete resource lock to the platform storage account, demonstrating that identity-based access control and resource locks serve complementary functions: access control governs who can act, while locks create an explicit barrier that even highly privileged identities cannot bypass without a deliberate removal step.
You have successfully completed this exercise.
Clean up
The lab environment is automatically reset at the end of the session. No manual resource deletion is required.