aws-sagemaker-create-workload-as
Create a new SageMaker compute resource (training/processing job, notebook, pipeline) bound to a passed privileged role - the canonical SageMaker PassRole privesc pattern.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?principal has one or more of: sagemaker:CreateTrainingJob, sagemaker:CreateProcessingJob, sagemaker:CreateNotebookInstance, sagemaker:CreatePipeline
?role trust policy allows sagemaker.amazonaws.com
iam:PassRole condition iam:PassedToService (if present) includes sagemaker.amazonaws.com
emit
| source type | Identity |
|---|---|
| target type | MachineIdentity |
| source | ?principal |
| target | ?role |
| permissions | iam:PassRole sagemaker:CreateTrainingJob|sagemaker:CreateProcessingJob|sagemaker:CreateNotebookInstance|sagemaker:CreatePipeline |
| conditions | role_compatibility iam_permission |
| state logic | ACTIVE when the role trust and iam:PassedToService admit sagemaker.amazonaws.com; POTENTIAL(role_compatibility) when trust is unknown or unresolved; CONDITIONAL(iam_permission) when the create permission is missing. The escalation roll-up (CanCreateWorkloadAs -> CanExecuteAs) is produced by can-execute-as.yaml execute-as-via-new-workload — cite, do not re-derive. |
Narrative
{principal.name} can create a SageMaker compute resource (training/processing job, notebook, or pipeline) and bind {role.name} to it (iam:PassRole + Create*Job/CreateNotebookInstance/CreatePipeline), causing attacker-controlled code to run as {role.name}.
Raw rule rules/derived/aws/sagemaker.yaml
id: aws-sagemaker-create-workload-as
emits: CanCreateWorkloadAs
description: "Create a new SageMaker compute resource (training/processing job, notebook, pipeline) bound\
\ to a passed privileged role \u2014 the canonical SageMaker PassRole privesc pattern."
match:
- - principal: null
- CanPassIdentity
- role: null
where:
- '?principal has one or more of: sagemaker:CreateTrainingJob, sagemaker:CreateProcessingJob, sagemaker:CreateNotebookInstance,
sagemaker:CreatePipeline'
- ?role trust policy allows sagemaker.amazonaws.com
- iam:PassRole condition iam:PassedToService (if present) includes sagemaker.amazonaws.com
emit:
source_type: Identity
target_type: MachineIdentity
source: ?principal
target: ?role
permissions:
- iam:PassRole
- sagemaker:CreateTrainingJob|sagemaker:CreateProcessingJob|sagemaker:CreateNotebookInstance|sagemaker:CreatePipeline
conditions:
- role_compatibility
- iam_permission
state_logic: "ACTIVE when the role trust and iam:PassedToService admit sagemaker.amazonaws.com; POTENTIAL(role_compatibility)\
\ when trust is unknown or unresolved; CONDITIONAL(iam_permission) when the create permission is missing.\
\ The escalation roll-up (CanCreateWorkloadAs -> CanExecuteAs) is produced by can-execute-as.yaml\
\ execute-as-via-new-workload \u2014 cite, do not re-derive."
confidence: min(contributing_confidences) * 0.95
derived_from:
- '<CanPassIdentity edge: principal -> role>'
false_positive_note: "This rule implements a DEVIATION from the canonical CanCreateWorkloadAs derivation\
\ (edges.yaml \xA7423: CanDeploy + CanPassIdentity + role_compatible => CanCreateWorkloadAs). For\
\ SageMaker, the create action (CreateTrainingJob/CreateNotebookInstance/etc.) doubles as the deployment\
\ primitive; no separate \"CanDeploy\" edge is emitted. The where-clause check on create permission\
\ substitutes for the CanDeploy edge. RATIONALE: SageMaker conflates workload creation and code submission\
\ into a single action, whereas Lambda/Batch model creation (CanDeploy) separately from identity attachment.\
\ This rule preserves the correct semantics while deviating from the canonical form for practical\
\ alignment with SageMaker's API model.\nHonor iam:PassedToService strictly: a role passable only\
\ to lambda.amazonaws.com or ec2.amazonaws.com does NOT qualify. The role must trust sagemaker.amazonaws.com\
\ in its AssumeRolePolicyDocument. Do not escalate if the passed role has equal or lower privilege."
narrative: '{principal.name} can create a SageMaker compute resource (training/processing job, notebook,
or pipeline) and bind {role.name} to it (iam:PassRole + Create*Job/CreateNotebookInstance/CreatePipeline),
causing attacker-controlled code to run as {role.name}.'