aws-ssm-start-automation-trigger

ssm:StartAutomationExecution triggers an existing Automation BuildWorker runner that executes as its AutomationAssumeRole.

derived aws emits CanTrigger

match

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

{'principal': None} HasPermission {'document': None} {'runner': None} ExecutesAs {'role': None}

where

effective_action == 'ssm:StartAutomationExecution' node_type(?document) == AutomationService ?document.document_type == 'Automation' node_type(?runner) == BuildWorker ?runner.document_arn == ?document.arn # runner is the Automation execution context for this document

emit

source typeIdentity
target typeBuildWorker
source?principal
target?runner
permissionsssm:StartAutomationExecution
conditionsiam_permission
state logicACTIVE when ssm:StartAutomationExecution is EFFECTIVE on the document ARN. The trigger itself is ACTIVE (the principal can start an execution); whether that execution yields the AutomationAssumeRole's credentials to the attacker depends on whether the document definition already runs attacker-controllable code — that is cicd-chains:cicd-trigger-runner-executes-as's judgment (CONDITIONAL(attacker_influenced_definition) by default). BLOCKED when an SCP denies ssm:StartAutomationExecution.

Narrative

{principal.name} can trigger runner {runner.name} via ssm:StartAutomationExecution on document {document.name}; if the document's steps already run attacker- influenceable code, this yields execution as {role.name}.

Raw rule rules/derived/aws/ssm.yaml

id: aws-ssm-start-automation-trigger
emits: CanTrigger
description: ssm:StartAutomationExecution triggers an existing Automation BuildWorker runner that executes
  as its AutomationAssumeRole.
match:
- - principal: null
  - HasPermission
  - document: null
- - runner: null
  - ExecutesAs
  - role: null
where:
- effective_action == 'ssm:StartAutomationExecution'
- node_type(?document) == AutomationService
- ?document.document_type == 'Automation'
- node_type(?runner) == BuildWorker
- '?runner.document_arn == ?document.arn  # runner is the Automation execution context for this document'
emit:
  source_type: Identity
  target_type: BuildWorker
  source: ?principal
  target: ?runner
  permissions:
  - ssm:StartAutomationExecution
  conditions:
  - iam_permission
  state_logic: "ACTIVE when ssm:StartAutomationExecution is EFFECTIVE on the document ARN. The trigger\
    \ itself is ACTIVE (the principal can start an execution); whether that execution yields the AutomationAssumeRole's\
    \ credentials to the attacker depends on whether the document definition already runs attacker-controllable\
    \ code \u2014 that is cicd-chains:cicd-trigger-runner-executes-as's judgment (CONDITIONAL(attacker_influenced_definition)\
    \ by default). BLOCKED when an SCP denies ssm:StartAutomationExecution."
  confidence: 0.9
  derived_from:
  - effective ssm:StartAutomationExecution on ?document
  - ?runner ExecutesAs ?role
  false_positive_note: "Triggering is strictly weaker than code modification (0.7 prior in cicd-chains).\
    \ Do NOT emit CanExecuteAs here \u2014 that is cicd-chains' job off this CanTrigger plus the runner's\
    \ ExecutesAs. A caller who both CanModifyCode and CanTrigger the same runner: cicd-chains rule 1 (ACTIVE)\
    \ dominates over rule 2 (CONDITIONAL) \u2014 do not double-count. If AutomationAssumeRole is NOT specified\
    \ and the Automation runs in the caller's context, the caller already IS the identity; no CanTrigger\
    \ toward a new identity is needed (no-op for escalation). The target is the BuildWorker runner (Compute-class),\
    \ not the AutomationService document node, to satisfy CanTrigger.target = [Compute] per schema/edges.yaml."
  narrative: '{principal.name} can trigger runner {runner.name} via ssm:StartAutomationExecution on document
    {document.name}; if the document''s steps already run attacker- influenceable code, this yields execution
    as {role.name}.'
move · open · esc close