Detection rules › Panther
Azure Policy DeployIfNotExists Action Triggered
Detects when an Azure Policy with the DeployIfNotExists effect is triggered and executes a deployment. The DeployIfNotExists effect allows policies to automatically deploy resources when certain conditions are met. Adversaries may abuse this feature to establish persistence by creating policies that automatically deploy backdoors, malicious configurations, or unauthorized resources when specific conditions occur. This technique enables stealthy persistence as deployments appear to be legitimate policy enforcement actions.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Persistence | T1078.004 Valid Accounts: Cloud Accounts |
| Stealth | T1078.004 Valid Accounts: Cloud Accounts, T1564 Hide Artifacts |
Rule body yaml
AnalysisType: rule
Filename: azure_policy_deployifnotexists.py
RuleID: "Azure.MonitorActivity.Policy.DeployIfNotExists"
DisplayName: "Azure Policy DeployIfNotExists Action Triggered"
Enabled: true
LogTypes:
- Azure.MonitorActivity
Severity: Medium
Description: >
Detects when an Azure Policy with the DeployIfNotExists effect is triggered and executes a deployment.
The DeployIfNotExists effect allows policies to automatically deploy resources when certain conditions are met.
Adversaries may abuse this feature to establish persistence by creating policies that automatically deploy
backdoors, malicious configurations, or unauthorized resources when specific conditions occur. This technique
enables stealthy persistence as deployments appear to be legitimate policy enforcement actions.
Reports:
MITRE ATT&CK:
- TA0003:T1078.004 # Persistence: Valid Accounts - Cloud Accounts
- TA0005:T1564 # Defense Evasion: Hide Artifacts
Tags:
- AZT508
- Persistence
- Defense Evasion
- Valid Accounts
- Cloud Accounts
- Hide Artifacts
Runbook: |
1. Find all policy-related operations by the callerIpAddress in the 48 hours before and after this alert to identify if new policies were created or assignments were modified
2. Query for the policy definition details to understand what resources are being deployed and review the deployment template for malicious configurations
3. Check if similar DeployIfNotExists actions have been triggered from this policy in the past 30 days to determine if this is expected behavior
Reference: https://microsoft.github.io/Azure-Threat-Research-Matrix/Persistence/AZT508/AZT508
SummaryAttributes:
- resourceId
- callerIpAddress
- correlationId
Tests:
- Name: DeployIfNotExists Policy Triggered
ExpectedResult: true
Log:
{
"time": "2025-12-23T10:30:00.0000000Z",
"resourceId": "/subscriptions/12345678-1234-1234-1234-123456789abc/resourceGroups/policy-rg/providers/Microsoft.Authorization/policyDefinitions/AutoDeployBackdoor",
"operationName": "Microsoft.Authorization/policies/deployIfNotExists/action",
"operationVersion": "2021-06-01",
"category": "Administrative",
"resultType": "Success",
"resultSignature": "200",
"callerIpAddress": "1.1.1.1",
"correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"level": "Informational",
"location": "eastus",
"tenantId": "87654321-4321-4321-4321-111111111111"
}
- Name: Policy Deployment Success
ExpectedResult: true
Log:
{
"time": "2025-12-23T11:15:00.0000000Z",
"resourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/prod-rg/providers/Microsoft.Authorization/policyAssignments/AutoDeploy",
"operationName": "Microsoft.Authorization/policies/deployIfNotExists/action",
"category": "Administrative",
"resultType": "Succeeded",
"callerIpAddress": "2.2.2.2",
"correlationId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
"level": "Information",
"location": "westeurope",
"tenantId": "22222222-2222-2222-2222-222222222222"
}
- Name: Case Insensitive Match
ExpectedResult: true
Log:
{
"time": "2025-12-23T12:00:00.0000000Z",
"resourceId": "/subscriptions/33333333-3333-3333-3333-333333333333/resourceGroups/security-rg/providers/Microsoft.Authorization/policyDefinitions/MaliciousPolicy",
"operationName": "microsoft.authorization/policies/deployifnotexists/action",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "3.3.3.3",
"correlationId": "c3d4e5f6-a7b8-9012-cdef-333333333333",
"level": "Informational",
"location": "centralus",
"tenantId": "33333333-3333-3333-3333-333333333333"
}
- Name: Different Operation
ExpectedResult: false
Log:
{
"time": "2025-12-23T14:00:00.0000000Z",
"resourceId": "/subscriptions/55555555-5555-5555-5555-555555555555/resourceGroups/policy-rg/providers/Microsoft.Authorization/policyDefinitions/MyPolicy",
"operationName": "Microsoft.Authorization/policyDefinitions/write",
"category": "Administrative",
"resultType": "Success",
"callerIpAddress": "5.5.5.5",
"correlationId": "e5f6a7b8-c9d0-1234-ef01-111111111111",
"tenantId": "55555555-5555-5555-5555-555555555555"
}
Detection logic
Condition
operationName in "MICROSOFT.AUTHORIZATION/POLICIES/DEPLOYIFNOTEXISTS/ACTION"
resultType in ["Success", "Succeeded"]
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
operationName | in |
|
resultType | in |
|