aws-emr-execute-as-add-steps
Submit a step to a running EMR cluster via AddJobFlowSteps; the step executes as the cluster's instance profile role without iam:PassRole.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?cluster) ==
AnalyticsService
?cluster provider_type == AWS::EMR::Cluster
cluster state is WAITING or RUNNING
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | ?principal |
| target | ?role |
| permissions | elasticmapreduce:AddJobFlowSteps |
| conditions | service_state |
| state logic | ACTIVE when the cluster is in WAITING or RUNNING state (service_state satisfied) and the principal has EFFECTIVE elasticmapreduce:AddJobFlowSteps on the cluster. CONDITIONAL(service_state) when the cluster state is unknown or BOOTSTRAPPING. Inherit weakest with the contributing CanModifyCode / ExecutesAs: a BLOCKED CanModifyCode (SCP/permission-boundary deny on AddJobFlowSteps) => BLOCKED. |
Narrative
{principal.name} can submit steps to EMR cluster {cluster.name} (elasticmapreduce:AddJobFlowSteps); submitted steps execute as the cluster's instance profile role {role.name} - no iam:PassRole required. This is the primary EMR escalation path.
Raw rule rules/derived/aws/emr.yaml
id: aws-emr-execute-as-add-steps
emits: CanExecuteAs
description: Submit a step to a running EMR cluster via AddJobFlowSteps; the step executes as the cluster's
instance profile role without iam:PassRole.
match:
- - principal: null
- CanModifyCode
- cluster: null
- - cluster: null
- ExecutesAs
- role: null
where:
- node_type(?cluster) == AnalyticsService
- ?cluster provider_type == AWS::EMR::Cluster
- cluster state is WAITING or RUNNING
emit:
source_type: Identity
target_type: Identity
source: ?principal
target: ?role
permissions:
- elasticmapreduce:AddJobFlowSteps
conditions:
- service_state
state_logic: 'ACTIVE when the cluster is in WAITING or RUNNING state (service_state satisfied) and the
principal has EFFECTIVE elasticmapreduce:AddJobFlowSteps on the cluster. CONDITIONAL(service_state)
when the cluster state is unknown or BOOTSTRAPPING. Inherit weakest with the contributing CanModifyCode
/ ExecutesAs: a BLOCKED CanModifyCode (SCP/permission-boundary deny on AddJobFlowSteps) => BLOCKED.'
confidence: min(contributing_confidences) * 0.97
derived_from:
- <CanModifyCode(aws-emr-add-steps-code) edge_id>
- <ExecutesAs(aws-emr-executes-as-instance-profile) edge_id>
false_positive_note: "AddJobFlowSteps does NOT require iam:PassRole \u2014 do not add that as a precondition.\
\ The submitted step runs as the cluster's existing instance profile (JobFlowRole). Only valid on\
\ clusters in WAITING or RUNNING state. Do not emit for clusters where AddJobFlowSteps is blocked\
\ by an SCP or permission boundary. This dedupes with can-execute-as execute-as-via-code-modify on\
\ (CanExecuteAs, ?principal, ?role) \u2014 same collapse, EMR-specific framing; do not double-count\
\ weight. Escalation roll-up to CanEscalateTo is can-control escalate-via-execute-as \u2014 CITE,\
\ do not re-derive."
narrative: "{principal.name} can submit steps to EMR cluster {cluster.name} (elasticmapreduce:AddJobFlowSteps);\
\ submitted steps execute as the cluster's instance profile role {role.name} \u2014 no iam:PassRole\
\ required. This is the primary EMR escalation path."