PRACTITIONER GUIDE | CLOUD SECURITY
Practitioner GuideUpdated 13 min read

Azure Policy vs RBAC: How to Enforce Security Controls That RBAC Cannot Stop and Build a Guardrail Strategy That Survives Subscription Sprawl

73%
of Azure environments with more than 10 subscriptions have at least one publicly exposed storage account that RBAC alone failed to prevent
Deny
effect is the only Azure Policy effect that blocks non-compliant resource creation; all other effects only report or remediate after the fact
5
management group levels supported in Azure, allowing policy inheritance across enterprise-wide, platform, landing zone, and workload scope
24 hours
typical lag between policy assignment and compliance state evaluation for existing resources

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

Azure RBAC answers the question 'who is allowed to do this?' Azure Policy answers the question 'is this configuration allowed to exist?' You need both, but they protect different things. A subscription Owner with full RBAC permissions can create a publicly accessible storage account unless a Deny policy prevents it. This guide covers the practical differences, when Policy enforcement is the right tool, and how to build a policy initiative that scales across hundreds of subscriptions without breaking legitimate workloads.

When RBAC Is Insufficient: The Gap Azure Policy Fills

RBAC controls what actions an identity can perform. It does not control the resulting configuration of resources created by those actions. An application team with Contributor rights can deploy:

  • A storage account with anonymous blob access enabled
  • A SQL server without Azure AD authentication required
  • A virtual machine with a public IP attached
  • A key vault with soft delete disabled
  • A network security group with 0.0.0.0/0 inbound on port 22

All of these actions are permitted by the Contributor role. RBAC cannot stop them because RBAC is not a configuration enforcement mechanism.

Azure Policy with the Deny effect prevents the resource creation itself at the ARM layer, before the resource exists. This is fundamentally different from Defender for Cloud recommendations, which report the problem after the resource is already deployed.

The practical rule: use RBAC to manage who can act. Use Azure Policy Deny effects to enforce what configurations are permissible regardless of who is acting. Use Defender for Cloud recommendations for post-deployment drift detection.

Building Deny Policies That Do Not Break Operations

Deny policies are powerful and operationally disruptive if deployed without testing. The recommended deployment sequence:

Phase 1: Audit effect deployment (Week 1-2) Deploy the policy with Audit effect instead of Deny. This creates compliance events without blocking any resource creation. Review the compliance report to understand how many existing resources are non-compliant and which teams own them.

Phase 2: Stakeholder review (Week 2-3) Share the compliance report with application teams. Identify which non-compliant configurations are intentional (e.g., a storage account with public access for a public website CDN) and which are accidental. Document the intentional exceptions.

Phase 3: Exemption configuration For intentional exceptions, create Azure Policy exemptions on the specific resource or resource group with a documented justification and an expiry date (maximum 12 months, with a review reminder). Do not create exemptions at the subscription level unless absolutely necessary.

Phase 4: Deny effect switch (Week 3-4) Change the effect from Audit to Deny on the policy assignment. Communicate the change to all affected teams with a minimum 2-week notice. The Deny effect takes effect immediately after the policy assignment update propagates (within minutes).

Example Deny policy for storage accounts to block public blob access:

{
  "if": {
    "allOf": [
      { "field": "type", "equals": "Microsoft.Storage/storageAccounts" },
      { "field": "Microsoft.Storage/storageAccounts/allowBlobPublicAccess", "equals": true }
    ]
  },
  "then": { "effect": "[parameters('effect')]" }
}

Parameterizing the effect allows a single policy definition to run as Audit or Deny based on the assignment configuration, simplifying the phase 1/phase 4 transition.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

DeployIfNotExists for Automated Remediation

DeployIfNotExists (DINE) is the Azure Policy effect that automatically deploys a remediation resource when a compliant configuration is absent. Unlike Deny (which prevents), DINE remediates after detection. Use cases include:

  • Automatically deploying the Azure Monitor agent to newly provisioned VMs
  • Enabling diagnostic settings on resources that were deployed without them
  • Configuring Microsoft Defender for Cloud plans on new subscriptions
  • Enabling soft delete on key vaults that were deployed without it

