gcp-cloudscheduler-can-schedule

cloudscheduler.jobs.create lets a principal create a new cron job - the persistence and event-source creation primitive. This feeds messaging-chains rule 3 (messaging-schedule-persists-executes-as) when paired with CanPassIdentity.

derived gcp emits CanSchedule

match (effective permission)

{ "action": "cloudscheduler.jobs.create", "resource_type": "google.cloud.scheduler.v1.Job" }

emit

source typeIdentity
target typeScheduler
source<principal>
target<Cloud Scheduler job (Scheduler node) in scope>
permissionscloudscheduler.jobs.create
conditionsiam_permission api_enabled
state logicACTIVE when the principal holds cloudscheduler.jobs.create at project scope AND the Cloud Scheduler API is enabled. The created job starts ENABLED by default. BLOCKED if an IAM deny or org policy denies cloudscheduler.jobs.create.

Narrative

{principal.name} can create a Cloud Scheduler job (cloudscheduler.jobs.create) - a persistent scheduled trigger that fires on its cron cadence without further attacker action. Combined with CanPassIdentity (actAs on the OIDC/OAuth2 SA), messaging-chains rule 3 rolls this up to CanExecuteAs(SA).

Raw rule rules/derived/gcp/cloudscheduler.yaml

id: gcp-cloudscheduler-can-schedule
emits: CanSchedule
description: "cloudscheduler.jobs.create lets a principal create a new cron job \u2014 the persistence\
  \ and event-source creation primitive. This feeds messaging-chains rule 3 (messaging-schedule-persists-executes-as)\
  \ when paired with CanPassIdentity."
match_effective_permission:
  action: cloudscheduler.jobs.create
  resource_type: google.cloud.scheduler.v1.Job
emit:
  source_type: Identity
  target_type: Scheduler
  source: <principal>
  target: <Cloud Scheduler job (Scheduler node) in scope>
  permissions:
  - cloudscheduler.jobs.create
  derived_from:
  - 'effective permission: cloudscheduler.jobs.create on the project/location'
  conditions:
  - iam_permission
  - api_enabled
  state_logic: ACTIVE when the principal holds cloudscheduler.jobs.create at project scope AND the Cloud
    Scheduler API is enabled. The created job starts ENABLED by default. BLOCKED if an IAM deny or org
    policy denies cloudscheduler.jobs.create.
  false_positive_note: cloudscheduler.jobs.create is a project-level permission (Cloud Scheduler jobs
    have no individual resource IAM policy). Confirm the Cloud Scheduler API (cloudscheduler.googleapis.com)
    is enabled in the project. The created job is ENABLED immediately after creation and fires on its
    next scheduled time.
  narrative: "{principal.name} can create a Cloud Scheduler job (cloudscheduler.jobs.create) \u2014 a\
    \ persistent scheduled trigger that fires on its cron cadence without further attacker action. Combined\
    \ with CanPassIdentity (actAs on the OIDC/OAuth2 SA), messaging-chains rule 3 rolls this up to CanExecuteAs(SA)."
move · open · esc close