azure-auto-executes-as-mi

An Automation Account sandbox job executes as the bound managed identity; any code running in the sandbox can mint MI tokens from IMDS.

derived azure emits ExecutesAs

match

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

{'account': None} HasPolicy {'identity': None}

where

node_type(?account) == AutomationService node_type(?identity) in [ManagedIdentity, ServiceIdentity] identity.type in [SystemAssigned, UserAssigned, 'SystemAssigned, UserAssigned']

emit

source typeGenericCompute
target typeManagedIdentity
source<runbook (BuildWorker) in ?account>
target?identity
state logicACTIVE when the account identity block confirms the MI binding (principalId or userAssignedIdentities map is non-empty). Zero-cost structural fact. cicd-chains cicd-modify-buildspec-executes-as consumes this edge with CanModifyCode to produce CanExecuteAs. No permissions required to assert this fact — it is an inventory observation.

Narrative

Automation Account {account.name} sandbox jobs execute as managed identity {target.name}; any code running in the sandbox can call IMDS (http://169.254.169.254/metadata/identity/oauth2/token) to mint a bearer token for {target.name} with no further credentials. cicd-chains collapses this with CanModifyCode to CanExecuteAs.

Raw rule rules/derived/azure/automation.yaml

id: azure-auto-executes-as-mi
emits: ExecutesAs
description: An Automation Account sandbox job executes as the bound managed identity; any code running
  in the sandbox can mint MI tokens from IMDS.
match:
- - account: null
  - HasPolicy
  - identity: null
where:
- node_type(?account) == AutomationService
- node_type(?identity) in [ManagedIdentity, ServiceIdentity]
- identity.type in [SystemAssigned, UserAssigned, 'SystemAssigned, UserAssigned']
emit:
  source_type: GenericCompute
  target_type: ManagedIdentity
  source: <runbook (BuildWorker) in ?account>
  target: ?identity
  permissions: []
  conditions: []
  state_logic: "ACTIVE when the account identity block confirms the MI binding (principalId or userAssignedIdentities\
    \ map is non-empty). Zero-cost structural fact. cicd-chains cicd-modify-buildspec-executes-as consumes\
    \ this edge with CanModifyCode to produce CanExecuteAs. No permissions required to assert this fact\
    \ \u2014 it is an inventory observation."
  confidence: 1.0
  derived_from:
  - Microsoft.Automation/automationAccounts identity.principalId or userAssignedIdentities
  - 'cicd-chains.yaml: ExecutesAs is the linchpin input for cicd-modify-buildspec-executes-as'
  - 'can-execute-as.yaml: execute-as-via-code-modify dedupes with cicd-chains on (CanExecuteAs, ?p, ?identity)'
  false_positive_note: "Only emit when the account identity block is non-empty (identity.type != None).\
    \ The account's system-assigned MI has principalId in the identity block; user-assigned MIs appear\
    \ in userAssignedIdentities. If both types are configured, emit one ExecutesAs per bound MI. Do NOT\
    \ emit if the account has no identity configured \u2014 sandbox jobs have no ARM token access and\
    \ CanRetrieveToken/CanExecuteAs to an MI must not follow."
  narrative: Automation Account {account.name} sandbox jobs execute as managed identity {target.name};
    any code running in the sandbox can call IMDS (http://169.254.169.254/metadata/identity/oauth2/token)
    to mint a bearer token for {target.name} with no further credentials. cicd-chains collapses this with
    CanModifyCode to CanExecuteAs.
move · open · esc close