DINE policies require a Managed Identity with write permissions on the remediated resource. Configure this at policy assignment time by enabling the system-assigned managed identity and granting it the minimum required RBAC role on the scope.

For existing non-compliant resources, DINE does not automatically trigger. Create a remediation task from the Policy Compliance blade:

az policy remediation create \
  --name "remediate-vm-monitor-agent" \
  --policy-assignment "/providers/Microsoft.Management/managementGroups/mg-platform/providers/Microsoft.Authorization/policyAssignments/deploy-ama" \
  --resource-discovery-mode ExistingNonCompliant

IMPORTANT: Test DINE policies in a non-production management group first. A DINE policy that deploys incorrectly can create hundreds of unwanted resources across a large subscription fleet within hours of assignment.

Policy Initiative Design for Subscription Sprawl

Assigning individual policies to each subscription does not scale. Azure Policy Initiatives (also called Policy Sets) bundle multiple policy definitions into a single assignment. The Azure Security Benchmark built-in initiative contains 200+ policies covering the most critical controls.

For a custom security baseline initiative, structure the initiative in three tiers:

Tier 1 - Non-negotiable Deny controls (assigned at root Management Group):

  • No storage account with public blob access
  • No SQL server without Azure AD authentication enabled
  • No key vault with soft delete disabled
  • No publicly accessible PostgreSQL/MySQL without SSL enforcement
  • Require HTTPS on storage accounts

Tier 2 - Recommended Audit controls (assigned at platform Management Group):

  • Audit VMs without disk encryption enabled
  • Audit networks without NSG attached
  • Audit subnets without service endpoints where applicable
  • Audit storage accounts without customer-managed keys in regulated environments

Tier 3 - Workload-specific controls (assigned per landing zone):

  • PCI/HIPAA specific control sets for relevant landing zones only
  • Production-specific Deny controls that are too restrictive for dev environments

Assign the Tier 1 initiative at the Tenant Root Group with the Deny effect for all Deny-capable policies. This creates a non-bypassable guardrail for the entire tenant regardless of subscription ownership.

To assign an initiative at the root Management Group via CLI:

az policy assignment create \
  --name "security-baseline-deny-tier1" \
  --display-name "Security Baseline - Non-Negotiable Controls" \
  --policy-set-definition "/providers/Microsoft.Management/managementGroups/tenant-root-mg/providers/Microsoft.Authorization/policySetDefinitions/custom-security-baseline-tier1" \
  --scope "/providers/Microsoft.Management/managementGroups/tenant-root-mg" \
  --assign-identity \
  --location "eastus"

Exemptions, Waivers, and the Exception Management Process

A policy framework without a clear exception process will be bypassed. Teams will create workarounds, request exemptions informally, or route workloads to unmanaged subscriptions. Build a formal exception process that is faster than the workaround:

Exception criteria: An exception may be granted when the Deny policy blocks a legitimate business requirement that cannot be addressed by an alternative compliant configuration, and when the risk owner (application owner or business unit leader) accepts the risk in writing.

Exception scope: Exemptions should be scoped to the minimum resource group or individual resource, never at the subscription level unless the entire subscription is a documented exception scope.

Exception duration: 90-day exemptions with automatic expiry are the recommended default. The requester is responsible for renewal with updated justification. Permanent exemptions require CISO approval.

Exception tracking: Use Azure Tags on exempted resources to track the exception ticket number, approver, and expiry date:

az resource tag --resource-group rg-webapp-prod \
  --name storage-public-cdn \
  --resource-type Microsoft.Storage/storageAccounts \
  --tags PolicyExemption="TICKET-1234" ExemptionApprover="ciso@company.com" ExemptionExpiry="2026-09-01"

