azure-auto-sourcecontrol-write

Repoint the Automation Account's source control sync to an attacker-controlled repository; runbook code is replaced at next sync.

derived azure emits CanModifyCode

match (effective permission)

{ "action": "Microsoft.Automation/automationAccounts/sourceControls/write", "scope_type": "resource|resourceGroup|subscription" }

where

account has source control sync enabled (sourceControls collection is non-empty, or attacker creates a new sourceControl entry)

emit

source typeIdentity
target typeGenericCompute
source<principal>
target<runbook(s) (BuildWorker) synced from the source control>
permissionsMicrosoft.Automation/automationAccounts/sourceControls/write
conditionstrigger_exists service_state
state logicCONDITIONAL(trigger_exists) — code is injected at the NEXT sync event (manually triggered or on a sync schedule), not immediately. ACTIVE only when the sync is configured to run automatically (syncType=AutoSync with a schedule) and the source control repo accepts attacker pushes. BLOCKED if deny assignment covers sourceControls/write.

Narrative

{principal.name} can repoint or create a source-control sync (sourceControls/write) for Automation Account {target.name}; attacker-controlled repo content replaces runbook code at the next sync, executing as the account's managed identity.

Raw rule rules/derived/azure/automation.yaml

id: azure-auto-sourcecontrol-write
emits: CanModifyCode
description: Repoint the Automation Account's source control sync to an attacker-controlled repository;
  runbook code is replaced at next sync.
match_effective_permission:
  action: Microsoft.Automation/automationAccounts/sourceControls/write
  scope_type: resource|resourceGroup|subscription
where:
- account has source control sync enabled (sourceControls collection is non-empty, or attacker creates
  a new sourceControl entry)
emit:
  source_type: Identity
  target_type: GenericCompute
  source: <principal>
  target: <runbook(s) (BuildWorker) synced from the source control>
  permissions:
  - Microsoft.Automation/automationAccounts/sourceControls/write
  conditions:
  - trigger_exists
  - service_state
  state_logic: "CONDITIONAL(trigger_exists) \u2014 code is injected at the NEXT sync event (manually triggered\
    \ or on a sync schedule), not immediately. ACTIVE only when the sync is configured to run automatically\
    \ (syncType=AutoSync with a schedule) and the source control repo accepts attacker pushes. BLOCKED\
    \ if deny assignment covers sourceControls/write."
  confidence: 0.75
  derived_from:
  - 'effective permission: Microsoft.Automation/automationAccounts/sourceControls/write'
  - 'cicd-chains.yaml: cicd-modify-buildspec-executes-as'
  false_positive_note: "Source control sync is NOT immediate; actual code import happens at the next configured\
    \ sync event. If syncType=Manual (operator-initiated sync), the attacker cannot self-trigger the sync\
    \ \u2014 keep CONDITIONAL(trigger_exists). AutoSync with a schedule is the ACTIVE case only if the\
    \ attacker also controls the target repo. Do not emit if source control is not configured or if the\
    \ attacker cannot push to the configured repository branch."
  narrative: '{principal.name} can repoint or create a source-control sync (sourceControls/write) for
    Automation Account {target.name}; attacker-controlled repo content replaces runbook code at the next
    sync, executing as the account''s managed identity.'
move · open · esc close