Azure Policy tampering: a green dashboard that is lying to you
Edit the policy and you turn off the guardrail and the auditor at once. A deny policy disappears, public resources appear, and the compliance dashboard stays green.
Azure Policy is the guardrail that blocks bad resources before they exist. If you can edit the policy, you can turn off the guardrail and the auditor in the same breath, which is why a green compliance dashboard is not always something to trust.
How the attack works
With Resource Policy Contributor or Owner scope, the attacker deletes a deny policy assignment, such as deny-public-blob-access, with a Microsoft.Authorization/policyAssignments/delete, then edits an audit-untagged-resources assignment so its effect is Disabled. With the deny effect gone, they create a publicly exposed storage account that would have been blocked moments earlier, and because the audit policy is gone, the new exposure never surfaces as non-compliant. The policy change is the primary event and the Activity Log records it even though compliance state then looks clean. In ATT&CK terms this is T1484, Domain or Tenant Policy Modification, with T1562, Impair Defenses.
Why it works
Policy assignments were standing-mutable by a broad role, with no enforced state and no alerting on policy changes. The guardrails could be removed as easily as any other config.
How to fix it
Do not trust the dashboard or hand-fix resources while the guardrail stays off. Restore the deny and audit policy assignments from source control to re-enforce their effects, and revoke the role that holds policyAssignments write and delete, or the actor simply deletes them again. Scope what slipped through by correlating the policy-change timestamps with resource create and write events in the same window, since the compliance state is unreliable. Afterward, manage policy as code so assignments self-heal, alert on every policyAssignments change, and gate the policy-modify privilege behind PIM with deny assignments on critical guardrails.
Practice it
We built this as a GraphLattice Range scenario so administrators trust the Activity Log over a blinded dashboard and restore guardrails from source.