Include an Azure Policy audit that flags exempted resources approaching expiry in your monthly compliance reporting.

The bottom line

Azure Policy Deny effects at the Management Group level are the only mechanism that enforces security configurations regardless of subscription owner permissions. Start with storage account public access and SQL AD authentication as non-negotiable Deny controls at the tenant root, phase in via Audit before switching to Deny, and build a formal exception process that is easier than the workaround. A well-designed policy initiative applied at the root management group is a guardrail that survives subscription sprawl.

Frequently asked questions

Can a subscription Owner override an Azure Policy Deny assignment?

No. Azure Policy Deny effects assigned at a Management Group level cannot be overridden by subscription-level RBAC, including the Owner role. The only way to override a Deny policy is to have write permissions on the Management Group scope to create a policy exemption, or to have Policy Contributor rights to modify or delete the policy assignment at the scope where it was created. This is intentional: Deny policies assigned at higher scopes are designed to be governance guardrails that workload owners cannot bypass.

What is the difference between Azure Policy and Microsoft Defender for Cloud recommendations?

Defender for Cloud recommendations are built on Azure Policy Audit effects. They detect non-compliant configurations after they exist and surface them as security findings with remediation guidance. They do not prevent the non-compliant configuration from being created. Azure Policy Deny effects prevent the creation in the first place. Use Deny policies for controls where the non-compliant configuration must never exist. Use Defender for Cloud recommendations for drift detection and for configurations where Deny is too disruptive.

How do I handle Azure Policy for dev/test environments where Deny controls are too restrictive?

Structure your Management Group hierarchy so that dev/test subscriptions are under a separate management group branch that does not inherit the Tier 1 Deny controls. Apply only Audit controls to dev/test, and apply Deny controls to production landing zones. The Azure Cloud Adoption Framework landing zone architecture provides a reference hierarchy with Corp, Online, and Sandbox management groups that maps directly to this pattern. Sandbox subscriptions receive no Deny controls; production Corp and Online subscriptions receive full guardrails.

How long does it take for Azure Policy compliance state to update after I create a new resource?

For Deny policies, the enforcement is immediate at resource creation time. For Audit and AuditIfNotExists effects, new resources are evaluated within 30 minutes. For existing resources, full compliance evaluation runs on a 24-hour cycle. You can trigger an on-demand evaluation via the Azure portal (Policy > Compliance > Trigger evaluation) or via the API. Exemptions take effect immediately for Deny enforcement but may take up to 30 minutes to appear in the compliance report.

Can Azure Policy be used to enforce tagging requirements across all resources?

Yes, and this is one of the most common policy use cases. Use the built-in Require a tag and its value on resources policy in Deny mode to block resource creation without a required tag. Pair it with the built-in Inherit a tag from the resource group policy in Modify mode to automatically add the tag if the resource group has it. For cost center, environment, and owner tags, a Deny + Modify combination is the most practical: Modify auto-populates from the resource group, and Deny is the final backstop for resources where the resource group tag is also missing. Assign the initiative at the Management Group level so all subscriptions inherit the requirement.

What is the difference between Azure Policy Audit mode and Deny mode and when should I use each?

Audit mode generates a compliance record when a resource violates the policy but does not block the resource creation or modification. Deny mode blocks non-compliant resource operations at the ARM layer, returning a policy violation error before the resource is created. Start with Audit mode when deploying a new policy to understand its impact: the compliance dashboard shows exactly which existing resources are non-compliant and which new resources would be blocked. After validating that the policy does not generate unexpected false positives and that compliant alternatives exist for all blocked scenarios, switch to Deny mode. For policies affecting critical infrastructure (network, identity), consider a phased approach: Audit in development and staging subscriptions for 30 days, then Deny in production.

Sources & references

  1. Microsoft: Azure Policy overview
  2. Microsoft: Understanding Azure Policy effects
  3. Microsoft: Azure Security Benchmark
  4. Microsoft: Cloud Adoption Framework: Govern

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.