azure-arm-templatespec-write

Overwrite a template spec version to inject a deploymentScript into all deployments that reference it.

derived azure emits CanModifyCode

match (effective permission)

{ "action": "Microsoft.Resources/templateSpecs/versions/write", "scope_type": "resource|resourceGroup|subscription" }

where

one or more ARM deployments reference this template spec version (or latestVersion)

emit

source typeIdentity
target typeArtifactRepository
source<principal>
target<template spec (ArtifactRepository)>
permissionsMicrosoft.Resources/templateSpecs/versions/write
conditionstrigger_exists
state logicACTIVE when a consuming deployment references the spec by `latestVersion` (mutable) AND auto-redeploys on version update (e.g., a CI/CD pipeline webhook or scheduled re-deploy on spec version change exists). CONDITIONAL(trigger_exists) when a consuming deployment uses `latestVersion` but requires manual re-trigger by the attacker (or another admin) to pick up the new version — modifying the spec alone does not guarantee execution without that trigger. If the consuming deployment pins a specific immutable version number (e.g. `v2.0.0`), the write does not affect it and this edge is NOT emitted for that deployment.

Narrative

{principal.name} can write a new version of template spec {target.name} (Microsoft.Resources/templateSpecs/versions/write), injecting a deploymentScript resource carrying attacker-controlled code; any downstream deployment that re-deploys this spec will execute that code as the UAMI named in the injected script. cicd-chains (cicd-modify-buildspec-executes-as) rolls up CanModifyCode on the consuming deployment + its ExecutesAs(UAMI) into CanExecuteAs(UAMI).

Raw rule rules/derived/azure/arm-deployments.yaml

id: azure-arm-templatespec-write
emits: CanModifyCode
description: Overwrite a template spec version to inject a deploymentScript into all deployments that
  reference it.
match_effective_permission:
  action: Microsoft.Resources/templateSpecs/versions/write
  scope_type: resource|resourceGroup|subscription
where:
- one or more ARM deployments reference this template spec version (or latestVersion)
emit:
  source_type: Identity
  target_type: ArtifactRepository
  source: <principal>
  target: <template spec (ArtifactRepository)>
  permissions:
  - Microsoft.Resources/templateSpecs/versions/write
  conditions:
  - trigger_exists
  state_logic: "ACTIVE when a consuming deployment references the spec by `latestVersion` (mutable) AND\
    \ auto-redeploys on version update (e.g., a CI/CD pipeline webhook or scheduled re-deploy on spec\
    \ version change exists).  CONDITIONAL(trigger_exists) when a consuming deployment uses `latestVersion`\
    \ but requires manual re-trigger by the attacker (or another admin) to pick up the new version \u2014\
    \ modifying the spec alone does not guarantee execution without that trigger.  If the consuming deployment\
    \ pins a specific immutable version number (e.g. `v2.0.0`), the write does not affect it and this\
    \ edge is NOT emitted for that deployment."
  false_positive_note: "A deployment that pins a SPECIFIC version number (e.g. `v2.0.0`) is unaffected\
    \ by a new version write; only deployments using `latestVersion` or a mutable reference propagate\
    \ this CanModifyCode.  Confirm that a re-deploy of the consuming pipeline is possible (the attacker\
    \ can trigger it OR it runs automatically on update) \u2014 absent a run path, use CONDITIONAL(trigger_exists)\
    \ not ACTIVE.  container-chains does not apply here (this is IaC, not an OCI image registry); cicd-chains\
    \ rule 1 consumes the resulting CanModifyCode on the consuming BuildWorker once the new version is\
    \ deployed."
  narrative: '{principal.name} can write a new version of template spec {target.name} (Microsoft.Resources/templateSpecs/versions/write),
    injecting a deploymentScript resource carrying attacker-controlled code; any downstream deployment
    that re-deploys this spec will execute that code as the UAMI named in the injected script.  cicd-chains
    (cicd-modify-buildspec-executes-as) rolls up CanModifyCode on the consuming deployment + its ExecutesAs(UAMI)
    into CanExecuteAs(UAMI).'
  derived_from:
  - azure-arm-templatespec-write (match_effective_permission)
  - 'cicd-chains: cicd-modify-buildspec-executes-as (roll-up via consuming deployment)'
move · open · esc close