aws-opsworks-create-deployment-modifies-code

opsworks:CreateDeployment lets a principal run arbitrary Chef recipes or commands on stack instances as the instance profile role.

derived aws emits CanModifyCode

match

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

{'principal': None} HasPermission {'stack': None}

where

node_type(?stack) == ApplicationPlatform ?stack.provider_type == 'AWS::OpsWorks::Stack' ?principal has effective opsworks:CreateDeployment on ?stack (resource scope: stack ARN or *) ?stack has at least one ONLINE instance (service_state == ONLINE)

emit

source typeIdentity
target typeVirtualMachine
source?principal
target<ONLINE OpsWorks-managed EC2 instances in ?stack>
permissionsopsworks:CreateDeployment
conditionsservice_state
state logicACTIVE when at least one instance in the stack is in ONLINE state (Chef agent responsive). CONDITIONAL(service_state) when all instances are stopped, starting, or in setup/configure lifecycle. BLOCKED when an SCP or permission boundary denies opsworks:CreateDeployment. Do NOT emit when the stack's service_state is OFFLINE/TERMINATED (no running instances to receive the command).

Narrative

{principal.name} can run a deployment (opsworks:CreateDeployment) on stack {stack.name}, executing arbitrary Chef recipes or shell commands on its instances (execute_recipes / run_command) as the instance profile role. The cicd-chains linchpin then derives CanExecuteAs(principal -> instance_profile).

Raw rule rules/derived/aws/opsworks.yaml

id: aws-opsworks-create-deployment-modifies-code
emits: CanModifyCode
description: opsworks:CreateDeployment lets a principal run arbitrary Chef recipes or commands on stack
  instances as the instance profile role.
match:
- - principal: null
  - HasPermission
  - stack: null
where:
- node_type(?stack) == ApplicationPlatform
- ?stack.provider_type == 'AWS::OpsWorks::Stack'
- '?principal has effective opsworks:CreateDeployment on ?stack (resource scope: stack ARN or *)'
- ?stack has at least one ONLINE instance (service_state == ONLINE)
emit:
  source_type: Identity
  target_type: VirtualMachine
  source: ?principal
  target: <ONLINE OpsWorks-managed EC2 instances in ?stack>
  permissions:
  - opsworks:CreateDeployment
  conditions:
  - service_state
  state_logic: ACTIVE when at least one instance in the stack is in ONLINE state (Chef agent responsive).
    CONDITIONAL(service_state) when all instances are stopped, starting, or in setup/configure lifecycle.
    BLOCKED when an SCP or permission boundary denies opsworks:CreateDeployment. Do NOT emit when the
    stack's service_state is OFFLINE/TERMINATED (no running instances to receive the command).
  confidence: 0.9
  derived_from:
  - ?principal HasPermission ?stack (opsworks:CreateDeployment)
  - cicd-chains cicd-modify-buildspec-executes-as (cited, not re-derived)
  false_positive_note: "opsworks:CreateDeployment covers multiple command types (deploy, rollback, execute_recipes,\
    \ run_command, configure, update_custom_cookbooks, etc.). ALL subtypes grant this edge because IAM\
    \ does not discriminate by deployment command type \u2014 a principal with CreateDeployment can always\
    \ supply execute_recipes. Confidence 0.9 reflects this (not 1.0) because the attacker must also supply\
    \ valid recipe names; for run_command, arbitrary shell is directly injectable. Emit CONDITIONAL(service_state)\
    \ when no instances are ONLINE. This is the OpsWorks-framing of cicd-modify-buildspec-executes-as\
    \ \u2014 dedupes with that rule on (CanModifyCode, ?principal, ?instance)."
  narrative: '{principal.name} can run a deployment (opsworks:CreateDeployment) on stack {stack.name},
    executing arbitrary Chef recipes or shell commands on its instances (execute_recipes / run_command)
    as the instance profile role. The cicd-chains linchpin then derives CanExecuteAs(principal -> instance_profile).'
move · open · esc close