SC-500 Azure Governance: Policy, Defender for Cloud Compliance, Locks, RBAC and Backup Security
Azure governance for security is the set of controls that make secure configuration the default and keep it that way: Azure Policy to enforce and remediate settings, Microsoft Defender for Cloud to measure posture against security and regulatory standards, resource locks and deployment stacks to stop destructive changes, Azure RBAC and custom roles to keep access least-privilege, and Azure Backup's soft delete, immutability and multi-user authorization to keep recovery possible. This lesson covers SC-500 task 1.3: how each control behaves, where the near-identical options differ, and how to pick the one a requirement actually calls for.
On this page10 sections
- Azure Policy effects: which one fits the requirement
- Remediating existing resources with remediation tasks
- Writing a custom policy definition
- Exemptions versus exclusions
- Regulatory compliance, standards and recommendations in Defender for Cloud
- Resource locks: CanNotDelete and ReadOnly
- Built-in role assignments, least privilege and overprivileged access
- Custom roles: Azure RBAC and Microsoft Entra
- Backup protection: soft delete, immutability and multi-user authorization
- Security controls in infrastructure as code
- Choose the Azure Policy effect (deny, modify, append, audit, auditIfNotExists, deployIfNotExists, denyAction) that matches a requirement, and remediate existing resources with remediation tasks and the right managed identity permissions.
- Write custom policy definitions with aliases, the correct mode and an existenceCondition, and choose between exemptions (Waiver or Mitigated) and exclusions.
- Assign regulatory compliance standards and create custom standards and recommendations in Microsoft Defender for Cloud, and interpret the compliance dashboard.
- Apply CanNotDelete and ReadOnly resource locks and predict what they block.
- Assign built-in roles with least privilege, delegate role assignment with conditions, create Azure and Microsoft Entra custom roles, and right-size overprivileged access with Defender CSPM.
- Protect backups with soft delete, immutable vaults and multi-user authorization, and secure infrastructure as code with Microsoft Security DevOps scanning and deployment stack deny settings.
Azure Policy effects: which one fits the requirement
Choose the effect from what the requirement wants to happen to a non-compliant request: deny rejects it, modify fixes it on the way in, audit lets it through and reports it, and deployIfNotExists adds a missing related resource after the fact. The effect lives in the definition's then block, and is often a parameter so the same definition can be assigned in audit mode first and enforced later.
| Effect | What it does | When it acts |
|---|---|---|
| disabled | Turns the rule off for this assignment | Checked first |
| append | Adds fields to the request, such as extra entries in an array | During the create/update request |
| modify | Adds, replaces or removes tags and properties that have a modifiable alias | During the request, before deny |
| deny | Fails the create or update with a 403 error | During the request |
| audit | Allows the request, marks the resource non-compliant and logs a warning | During the request and in compliance scans |
| auditIfNotExists | Flags the resource when a related resource (such as a diagnostic setting) is missing | After the request succeeds |
| deployIfNotExists | Deploys a template to create the missing related resource | After the request succeeds |
| denyAction | Blocks DELETE calls on matching resources | During a delete request |
Two near-twins decide many scenarios. Deny versus modify: both guarantee the end state, but deny does it by failing the deployment, while modify rewrites the request so it succeeds with the secure value. If existing templates must keep working unchanged, modify is the fit; if engineers must see an error at deploy time, deny is. Because modify runs before deny, a request can be corrected before deny ever evaluates it. Deny versus denyAction: deny only evaluates create and update requests and never sees a DELETE. To stop deletions at scale, use denyAction with actionNames set to delete; its cascadeBehaviors setting for resourceGroup (default deny, and available only in Indexed mode) also blocks deleting a resource group that holds a matching resource. Assigned at a management group, it cannot be edited or removed by subscription Owners, although anyone with exemption rights at a lower scope can still exempt resources, so those rights need governing too.
Policy is a guardrail, not a replacement for a resource lock or a role: a ReadOnly lock blocks every write to a scope, while a deny policy blocks only the requests its rule matches.
Remediating existing resources with remediation tasks
Resources that existed before an assignment are only reported, never changed, until you run a remediation task. Azure Policy applies modify during new create or update requests and deployIfNotExists after they succeed, so new resources are fixed automatically while existing ones simply show as non-compliant. A compliance scan refreshes that report but deploys nothing, and switching enforcement mode does not reach existing resources either.
- Only two effects support remediation:
modify(it carries operations on tags or properties) anddeployIfNotExists(it carries a template). Append, audit, auditIfNotExists, deny and denyAction have nothing to execute against existing resources. - The task runs as the assignment's managed identity (system-assigned or user-assigned), not as the person who starts it or the pipeline that created the assignment. That identity needs the roles listed in the definition's
roleDefinitionIds, at a scope that covers the resources. - The portal grants those roles automatically; an assignment created with Bicep, ARM templates, the Azure CLI or PowerShell does not, so you add that role assignment as a separate step. Missing it shows up as authorization failures in every remediation deployment, however much access the operator has. A policy-management role such as Resource Policy Contributor does not help: the identity must be allowed to deploy or change the remediated resources themselves.
Writing a custom policy definition
A custom definition is a JSON policyRule with an if block that selects resources and a then block that names the effect, plus a mode and optional parameters. You write one when no built-in definition expresses your rule; built-ins should be your first stop.
- Aliases expose properties. A rule can evaluate a resource property only through an alias used in a
fieldcondition, for exampleMicrosoft.Storage/storageAccounts/minimumTlsVersion. Policy sees the resource request and its stored properties; it never sees template parameters, and a tag is just a label that proves nothing about real configuration. Find aliases withGet-AzPolicyAlias, the CLI or the Azure Policy extension for Visual Studio Code. - Mode All versus Indexed.
Indexedevaluates only resource types that support tags and location, and it skips resource groups and subscriptions. UseAllfor most definitions, and always when the rule targets resource groups. The evaluated type string for a resource group isMicrosoft.Resources/subscriptions/resourceGroups(notMicrosoft.Resources/resourceGroups). A tag-enforcing rule written in Indexed mode is the classic reason untagged resource groups deploy and never show in compliance results. - The details block of the IfNotExists effects. For auditIfNotExists and deployIfNotExists,
ifpicks the primary resource (for example a firewall),details.typenames the related resource to look for (for exampleMicrosoft.Insights/diagnosticSettings), andexistenceConditionsays which related resource counts. Without an existenceCondition, any related resource of that type makes the primary compliant, so a diagnostic setting pointing at the wrong workspace passes. The existenceCondition is evaluated against the related resource, which is why a check on itsworkspaceIdbelongs there and not in theifblock. - Initiatives (policy set definitions) group definitions under one assignment; each member has a
policyDefinitionReferenceIdthat exemptions can target.
Exemptions versus exclusions
An exclusion (notScopes on the assignment) removes a scope from evaluation entirely and permanently, while an exemption keeps the resource evaluated but records it as Exempt with a reason. Pick by whether the resource should still be assessed and counted.
| Exclusion (notScopes) | Exemption | |
|---|---|---|
| Set on | The assignment | A separate object at the resource, resource group, subscription or management group |
| Evaluation | Not evaluated or counted at all | Still evaluated; shown as Exempt |
| Granularity | Every definition in the assignment | The whole assignment, or only the definitions named in policyDefinitionReferenceIds |
| Expiry | None | Optional expiresOn; it stops being honoured after that date |
| Reason recorded | No | Category plus description |
Exemptions have two categories. Waiver means the non-compliance is accepted, usually temporarily (for example, a legacy workload scheduled for migration next quarter that cannot yet meet a tagging or SKU rule). Mitigated means the policy's intent is met another way (for example, a compensating control outside the policy's view delivers the outcome the definition checks for). Combine a category, a definition-level scope and, where the exception is temporary, an expiry date, so the exception ends without anyone remembering to remove it. Setting an effect to disabled through a parameter is a different tool: it switches the rule off for every resource the assignment covers.
Regulatory compliance, standards and recommendations in Defender for Cloud
Defender for Cloud's Regulatory compliance dashboard shows how a scope measures up against standards such as PCI DSS, ISO/IEC 27001, NIST SP 800-53 or CIS, and each of those standards is an Azure Policy initiative under the hood. The Microsoft cloud security benchmark (MCSB) is assigned automatically when Defender for Cloud is enabled on an Azure subscription, and its recommendations drive the secure score; every other standard is optional.
To add a standard you switch it on for the scope from the security policies page (Environment settings). Two prerequisites apply:
- A qualifying paid plan: any Defender plan except Defender for Servers Plan 1 and Defender for APIs Plan 1 must be enabled on the scope, for example Defender CSPM.
- Permission to assign policy: Owner or Policy Contributor on the scope, because you are assigning an initiative. Security Reader can view the dashboard but not add standards.
Reading the dashboard: controls that can be assessed automatically show resources as passing or failing. Controls about procedures, documentation or staff (for example a written policy) have no automated assessment, so they appear greyed out with no resources counted; they are evidenced outside Defender for Cloud. Separately, a standard can be hidden or show nothing when the scope has no resources relevant to it. Standards for Azure, AWS and GCP resources are managed in Defender for Cloud itself, on the security policies page.
Custom standards and recommendations
A security standard in Defender for Cloud is a set of recommendations you assign to a scope; a recommendation is one check with a severity and remediation steps. Beyond the built-in standards you can create custom ones, and there are two ways to build custom recommendations:
| KQL-based custom recommendation | Azure Policy-based custom recommendation | |
|---|---|---|
| Status | Current approach | Legacy |
| Clouds | Azure, AWS and GCP (queries Defender for Cloud's multicloud data) | Azure only (policy evaluates Azure Resource Manager resources) |
| Requires | Defender CSPM | A custom initiative onboarded to Defender for Cloud |
| You define | The query, severity, description and remediation text; add it to a custom standard | Policy definitions and their metadata |
So a check that must cover AWS accounts as well as Azure subscriptions points to a KQL custom recommendation in a custom standard. A query you only run or save yourself produces findings, not a recommendation: it has no severity, no remediation guidance and no secure-score effect until it is part of a custom recommendation. Exempting a recommendation in Defender for Cloud changes what is assessed, not what can be deployed; enforcement remains Azure Policy's job.
Resource locks: CanNotDelete and ReadOnly
A resource lock stops control-plane deletion (CanNotDelete) or every control-plane change (ReadOnly) on a subscription, resource group or resource, and it applies to everyone, including Owners, until the lock itself is removed. That removal is the deliberate extra step that protects against accidents.
| Behaviour | CanNotDelete | ReadOnly |
|---|---|---|
| Read | Allowed | Allowed |
| Update configuration | Allowed | Blocked |
| Delete | Blocked | Blocked |
| POST operations such as listing storage account keys | Allowed | Blocked |
- Locks beat roles. Granting Owner or another role never gets past a lock, so when a lock breaks a legitimate task you change the lock type, not the role.
- Inheritance. A lock on a parent scope applies to all resources in it, including ones added later; the most restrictive inherited lock wins. A resource group that contains a locked resource cannot be deleted.
- Control plane only. Locks act on Azure Resource Manager operations. Data-plane actions, such as reading or deleting blobs with Entra ID or an account key, are untouched, so a lock protects the resource, not its data. ReadOnly can still break things that look like reads because they are POSTs (listing keys).
- Role assignments are protected too: CanNotDelete on a scope blocks deleting role assignments at that scope.
- Who can create locks: you need
Microsoft.Authorization/locks/*. Owner and User Access Administrator have it; Contributor does not (it excludes Microsoft.Authorization writes); Role Based Access Control Administrator does not either. A custom role granting onlyMicrosoft.Authorization/locks/*lets a pipeline manage locks without being able to grant roles. - Locks in IaC: a Bicep or ARM template can declare a
Microsoft.Authorization/locksresource, using thescopeproperty to attach it to another resource, so locks are deployed with what they protect.
Built-in role assignments, least privilege and overprivileged access
An Azure role assignment is a security principal, a role definition and a scope, and least privilege means the narrowest role at the narrowest scope that still does the job. Scopes form a hierarchy (management group → subscription → resource group → resource) and assignments inherit downward, never sideways to sibling subscriptions.
| Role | Can manage resources | Can assign roles |
|---|---|---|
| Owner | Yes | Yes, plus every other action |
| Contributor | Yes | No (no Microsoft.Authorization writes) |
| Reader | Read all | No |
| User Access Administrator | No | Yes, with all Microsoft.Authorization actions |
| Role Based Access Control Administrator | No | Yes, with the fewest permissions of the three |
Read-only access to everything in one subscription is Reader at that subscription, not at the management group above it (too wide) and not Security Reader (it shows security data, not all configuration). To delegate role assignment without letting the delegate grant Owner to anyone, including themselves, assign Role Based Access Control Administrator and add a condition that limits which roles they can assign (for example only Virtual Machine User Login or Storage Blob Data Reader) and, optionally, to which principal types. A condition can be added to any role that includes Microsoft.Authorization/roleAssignments/write, but Owner and User Access Administrator grant far more (resource management, or every Microsoft.Authorization action), so Role Based Access Control Administrator plus a condition is the least-privilege choice.
Finding and right-sizing overprivileged access
Overprivileged access is any assignment broader than what the identity actually uses, and you fix it with evidence: find unused or excessive permissions, then replace the assignment with a narrower role at a narrower scope. The tool for continuous, usage-based analysis is the permissions management (CIEM) capability of Defender CSPM. It evaluates the effective permissions and activity of users, service principals and managed identities across Azure, AWS and GCP, and raises recommendations to remove inactive identities and right-size overprovisioned ones. The retirement of the separate Microsoft Entra Permissions Management product does not affect these Defender for Cloud capabilities.
Choose by the question being asked. CIEM answers "what does this identity actually use?" from activity data. Tools built for other jobs, such as periodic attestation or configuration rules, can confirm that access was approved or is shaped correctly, but not whether it is used.
The general right-sizing method works for people, apps and automation alike:
- Scope: narrow the assignment to the smallest scope the activity evidence shows is used (a resource group or a single resource instead of a subscription).
- Resource actions: pick the narrowest built-in role that covers what the identity does there, for example a service-specific contributor role rather than a general one, or a custom role when no built-in fits.
- Access-management actions: if it must also grant access, split that out into a separate, conditioned role-assignment permission instead of keeping a role that bundles it with everything else.
- Remove and verify: delete the broad assignment and confirm the workload still runs.
Privileged Identity Management for just-in-time activation is covered in the Entra ID access lesson; it complements right-sizing but does not replace it.
Custom roles: Azure RBAC and Microsoft Entra
Azure custom roles and Microsoft Entra custom roles are different things: Azure custom roles control Azure resources through Azure RBAC and need no extra licence, while Entra custom roles control directory objects and need Microsoft Entra ID P1 or P2.
Azure custom roles
- A definition has
ActionsandNotActions(control plane),DataActionsandNotDataActions(data plane), andAssignableScopes. - NotActions is not a deny. It only subtracts from that role's own Actions. Azure RBAC adds up all of a principal's assignments, so another role (such as Virtual Machine Contributor) can still grant what a NotActions entry leaves out. Only a deny assignment or a lock blocks it. There is no precedence between custom and built-in roles.
- AssignableScopes controls where the role can be assigned: list each subscription or resource group, or at most one management group. The root scope (
/) is not allowed for custom roles. A role with DataActions cannot be assigned at management group scope, so one definition listing the management group is assigned at each subscription beneath it. - Creating or updating a custom role needs
Microsoft.Authorization/roleDefinitions/writeon every assignable scope, which Owner and User Access Administrator have. Role Based Access Control Administrator can assign roles but cannot write role definitions. Role names are unique in the tenant, so you extend one definition's AssignableScopes rather than duplicating it.
Microsoft Entra custom roles
- Built from the permissions Entra makes available for custom roles, such as
microsoft.directory/applications/credentials/updatefor rotating app secrets. - Assign at directory scope (every object) or at a single app registration (or enterprise app) scope for least privilege. Administrative units hold users, groups and devices, not app registrations. A built-in role like Application Administrator, even scoped to one app, grants far more than one permission.
Security controls in infrastructure as code
Infrastructure as code gives you two security control points: scan templates before deployment, and protect deployed resources with controls that travel with the template. Azure Policy remains the deployment-time backstop for anything that slips through.
Scanning with Microsoft Security DevOps
Microsoft Security DevOps (MSDO) is a GitHub action and an Azure DevOps extension that runs open-source analyzers in the pipeline and, for repositories onboarded to Defender for Cloud, surfaces the findings on the DevOps security page. It needs no GitHub Advanced Security licence. Set the IaC category to run the template scanners:
| Analyzer | Scans |
|---|---|
| Template Analyzer | ARM templates and Bicep only |
| Checkov | Terraform, Bicep, ARM templates and CloudFormation, plus Kubernetes manifests, Helm charts and Dockerfiles |
| Terrascan | Terraform, plus other formats such as Kubernetes manifests and Helm charts |
| Trivy | IaC files and container images |
| BinSkim / Bandit / ESLint | Binaries / Python / JavaScript code, not infrastructure |
The point of these scanners is that they read the template files themselves, before anything is deployed; tools that only preview a deployment or watch running workloads act at a different stage and do not evaluate template security rules.
Deployment stacks and deny settings
A deployment stack manages a set of resources from one template and can apply deny settings that create a deny assignment on the managed resources, which even Owners cannot override:
none,denyDelete(updates allowed, deletion blocked) ordenyWriteAndDelete(both blocked).- Excluded principals (such as the pipeline identity) and excluded actions bypass the deny settings, so the pipeline can keep updating or pruning resources that the people working in the resource group cannot touch.
- Store the stack at a parent scope (for example the subscription for resources in a resource group) so the people who hold Owner on the resource group cannot edit or delete the stack and its deny settings.
- A stack protects only the resources it manages; it is not a way to guard resources deployed by others.
| Resource lock | Deployment stack deny settings | |
|---|---|---|
| Who it stops | Everyone, until someone with lock permission removes it | Everyone except excluded principals; Owners cannot override it |
| Exceptions | None | Excluded principals and actions |
| Fits | Simple accident prevention | Resources an IaC pipeline owns that other admins must not change |
Tip. Expect short Microsoft-style scenarios: an environment, a requirement, and a constraint such as least privilege, deployments must keep succeeding, the exception must expire automatically, the protection must not be reversible, Owners must not override it, or AWS accounts must be covered too. The options are usually near-twins that differ by one property: deny versus modify versus denyAction, a Waiver versus a Mitigated exemption versus an exclusion, CanNotDelete versus ReadOnly, Role Based Access Control Administrator versus User Access Administrator, assignment scope, immutable vault locked versus unlocked, Backup MUA Operator versus Backup MUA Admin, and denyDelete versus denyWriteAndDelete. Some items are select-two, and others give a symptom (existing resources stay non-compliant, a script that lists keys fails, untagged resource groups deploy) and ask for the fix.
- Deny fails a non-compliant create or update; modify fixes it so the deployment succeeds; audit only reports; denyAction is the effect that blocks deletes.
- Existing resources are only reported until a remediation task runs; only modify and deployIfNotExists support remediation, and the task runs as the assignment's managed identity, which needs the definition's roleDefinitionIds roles (granted automatically only in the portal).
- Mode Indexed skips resource groups and subscriptions; resource properties enter a rule through aliases; existenceCondition decides which related resource counts for the IfNotExists effects.
- Exclusions stop evaluation for every definition; exemptions keep evaluating, can target single definitions, can expire, and are Waiver (accepted risk) or Mitigated (met another way).
- Microsoft cloud security benchmark is the default standard; extra regulatory standards need a paid Defender plan other than Servers P1 or APIs P1 plus Owner or Policy Contributor, and greyed-out controls are ones that cannot be assessed automatically.
- Multicloud custom recommendations are KQL-based and need Defender CSPM; Azure Policy-based custom recommendations are legacy and Azure-only.
- Locks override roles, act only on the control plane, and are inherited; ReadOnly also blocks POST calls such as listing storage keys; creating locks needs Microsoft.Authorization/locks/*.
- NotActions is not a deny; DataActions roles cannot be assigned at management group scope; defining a custom role needs roleDefinitions/write, which RBAC Administrator lacks; Entra custom roles need P1 or P2.
- Delegate role assignment with Role Based Access Control Administrator plus a condition; right-size with CIEM evidence from Defender CSPM.
- Irreversible backup protection is an immutable vault enabled and locked; MUA approvals grant Backup MUA Operator on a Resource Guard kept in a separate tenant or subscription; deployment stack deny settings, stored at a parent scope, stop even Owners.
Frequently asked questions
What is the difference between the deny and modify effects in Azure Policy?
Both make sure a resource ends up compliant, but deny rejects a non-compliant create or update request with an error, while modify rewrites the request (adding, replacing or removing a tag or property with a modifiable alias) so the deployment succeeds with the compliant value. Modify is evaluated before deny. Use modify when existing templates must keep deploying unchanged and deny when engineers must see the failure at deployment time.
Why does a deployIfNotExists policy not fix resources that already existed?
Azure Policy runs deployIfNotExists after a create or update request succeeds, so resources that existed before the assignment are only marked non-compliant. To fix them you create a remediation task, which deploys the definition's template using the assignment's managed identity. That identity needs the roles listed in the definition's roleDefinitionIds; the portal grants them automatically, but assignments made with Bicep, ARM, the CLI or PowerShell need the role assignment added separately.
When should I use a policy exemption instead of an exclusion?
Use an exclusion (notScopes on the assignment) when a scope must not be evaluated or counted at all, for every definition, permanently. Use an exemption when the resource should still be evaluated but recorded as Exempt with a reason: it can target specific definitions in an initiative through policyDefinitionReferenceIds, can expire automatically with expiresOn, and is categorised as Waiver (accepted non-compliance) or Mitigated (the intent is met by another control).
What do I need to add a regulatory compliance standard in Microsoft Defender for Cloud?
The scope needs a paid Defender plan other than Defender for Servers Plan 1 or Defender for APIs Plan 1 (Defender CSPM qualifies), and you need Owner or Policy Contributor on the scope, because each standard is an Azure Policy initiative. You then turn the standard on from the scope's security policies page. The Microsoft cloud security benchmark is assigned by default and needs no action.
Does a resource lock protect the data in a storage account?
No. Resource locks apply only to Azure Resource Manager (control plane) operations, so data-plane actions such as reading or deleting blobs with Microsoft Entra ID or an account key are unaffected. A CanNotDelete lock stops the account being deleted; a ReadOnly lock also blocks configuration changes and POST operations such as listing the account keys. Use features such as soft delete and immutability to protect the data itself.
Why can a user still perform an action that a custom role lists in NotActions?
NotActions only removes permissions from that one role's Actions; it is not a deny. Azure RBAC grants the sum of all a user's role assignments, so if another role, such as a built-in role at the same or a parent scope, includes the action, the user can perform it. To block an action regardless of role assignments you need a deny assignment (for example from a deployment stack) or a resource lock.
Which role should I give someone who must grant only one specific Azure role?
Assign Role Based Access Control Administrator at the needed scope and add a condition that limits the roles they can assign to that one role (and optionally the principal types). Owner and User Access Administrator grant far more (Owner manages every resource; User Access Administrator holds every Microsoft.Authorization action), so even with a condition they are not least privilege. Role Based Access Control Administrator cannot create custom role definitions or manage locks.
How do I make Azure Backup data impossible to delete early, even by an Owner?
Enable immutability on the vault and then lock the immutable setting (Enabled and locked). Locked immutability is irreversible: recovery points cannot be deleted before they expire and retention cannot be reduced. Unlocked immutability can be turned off, multi-user authorization still lets an approved operator act, and a resource lock can be removed by an Owner.
Source
This lesson covers the "Manage identity, access, and governance" domain of the official SC-500 exam guide. Vendors revise their guides — check the source for the current version.
- Microsoft SC-500 study guide — Microsoft Learn
Sign up free to mark lessons complete, bookmark topics and track your exam readiness.