Skip to main content
compliance · azure

Production VMs carrying no CanNotDelete resource lock

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

A CanNotDelete lock is the last guardrail between a production Azure VM and one wrong az vm delete by anyone holding delete permissions. RC-266 flags running, production-classified VMs whose lock state is an explicit false, taken from the Microsoft.Authorization/locks lookup or a deletion_protection=false tag, and abstains when no signal exists.

Signal and threshold

How ZopNight evaluates Production VMs carrying no CanNotDelete resource lock.
Field Value
Rule IDsRC-266
Categorycompliance
Severitymedium
Metricnone — pure configuration read
Sourcevm_deletion_protection.go

The blast radius of a mistyped delete

Deleting an Azure VM is fast, silent, and final for the compute resource itself. Disks may survive depending on their delete options, but the machine, its NIC associations, and its runtime state are gone, and if backups were never configured the recovery path is a rebuild. A CanNotDelete lock converts that scenario into a failed API call: the delete is refused until someone with lock-management rights consciously removes the lock first, which is exactly the deliberate two-step you want in front of production.

Only production VMs are held to this bar

Dev and test machines are disposable by design, so the rule first requires production classification: a production naming pattern or an explicit env=prod tag, whichever matched is named in the finding. The tag is treated as the authoritative signal and the name match as a guess. That ordering matters, since name-only classification had previously pulled ordinary VMs into scope. Deallocated machines are also skipped; only running production workloads generate findings.

From fail-open to fail-closed

The instructive part of this rule is its history. The original gate fired when the lock signal was absent or false, which meant every unlabelled production VM was flagged, an evidence-free default. The current logic reads the discoverer’s deletion_protection metadata (derived from the Microsoft.Authorization/locks lookup set) first and fires only on an explicit "false"; if that key is absent it falls back to requiring a literal deletion_protection=false customer tag. No signal at all now means no finding.

Audit lock coverage yourself

Terminal window
az lock list --resource-group <rg> \
--query "[?level=='CanNotDelete'].{name:name, scope:id}" -o table

Compare against the resource group’s production VMs; anything unlisted is unprotected.

Cheap insurance

Locks cost nothing, apply in seconds (az lock create --lock-type CanNotDelete ...), and are reversible by anyone with Microsoft.Authorization/locks/* rights, typically Owner or User Access Administrator, which is the point: routine contributors can’t delete around them. Consider ReadOnly locks for the most critical machines, noting they also block writes like resizes. Reader reproduces the detection; ZopNight places no locks itself.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·