aws-sf-can-schedule-via-scheduler
Creating an EventBridge Scheduler schedule that targets a Step Functions state machine is persistence: it fires on a cadence with an optional execution role, running the state machine without further attacker action.
match (effective permission)
{
"action": "scheduler:CreateSchedule",
"resource_type": "AWS::Scheduler::Schedule"
}
where
schedule target is a Step Functions state machine ARN
principal also has effective iam:PassRole for the
Scheduler execution role (or uses an existing role)
emit
| source type | Identity |
|---|---|
| target type | Scheduler |
| source | <principal> |
| target | <EventBridge Scheduler (Scheduler)> |
| permissions | scheduler:CreateSchedule iam:PassRole |
| conditions | iam_permission role_compatibility |
| state logic | ACTIVE when the principal has effective scheduler:CreateSchedule AND iam:PassRole for the Scheduler execution role (which must allow the scheduler service). CONDITIONAL(role_compatibility) when the role or PassRole is uncertain. The schedule fires on its configured cadence — a persistence primitive independent of further attacker action. |
Narrative
{principal.name} can create an EventBridge Scheduler schedule targeting state machine {stateMachine.name} (scheduler:CreateSchedule + iam:PassRole), establishing a time-based trigger that fires executions on a cadence without further attacker action.
Raw rule rules/derived/aws/stepfunctions.yaml
id: aws-sf-can-schedule-via-scheduler
emits: CanSchedule
description: 'Creating an EventBridge Scheduler schedule that targets a Step Functions state machine is
persistence: it fires on a cadence with an optional execution role, running the state machine without
further attacker action.'
match_effective_permission:
action: scheduler:CreateSchedule
resource_type: AWS::Scheduler::Schedule
where:
- schedule target is a Step Functions state machine ARN
- principal also has effective iam:PassRole for the Scheduler execution role (or uses an existing role)
emit:
source_type: Identity
target_type: Scheduler
source: <principal>
target: <EventBridge Scheduler (Scheduler)>
permissions:
- scheduler:CreateSchedule
- iam:PassRole
conditions:
- iam_permission
- role_compatibility
state_logic: "ACTIVE when the principal has effective scheduler:CreateSchedule AND iam:PassRole for\
\ the Scheduler execution role (which must allow the scheduler service). CONDITIONAL(role_compatibility)\
\ when the role or PassRole is uncertain. The schedule fires on its configured cadence \u2014 a persistence\
\ primitive independent of further attacker action."
derived_from:
- effective scheduler:CreateSchedule + iam:PassRole (EventBridge Scheduler)
false_positive_note: CanSchedule here targets the Scheduler node. messaging-chains rule 3 (messaging-schedule-persists-executes-as)
requires both CanSchedule (?schedule) AND CanPassIdentity(?identity) where ?identity is the Scheduler
execution role. The Scheduler execution role is passed via iam:PassRole scoped to scheduler.amazonaws.com.
Unlike EventBridge rules (events:PutRule), Scheduler schedules always run with an explicitly-set execution
role; this path is the primary way to establish persistence in Scheduler for Step Functions.
narrative: '{principal.name} can create an EventBridge Scheduler schedule targeting state machine {stateMachine.name}
(scheduler:CreateSchedule + iam:PassRole), establishing a time-based trigger that fires executions
on a cadence without further attacker action.'