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.
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 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 → 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}.'