gcp-gcf-execute-as-via-code
Modify function source + (invoke/call OR existing trigger) + ExecutesAs.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?function) ==
ServerlessFunction
?sa.privilege_level >= ?principal.privilege_level
optional
Present → upgrade the emitted state; absent → downgrade (not a hard requirement).
{'principal': None}
CanInvoke {'function': None}
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | <principal> |
| target | <runtime service account> |
| permissions | cloudfunctions.functions.sourceCodeSet |
| state logic | ACTIVE if matched(optional[0]) or trigger_exists(?function) else CONDITIONAL(trigger_exists). The CanInvoke that satisfies optional[0] is gcp-gcf-invoke for 1st-gen or gcp-gcf-invoke-run (run.routes.invoke on the backing Cloud Run service) for 2nd-gen. |
Narrative
{principal.name} can replace the source of {function.name} (cloudfunctions.functions.sourceCodeSet) and run it, executing as {sa.name}.
Raw rule rules/derived/gcp/gcf.yaml
id: gcp-gcf-execute-as-via-code
emits: CanExecuteAs
description: Modify function source + (invoke/call OR existing trigger) + ExecutesAs.
match:
- - principal: null
- CanModifyCode
- function: null
- - function: null
- ExecutesAs
- sa: null
optional:
- - principal: null
- CanInvoke
- function: null
where:
- node_type(?function) == ServerlessFunction
- ?sa.privilege_level >= ?principal.privilege_level
emit:
source_type: Identity
target_type: Identity
source: <principal>
target: <runtime service account>
permissions:
- cloudfunctions.functions.sourceCodeSet
state_logic: ACTIVE if matched(optional[0]) or trigger_exists(?function) else CONDITIONAL(trigger_exists).
The CanInvoke that satisfies optional[0] is gcp-gcf-invoke for 1st-gen or gcp-gcf-invoke-run (run.routes.invoke
on the backing Cloud Run service) for 2nd-gen.
conditions_from:
- function: null
- sa: null
false_positive_note: 'Without invoke/call (1st-gen: cloudfunctions.functions.invoke/.call; 2nd-gen:
run.routes.invoke on the backing Cloud Run service) AND without an existing event trigger -> CONDITIONAL(trigger_exists),
not ACTIVE. Only escalation when SA privilege exceeds caller''s (default appspot editor SA qualifies).'
narrative: '{principal.name} can replace the source of {function.name} (cloudfunctions.functions.sourceCodeSet)
and run it, executing as {sa.name}.'