gcp-vertexai-create-workload-as-training

Create a Vertex AI custom training job / pipeline job / notebook execution job whose workers run as a passable SA (create + actAs). Job runs immediately on creation - no invoke step.

derived gcp emits CanCreateWorkloadAs

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanPassIdentity {'sa': None}

where

?principal has EFFECTIVE aiplatform.customJobs.create OR aiplatform.pipelineJobs.create OR aiplatform.notebookExecutionJobs.create in the target project/location ?principal has iam.serviceAccounts.actAs on ?sa (confirmed present)

emit

source typeIdentity
target typeServiceAccount
source<principal>
target<service account>
permissionsaiplatform.customJobs.create iam.serviceAccounts.actAs
conditionsiam_permission role_compatibility
state logicACTIVE if iam.serviceAccounts.actAs on ?sa is confirmed AND the job-create permission is present (the job runs immediately — no trigger_exists gate; contrast with GCF). POTENTIAL(iam_permission) if actAs is not confirmed on ?sa. BLOCKED if org policy iam.disableCrossProjectServiceAccountUsage is active AND ?sa is in a different project.

Narrative

{principal.name} can create a Vertex AI training job (aiplatform.customJobs.create) whose worker VMs run attacker-controlled code as {sa.name} (iam.serviceAccounts.actAs); the job runs on creation, no separate invocation needed.

Raw rule rules/derived/gcp/vertexai.yaml

id: gcp-vertexai-create-workload-as-training
emits: CanCreateWorkloadAs
description: "Create a Vertex AI custom training job / pipeline job / notebook execution job whose workers\
  \ run as a passable SA (create + actAs). Job runs immediately on creation \u2014 no invoke step."
match:
- - principal: null
  - CanPassIdentity
  - sa: null
where:
- ?principal has EFFECTIVE aiplatform.customJobs.create OR aiplatform.pipelineJobs.create OR aiplatform.notebookExecutionJobs.create
  in the target project/location
- ?principal has iam.serviceAccounts.actAs on ?sa (confirmed present)
emit:
  source_type: Identity
  target_type: ServiceAccount
  source: <principal>
  target: <service account>
  permissions:
  - aiplatform.customJobs.create
  - iam.serviceAccounts.actAs
  conditions:
  - iam_permission
  - role_compatibility
  state_logic: "ACTIVE if iam.serviceAccounts.actAs on ?sa is confirmed AND the job-create permission\
    \ is present (the job runs immediately \u2014 no trigger_exists gate; contrast with GCF). POTENTIAL(iam_permission)\
    \ if actAs is not confirmed on ?sa. BLOCKED if org policy iam.disableCrossProjectServiceAccountUsage\
    \ is active AND ?sa is in a different project."
  derived_from:
  - <CanPassIdentity edge_id>
  false_positive_note: "No invoke/trigger gating \u2014 Vertex AI custom training creates and runs in\
    \ a single API call. The attacker's container runs immediately with ?sa's credentials. actAs is required\
    \ on the exact SA; without it -> POTENTIAL. If the SA is cross-project AND iam.disableCrossProjectServiceAccountUsage\
    \ is active -> BLOCKED."
  narrative: '{principal.name} can create a Vertex AI training job (aiplatform.customJobs.create) whose
    worker VMs run attacker-controlled code as {sa.name} (iam.serviceAccounts.actAs); the job runs on
    creation, no separate invocation needed.'
move · open · esc close