azure-aci-create-workload-as
Deploy a NEW container group with a privileged user-assigned MI attached, run it, and execute as the MI.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanPassIdentity {'userMI': None}
{'principal': None} CanAttachIdentity {'group': None}
{'principal': None} CanDeploy {'group': None}
where
?userMI is the identity carried on the
CanAttachIdentity edge (evidence.passable_identity == ?userMI), i.e. the MI attachable to ?group
?userMI.privilege_level >= ?principal.privilege_level
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | <principal> |
| target | <user-assigned managed identity> |
| permissions | Microsoft.ManagedIdentity/userAssignedIdentities/assign/action Microsoft.ContainerInstance/containerGroups/write |
| conditions | role_compatibility |
Narrative
{principal.name} can deploy a new container group with user-assigned MI {userMI.name} attached (assign/action + containerGroups/write), executing attacker code as {userMI.name}.
Raw rule rules/derived/azure/aci.yaml
id: azure-aci-create-workload-as
emits: CanCreateWorkloadAs
description: Deploy a NEW container group with a privileged user-assigned MI attached, run it, and execute
as the MI.
match:
- - principal: null
- CanPassIdentity
- userMI: null
- - principal: null
- CanAttachIdentity
- group: null
- - principal: null
- CanDeploy
- group: null
where:
- ?userMI is the identity carried on the CanAttachIdentity edge (evidence.passable_identity == ?userMI),
i.e. the MI attachable to ?group
- ?userMI.privilege_level >= ?principal.privilege_level
emit:
source_type: Identity
target_type: Identity
source: <principal>
target: <user-assigned managed identity>
permissions:
- Microsoft.ManagedIdentity/userAssignedIdentities/assign/action
- Microsoft.ContainerInstance/containerGroups/write
conditions:
- role_compatibility
derived_from:
- <CanPassIdentity edge_id>
- <CanAttachIdentity edge_id>
- <CanDeploy edge_id>
false_positive_note: Requires the attach chain (assign/action + containerGroups/write). ?userMI is bound
via CanPassIdentity and cross-checked against the CanAttachIdentity edge's evidence.passable_identity
for ?group so the privilege_level guard has a real binding. The new group runs the attacker image
immediately (restartPolicy Always/OnFailure), so no separate exec is needed. Escalation only if the
attached MI out-privileges the caller.
narrative: '{principal.name} can deploy a new container group with user-assigned MI {userMI.name} attached
(assign/action + containerGroups/write), executing attacker code as {userMI.name}.'