aws-codepipeline-trigger-executes-as

StartPipelineExecution over a pipeline whose current definition already runs attacker-influenced code (poisoned artifact, malicious source commit, unpinned dependency) yields execution as the pipeline's service/action role; cicd-chains rule 2 is the canonical collapse (CONDITIONAL).

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 {'service_role': None}

where

node_type(?pipeline) == BuildWorker ?pipeline.provider_type == 'AWS::CodePipeline::Pipeline'

emit

source typeIdentity
target typeIdentity
source?principal
target?service_role
permissionscodepipeline:StartPipelineExecution
conditionsattacker_influenced_definition
state logicCONDITIONAL(attacker_influenced_definition) by default: triggering runs the CURRENT definition, which yields the service role only if that definition already runs attacker-influenceable code (mutable/unpinned artifact dependency, attacker-authored source branch the trigger builds, already-tampered stage spec, or a build step that runs untrusted PR content). ACTIVE only when attacker influence over the current definition is established (then it collapses to the modify path). A trigger over a fully pinned, reviewed, clean definition stays CONDITIONAL. Inherit weakest with CanTrigger / ExecutesAs contributions.

Narrative

{principal.name} can start pipeline {pipeline.name} (codepipeline:StartPipelineExecution), which executes as {service_role.name}; if the pipeline's current definition already runs attacker-influenceable code (poisoned dependency, attacker-authored source, tampered stage spec), this run executes as {service_role.name}.

Raw rule rules/derived/aws/codepipeline.yaml

id: aws-codepipeline-trigger-executes-as
emits: CanExecuteAs
description: StartPipelineExecution over a pipeline whose current definition already runs attacker-influenced
  code (poisoned artifact, malicious source commit, unpinned dependency) yields execution as the pipeline's
  service/action role; cicd-chains rule 2 is the canonical collapse (CONDITIONAL).
match:
- - principal: null
  - CanTrigger
  - pipeline: null
- - pipeline: null
  - ExecutesAs
  - service_role: null
where:
- node_type(?pipeline) == BuildWorker
- ?pipeline.provider_type == 'AWS::CodePipeline::Pipeline'
emit:
  source_type: Identity
  target_type: Identity
  source: ?principal
  target: ?service_role
  permissions:
  - codepipeline:StartPipelineExecution
  conditions:
  - attacker_influenced_definition
  state_logic: 'CONDITIONAL(attacker_influenced_definition) by default: triggering runs the CURRENT definition,
    which yields the service role only if that definition already runs attacker-influenceable code (mutable/unpinned
    artifact dependency, attacker-authored source branch the trigger builds, already-tampered stage spec,
    or a build step that runs untrusted PR content). ACTIVE only when attacker influence over the current
    definition is established (then it collapses to the modify path). A trigger over a fully pinned, reviewed,
    clean definition stays CONDITIONAL. Inherit weakest with CanTrigger / ExecutesAs contributions.'
  confidence: min(contributing_confidences) * 0.7
  derived_from:
  - ?principal CanTrigger ?pipeline
  - ?pipeline ExecutesAs ?service_role
  - 'cicd-chains: cicd-trigger-runner-executes-as'
  false_positive_note: "Strictly weaker than the modify path (0.7 prior). Do NOT emit ACTIVE merely because\
    \ the principal can start a pipeline execution \u2014 the current definition must already run attacker-influenceable\
    \ code. Classic ACTIVE cases: a pipeline whose Source stage pulls from a repo branch the attacker\
    \ can push to without review (the push both modifies and triggers), or an artifact dependency the\
    \ attacker can poison (unpinned package published to an attacker-accessible registry). A fully pinned,\
    \ reviewed pipeline definition is CONDITIONAL only. Dedupes with aws-codepipeline-update- pipeline-executes-as\
    \ when the principal can BOTH modify and trigger \u2014 the ACTIVE modify edge dominates, do not double-count."
  narrative: '{principal.name} can start pipeline {pipeline.name} (codepipeline:StartPipelineExecution),
    which executes as {service_role.name}; if the pipeline''s current definition already runs attacker-influenceable
    code (poisoned dependency, attacker-authored source, tampered stage spec), this run executes as {service_role.name}.'
move · open · esc close