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.

derived azure emits ExecutesAs

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'assignment': None} Identity {'identity': None}

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 typeBuildWorker
target typeManagedIdentity
source<remediation task for the assignment>
target?identity
state logicACTIVE 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.
move · open · esc close