gcp-eventarc-execute-as-via-new-trigger

Create a new Eventarc trigger binding an event source to a destination consumer, then publish an event (or wait for a natural event) to run the consumer as its runtime SA. Provides the Eventarc-specific framing of messaging-chains rule 2.

derived gcp emits CanExecuteAs

match

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

{'principal': None} CanSchedule {'trigger': None} {'trigger': None} CanTrigger {'consumer': None} {'consumer': None} ExecutesAs {'sa': None}

where

node_type(?trigger) == EventRule node_class(?consumer) == Compute or node_type(?consumer) == Workflow ?sa.privilege_level >= ?principal.privilege_level

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'principal': None} CanWriteData {'src': None} {'src': None} CanTrigger {'trigger': None}

emit

source typeIdentity
target typeIdentity
source<principal>
target<consumer's runtime service account>
permissionseventarc.triggers.create iam.serviceAccounts.actAs pubsub.topics.publish
conditionstrigger_exists role_compatibility
state logicACTIVE when the CanSchedule gate is satisfied (trigger.create + actAs on trigger SA), the new trigger binding is confirmed live (CanTrigger(trigger → consumer) ACTIVE), AND matched(optional[0]) confirms the principal can publish an event to drive the trigger immediately. CONDITIONAL(trigger_exists) when the trigger is created but a natural event (Audit Log, GCS notification) drives it rather than a direct publish — the consumer will execute on the next matching event. POTENTIAL(role_compatibility) when actAs or the trigger SA's invoker rights on the consumer are unconfirmed. Inherits weakest contributor state.

Narrative

{principal.name} can create an Eventarc trigger binding an event source to {consumer.name}, which executes as {sa.name}; publishing a matching event (or waiting for a natural one) delivers an attacker-influenced payload to {consumer.name}, executing as {sa.name}.

Raw rule rules/derived/gcp/eventarc.yaml

id: gcp-eventarc-execute-as-via-new-trigger
emits: CanExecuteAs
description: Create a new Eventarc trigger binding an event source to a destination consumer, then publish
  an event (or wait for a natural event) to run the consumer as its runtime SA. Provides the Eventarc-specific
  framing of messaging-chains rule 2.
match:
- - principal: null
  - CanSchedule
  - trigger: null
- - trigger: null
  - CanTrigger
  - consumer: null
- - consumer: null
  - ExecutesAs
  - sa: null
where:
- node_type(?trigger) == EventRule
- node_class(?consumer) == Compute or node_type(?consumer) == Workflow
- ?sa.privilege_level >= ?principal.privilege_level
optional:
- - principal: null
  - CanWriteData
  - src: null
- - src: null
  - CanTrigger
  - trigger: null
emit:
  source_type: Identity
  target_type: Identity
  source: <principal>
  target: <consumer's runtime service account>
  permissions:
  - eventarc.triggers.create
  - iam.serviceAccounts.actAs
  - pubsub.topics.publish
  conditions:
  - trigger_exists
  - role_compatibility
  state_logic: "ACTIVE when the CanSchedule gate is satisfied (trigger.create + actAs on trigger SA),\
    \ the new trigger binding is confirmed live (CanTrigger(trigger \u2192 consumer) ACTIVE), AND matched(optional[0])\
    \ confirms the principal can publish an event to drive the trigger immediately. CONDITIONAL(trigger_exists)\
    \ when the trigger is created but a natural event (Audit Log, GCS notification) drives it rather than\
    \ a direct publish \u2014 the consumer will execute on the next matching event. POTENTIAL(role_compatibility)\
    \ when actAs or the trigger SA's invoker rights on the consumer are unconfirmed. Inherits weakest\
    \ contributor state."
  confidence: min(contributing_confidences) * 0.90
  derived_from:
  - ?principal CanSchedule ?trigger (gcp-eventarc-create-trigger)
  - ?trigger CanTrigger ?consumer (gcp-eventarc-trigger-routes-to-consumer)
  - '?consumer ExecutesAs ?sa (from consumer''s rule file: gcp-cloudrun-executes-as / gcp-gcf-executes-as
    / gcp-workflows-executes-as)'
  - ?principal CanWriteData ?src + ?src CanTrigger ?trigger (gcp-eventarc-publish-to-bus or -publish-to-transport-topic)
    [optional]
  false_positive_note: "De-dupes with messaging-chains messaging-trigger-executes-as on (CanExecuteAs,\
    \ ?principal, ?sa) \u2014 emit once, preferring this Eventarc-framed narrative for GCP-specific queries.\
    \ The CanSchedule gate enforces eventarc.triggers.create + actAs on trigger SA; without actAs this\
    \ degrades to POTENTIAL(role_compatibility). The consumer's runtime SA (the escalation target) is\
    \ determined by the consumer's own configuration (Cloud Run SA, Workflow SA, Cloud Function SA) \u2014\
    \ NOT by the Eventarc trigger SA. Never attribute the trigger SA as the CanExecuteAs target for this\
    \ rule."
  narrative: '{principal.name} can create an Eventarc trigger binding an event source to {consumer.name},
    which executes as {sa.name}; publishing a matching event (or waiting for a natural one) delivers an
    attacker-influenced payload to {consumer.name}, executing as {sa.name}.'
move · open · esc close