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.

derived aws emits ExecutesAs

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 typeMessaging
target typeRole
source?schedule_record
target?role
conditionstrust_relationship
state logicACTIVE 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}.'
move · open · esc close