azure-arm-templatespec-write
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 — 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)'