azure-adf-pipeline-write-modifycode

Overwrite an ADF pipeline definition to inject arbitrary activities (Web, Custom, Copy) that run as the factory MI.

derived azure emits CanModifyCode

match (effective permission)

{ "action": "Microsoft.DataFactory/factories/pipelines/write", "scope_type": "resource|resourceGroup|subscription" }

emit

source typeIdentity
target typeWorkflow
source<principal>
target<ADF pipeline (Workflow node)>
permissionsMicrosoft.DataFactory/factories/pipelines/write
conditionstrigger_exists
state logicACTIVE when the definition is modified AND a trigger path exists (a Schedule trigger is Enabled, a Storage Events trigger is bound to an active blob event, or the principal also holds pipelines/createRun/action to start a run directly). CONDITIONAL(trigger_exists) when no confirmed trigger or invoke path exists. BLOCKED if a deny assignment covers pipelines/write at the scope. Note: if the factory uses Git integration (repoConfiguration set), the ARM pipelines/write reflects the PUBLISHED version; modifying via ARM still overwrites the published definition. Parallel path via Git repo is a separate cicd-chains entry.

Narrative

{principal.name} can overwrite the pipeline definition of {target.name} (Microsoft.DataFactory/factories/pipelines/write), injecting Web, Custom, or Copy activities that run as the factory's managed identity on the next trigger or run invocation.

Raw rule rules/derived/azure/datafactory.yaml

id: azure-adf-pipeline-write-modifycode
emits: CanModifyCode
description: Overwrite an ADF pipeline definition to inject arbitrary activities (Web, Custom, Copy) that
  run as the factory MI.
match_effective_permission:
  action: Microsoft.DataFactory/factories/pipelines/write
  scope_type: resource|resourceGroup|subscription
emit:
  source_type: Identity
  target_type: Workflow
  source: <principal>
  target: <ADF pipeline (Workflow node)>
  permissions:
  - Microsoft.DataFactory/factories/pipelines/write
  conditions:
  - trigger_exists
  state_logic: 'ACTIVE when the definition is modified AND a trigger path exists (a Schedule trigger is
    Enabled, a Storage Events trigger is bound to an active blob event, or the principal also holds pipelines/createRun/action
    to start a run directly). CONDITIONAL(trigger_exists) when no confirmed trigger or invoke path exists.
    BLOCKED if a deny assignment covers pipelines/write at the scope. Note: if the factory uses Git integration
    (repoConfiguration set), the ARM pipelines/write reflects the PUBLISHED version; modifying via ARM
    still overwrites the published definition. Parallel path via Git repo is a separate cicd-chains entry.'
  confidence: 0.97
  derived_from:
  - 'effective permission: Microsoft.DataFactory/factories/pipelines/write'
  false_positive_note: "pipelines/write is granted to Data Factory Contributor, Contributor, and Owner.\
    \ The Data Factory Operator role (if used via ARM custom role for trigger management only) does NOT\
    \ include pipelines/write; do not derive CanModifyCode from a trigger-only role. Realized on next\
    \ trigger event or direct createRun \u2014 without either, emit CONDITIONAL(trigger_exists) not ACTIVE.\
    \ The managed identity must exist for CanExecuteAs to fire via can-execute-as; if the factory has\
    \ no MI, this yields only linked-service credential access, not ARM token access."
  narrative: '{principal.name} can overwrite the pipeline definition of {target.name} (Microsoft.DataFactory/factories/pipelines/write),
    injecting Web, Custom, or Copy activities that run as the factory''s managed identity on the next
    trigger or run invocation.'
move · open · esc close