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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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 — 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}.'