azure-policy-remediation-task-executes-as-mi
An Azure Policy remediation task (modeled as BuildWorker - the ARM deployment runner) executes as the managed identity bound in the policy assignment's identity block. Zero-cost structural fact; can-execute-as execute-as-via-code-modify and cicd-chains cicd-modify-buildspec-executes-as consume this to produce CanExecuteAs.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
Identity {'identity': None}
where
BuildWorker
?assignment.provider_type == 'Microsoft.PolicyInsights/remediations'
node_type(?identity) in [ManagedIdentity, ServiceIdentity]
?assignment references an assignment identity (principalId or userAssignedIdentities)
the policy definition referenced by the assignment has at least one deployIfNotExists or modify effect rule
emit
| source type | BuildWorker |
|---|---|
| target type | ManagedIdentity |
| source | <remediation task for the assignment> |
| target | ?identity |
| state logic | ACTIVE when the assignment identity block is non-empty AND the referenced policy definition uses deployIfNotExists or modify effect (confirming remediation execution is intended). Zero-cost structural fact. BLOCKED if the assignment is disabled (enforcementMode=DoNotEnforce with no remediation scheduled). Do NOT emit for Deny/Audit/AuditIfNotExists assignments — those effects do not trigger remediation tasks. |
Narrative
The remediation task for policy assignment {assignment.name} executes as managed identity {target.name} (assignment identity block); any ARM operations the remediation task performs run under {target.name}'s RBAC. can-execute-as collapses this with CanModifyConfiguration(principal -> assignment) and CanPassIdentity(principal -> {target.name}) to produce CanExecuteAs.
Raw rule rules/derived/azure/policy.yaml
id: azure-policy-remediation-task-executes-as-mi
emits: ExecutesAs
description: "An Azure Policy remediation task (modeled as BuildWorker \u2014 the ARM deployment runner)\
\ executes as the managed identity bound in the policy assignment's identity block. Zero-cost structural\
\ fact; can-execute-as execute-as-via-code-modify and cicd-chains cicd-modify-buildspec-executes-as\
\ consume this to produce CanExecuteAs."
match:
- - assignment: null
- Identity
- identity: null
where:
- node_type(?assignment) == BuildWorker
- ?assignment.provider_type == 'Microsoft.PolicyInsights/remediations'
- node_type(?identity) in [ManagedIdentity, ServiceIdentity]
- ?assignment references an assignment identity (principalId or userAssignedIdentities)
- the policy definition referenced by the assignment has at least one deployIfNotExists or modify effect
rule
emit:
source_type: BuildWorker
target_type: ManagedIdentity
source: <remediation task for the assignment>
target: ?identity
permissions: []
conditions: []
state_logic: "ACTIVE when the assignment identity block is non-empty AND the referenced policy definition\
\ uses deployIfNotExists or modify effect (confirming remediation execution is intended). Zero-cost\
\ structural fact. BLOCKED if the assignment is disabled (enforcementMode=DoNotEnforce with no remediation\
\ scheduled). Do NOT emit for Deny/Audit/AuditIfNotExists assignments \u2014 those effects do not\
\ trigger remediation tasks."
confidence: 1.0
derived_from:
- policyAssignment.identity.principalId or userAssignedIdentities (ARM collection)
- policyAssignment.properties.policyDefinitionId -> effect = deployIfNotExists|modify
- 'can-execute-as.yaml: execute-as-via-code-modify consumes this ExecutesAs to produce CanExecuteAs'
- 'cicd-chains.yaml: cicd-modify-buildspec-executes-as (remediation task as runner)'
false_positive_note: "Only emit when the assignment identity block is populated AND the policy effect\
\ is deployIfNotExists or modify \u2014 these are the only effects that produce remediation tasks.\
\ A Deny/Audit assignment with a non-empty identity block is unusual (Azure may include it for historical\
\ reasons) but does NOT produce a remediation task at runtime \u2014 do not emit ExecutesAs in that\
\ case. Verify the effect from the policyDefinition, not only the assignment metadata."
narrative: The remediation task for policy assignment {assignment.name} executes as managed identity
{target.name} (assignment identity block); any ARM operations the remediation task performs run under
{target.name}'s RBAC. can-execute-as collapses this with CanModifyConfiguration(principal -> assignment)
and CanPassIdentity(principal -> {target.name}) to produce CanExecuteAs.