azure-vm-execute-as-via-attach-mi

Attach a privileged user-assigned MI to an existing VM the caller can run code on, then execute as that MI via IMDS.

derived azure emits CanExecuteAs

match

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

{'principal': None} CanPassIdentity {'userMI': None} {'principal': None} CanAttachIdentity {'vm': None} {'principal': None} CanExecuteCommand {'vm': None}

where

node_type(?vm) == VirtualMachine ?userMI.privilege_level >= ?principal.privilege_level # escalation only

emit

source typeIdentity
target typeIdentity
source<principal>
target<user-assigned managed identity>
permissionsMicrosoft.ManagedIdentity/userAssignedIdentities/assign/action Microsoft.Compute/virtualMachines/write runCommand/extensions
conditionsrole_compatibility

Narrative

{principal.name} can attach user-assigned MI {userMI.name} to VM {vm.name} it can run code on, then mint {userMI.name}'s token from IMDS, executing as {userMI.name}.

Raw rule rules/derived/azure/vm.yaml

id: azure-vm-execute-as-via-attach-mi
emits: CanExecuteAs
description: Attach a privileged user-assigned MI to an existing VM the caller can run code on, then execute
  as that MI via IMDS.
match:
- - principal: null
  - CanPassIdentity
  - userMI: null
- - principal: null
  - CanAttachIdentity
  - vm: null
- - principal: null
  - CanExecuteCommand
  - vm: null
where:
- node_type(?vm) == VirtualMachine
- '?userMI.privilege_level >= ?principal.privilege_level   # escalation only'
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <user-assigned managed identity>
  permissions:
  - Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
  - Microsoft.Compute/virtualMachines/write
  - runCommand/extensions
  conditions:
  - role_compatibility
  derived_from:
  - <CanPassIdentity edge_id>
  - <CanAttachIdentity edge_id>
  - <CanExecuteCommand edge_id>
  false_positive_note: Requires the attach chain (CanPassIdentity via assign/action + VM write) AND a
    code-exec primitive on that VM. This is the EXISTING-VM chain (attach MI, then run) so it emits CanExecuteAs,
    not CanCreateWorkloadAs. Escalation only if the attached MI out-privileges the caller.
  narrative: '{principal.name} can attach user-assigned MI {userMI.name} to VM {vm.name} it can run code
    on, then mint {userMI.name}''s token from IMDS, executing as {userMI.name}.'
move · open · esc close