aws-imagebuilder-trigger-executes-as

Trigger an Image Builder pipeline whose current definition already executes attacker-influenced code (e.g., an S3-overwritable component URI or an already-tampered component version), executing as the build instance role.

derived aws emits CanExecuteAs

match

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

{'principal': None} CanTrigger {'pipeline': None} {'pipeline': None} ExecutesAs {'role': None}

where

node_type(?pipeline) == BuildWorker ?pipeline.provider_type == 'AWS::ImageBuilder::ImagePipeline'

emit

source typeIdentity
target typeMachineIdentity
source?principal
target?role
permissionsimagebuilder:StartImagePipelineExecution
conditionsattacker_influenced_definition
state logicCONDITIONAL(attacker_influenced_definition) by default. ACTIVE only when the current pipeline definition already runs attacker-controllable code — specifically when a component in the recipe references an S3 URI that the attacker can overwrite (confirmed via ContainsResourceReference(component -> S3 bucket) + CanWrite(principal -> S3 bucket/key)), or when an attacker-authored component version is already the active version referenced by the recipe. Triggering a clean, customer-reviewed, pinned definition (no S3 URI components, no attacker-authored versions) is NOT an active execute-as — keep CONDITIONAL. Dedupes with rules 1-2 on (CanExecuteAs, ?principal, ?role) when the principal can also modify the definition — rule 1/2's ACTIVE dominates. Inherit weakest from CanTrigger and ExecutesAs. BLOCKED when an SCP denies imagebuilder:StartImagePipelineExecution.

Narrative

{principal.name} can trigger {pipeline.name} (imagebuilder:StartImagePipelineExecution), which runs as {role.name}. If the pipeline's current definition already executes attacker-influenced code (e.g., a component document at an S3 URI the attacker controls or an already-tampered component version), the build executes that code as {role.name}.

Raw rule rules/derived/aws/imagebuilder.yaml

id: aws-imagebuilder-trigger-executes-as
emits: CanExecuteAs
description: Trigger an Image Builder pipeline whose current definition already executes attacker-influenced
  code (e.g., an S3-overwritable component URI or an already-tampered component version), executing as
  the build instance role.
match:
- - principal: null
  - CanTrigger
  - pipeline: null
- - pipeline: null
  - ExecutesAs
  - role: null
where:
- node_type(?pipeline) == BuildWorker
- ?pipeline.provider_type == 'AWS::ImageBuilder::ImagePipeline'
emit:
  source_type: Identity
  target_type: MachineIdentity
  source: ?principal
  target: ?role
  permissions:
  - imagebuilder:StartImagePipelineExecution
  conditions:
  - attacker_influenced_definition
  state_logic: "CONDITIONAL(attacker_influenced_definition) by default. ACTIVE only when the current pipeline\
    \ definition already runs attacker-controllable code \u2014 specifically when a component in the recipe\
    \ references an S3 URI that the attacker can overwrite (confirmed via ContainsResourceReference(component\
    \ -> S3 bucket) + CanWrite(principal -> S3 bucket/key)), or when an attacker-authored component version\
    \ is already the active version referenced by the recipe. Triggering a clean, customer-reviewed, pinned\
    \ definition (no S3 URI components, no attacker-authored versions) is NOT an active execute-as \u2014\
    \ keep CONDITIONAL. Dedupes with rules 1-2 on (CanExecuteAs, ?principal, ?role) when the principal\
    \ can also modify the definition \u2014 rule 1/2's ACTIVE dominates. Inherit weakest from CanTrigger\
    \ and ExecutesAs. BLOCKED when an SCP denies imagebuilder:StartImagePipelineExecution."
  confidence: min(contributing_confidences) * 0.70
  derived_from:
  - ?principal CanTrigger ?pipeline (imagebuilder:StartImagePipelineExecution)
  - ?pipeline ExecutesAs ?role (instanceProfileName -> IAM role)
  - cicd-chains cicd-trigger-runner-executes-as (cited, deduped)
  false_positive_note: "Strictly weaker than rules 1-2 (0.70 prior): a trigger is not code control. Do\
    \ NOT emit ACTIVE merely because the principal can call StartImagePipelineExecution \u2014 the current\
    \ definition must already run attacker-influenced code. The classic ACTIVE case is a component with\
    \ a mutable S3 URI the attacker has already overwritten. A locked-down definition (all components\
    \ inline, no S3 URI, all AWS-managed) keeps this CONDITIONAL and is NOT an active escalation. When\
    \ rules 1-2 also apply, they subsume this edge at ACTIVE \u2014 do not double-count weight."
  narrative: '{principal.name} can trigger {pipeline.name} (imagebuilder:StartImagePipelineExecution),
    which runs as {role.name}. If the pipeline''s current definition already executes attacker-influenced
    code (e.g., a component document at an S3 URI the attacker controls or an already-tampered component
    version), the build executes that code as {role.name}.'
move · open · esc close