aws-eb-scheduler-executes-as
An EventBridge Scheduler schedule assumes its Target.RoleArn (via scheduler.amazonaws.com) at each fire; anyone who can modify the schedule or the role effectively runs as that role on a cadence.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'schedule_record': None}
HasProperty Target.RoleArn
where
node_type(?schedule_record) ==
Scheduler
?schedule_record.Target.RoleArn is set
?role is the IAM role at ?schedule_record.Target.RoleArn
emit
| source type | Messaging |
|---|---|
| target type | Role |
| source | ?schedule_record |
| target | ?role |
| conditions | trust_relationship |
| state logic | ACTIVE when the role trust policy allows scheduler.amazonaws.com to assume it and the schedule is ENABLED. CONDITIONAL(service_state) when the schedule state is DISABLED. CONDITIONAL(trust_relationship) when the trust policy is unknown. BLOCKED when the role does not trust scheduler.amazonaws.com or an SCP denies sts:AssumeRole for that principal. |
Narrative
{schedule.name} assumes {role.name} (via scheduler.amazonaws.com) at each scheduled fire; an attacker who can create or modify the schedule and pass the role obtains persistent execution as {role.name}.
Raw rule rules/derived/aws/eventbridge.yaml
id: aws-eb-scheduler-executes-as
emits: ExecutesAs
description: An EventBridge Scheduler schedule assumes its Target.RoleArn (via scheduler.amazonaws.com)
at each fire; anyone who can modify the schedule or the role effectively runs as that role on a cadence.
match:
- - schedule_record: null
- HasProperty
- Target.RoleArn
where:
- node_type(?schedule_record) == Scheduler
- ?schedule_record.Target.RoleArn is set
- ?role is the IAM role at ?schedule_record.Target.RoleArn
emit:
source_type: Messaging
target_type: Role
source: ?schedule_record
target: ?role
permissions: []
conditions:
- trust_relationship
state_logic: ACTIVE when the role trust policy allows scheduler.amazonaws.com to assume it and the schedule
is ENABLED. CONDITIONAL(service_state) when the schedule state is DISABLED. CONDITIONAL(trust_relationship)
when the trust policy is unknown. BLOCKED when the role does not trust scheduler.amazonaws.com or
an SCP denies sts:AssumeRole for that principal.
confidence: 0.95
derived_from:
- "scheduler:GetSchedule \u2192 Target.RoleArn, State"
false_positive_note: The execution role is assumed by the SCHEDULER SERVICE, not the attacker directly.
The attack path requires either (a) CanTrigger(attacker, schedule) + this ExecutesAs => CanExecuteAs
(via messaging-chains rule 2); or (b) CanSchedule + CanPassIdentity => CanExecuteAs (via messaging-chains
rule 3, persistence). A schedule in DISABLED state contributes CONDITIONAL(service_state) to the chain,
not ACTIVE. Honor iam:PassedToService for scheduler.amazonaws.com when evaluating CanPassIdentity;
PassRole granted only for ec2/ecs does NOT yield this path.
narrative: '{schedule.name} assumes {role.name} (via scheduler.amazonaws.com) at each scheduled fire;
an attacker who can create or modify the schedule and pass the role obtains persistent execution as
{role.name}.'