azure-auto-sourcecontrol-write
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) — 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.'