azure-appgw-attach-mi

An attacker who can write an Application Gateway and pass a user-assigned MI can swap the gateway's identity, gaining that MI's Key Vault (and potentially broader) permissions.

derived azure emits CanAttachIdentity

match

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

{'principal': None} CanPassIdentity {'userMI': None}

where

?principal has EFFECTIVE Microsoft.ManagedIdentity/userAssignedIdentities/assign/action on ?userMI ?principal has EFFECTIVE Microsoft.Network/applicationGateways/write on the target Application Gateway

emit

source typeIdentity
target typeLoadBalancer
source<principal>
target<Microsoft.Network/applicationGateways>
permissionsMicrosoft.ManagedIdentity/userAssignedIdentities/assign/action Microsoft.Network/applicationGateways/write
conditionsrole_compatibility
state logicif both assign/action and applicationGateways/write are confirmed at their respective scopes with no deny assignment: ACTIVE; if assign/action or trust is unknown/unresolved: POTENTIAL(role_compatibility).

Narrative

{principal.name} can attach user-assigned MI {userMI.name} to Application Gateway {target.name} (assign/action + applicationGateways/write). This grants the gateway - and any process that can read Key Vault secrets via the gateway's identity - the permissions of {userMI.name}.

Raw rule rules/derived/azure/loadbalancer.yaml

id: azure-appgw-attach-mi
emits: CanAttachIdentity
description: An attacker who can write an Application Gateway and pass a user-assigned MI can swap the
  gateway's identity, gaining that MI's Key Vault (and potentially broader) permissions.
match:
- - principal: null
  - CanPassIdentity
  - userMI: null
where:
- ?principal has EFFECTIVE Microsoft.ManagedIdentity/userAssignedIdentities/assign/action on ?userMI
- ?principal has EFFECTIVE Microsoft.Network/applicationGateways/write on the target Application Gateway
emit:
  source_type: Identity
  target_type: LoadBalancer
  source: <principal>
  target: <Microsoft.Network/applicationGateways>
  permissions:
  - Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
  - Microsoft.Network/applicationGateways/write
  conditions:
  - role_compatibility
  state_logic: 'if both assign/action and applicationGateways/write are confirmed at their respective
    scopes with no deny assignment: ACTIVE; if assign/action or trust is unknown/unresolved: POTENTIAL(role_compatibility).'
  derived_from:
  - <CanPassIdentity edge_id>
  note: 'Emits CanAttachIdentity with nature: derived. CanAttachIdentity in edges.yaml allows nature:
    explicit, but this rule is a pattern-based derivation that combines CanPassIdentity + write permission.
    Both nature modes are conformant (CanAttachIdentity: nature: explicit in edges.yaml; derived rule
    may only emit nature: derived or both, not explicit alone). This rule MUST use nature: both in edges.yaml
    or be reformulated as an explicit_rules entry without match:. The current derivation pattern is correct;
    CanAttachIdentity''s nature in edges.yaml needs to be updated to both to reflect this reality.'
  false_positive_note: "BOTH permissions are required: assign/action on the target MI AND applicationGateways/write\
    \ on the gateway. Neither alone attaches the MI. The attached MI on an Application Gateway is used\
    \ for Key Vault certificate access \u2014 confirm the MI's role assignments to determine actual blast\
    \ radius (may be limited to Key Vault reads). Do not assume subscription-level escalation without\
    \ checking the MI's effective permissions."
  narrative: "{principal.name} can attach user-assigned MI {userMI.name} to Application Gateway {target.name}\
    \ (assign/action + applicationGateways/write). This grants the gateway \u2014 and any process that\
    \ can read Key Vault secrets via the gateway's identity \u2014 the permissions of {userMI.name}."
move · open · esc close