gcp-workflows-create-workload-as
Create a new workflow bound to a passable SA (create + actAs) to execute code as that SA.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?principal has workflows.workflows.create in scope
?principal has iam.serviceAccounts.actAs on ?sa
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | <principal> |
| target | <service account> |
| permissions | workflows.workflows.create iam.serviceAccounts.actAs workflows.executions.create? |
| conditions | role_compatibility iam_permission |
| state logic | ACTIVE when the principal holds workflows.workflows.create AND actAs on ?sa AND can invoke the new workflow (workflows.executions.create — which the creator typically holds in scope). POTENTIAL(role_compatibility) when actAs on ?sa is unknown/unresolved. |
Narrative
{principal.name} can create a workflow bound to {sa.name} (workflows.workflows.create + iam.serviceAccounts.actAs), then invoke it to execute attacker logic as {sa.name}.
Raw rule rules/derived/gcp/workflows.yaml
id: gcp-workflows-create-workload-as
emits: CanCreateWorkloadAs
description: Create a new workflow bound to a passable SA (create + actAs) to execute code as that SA.
match:
- - principal: null
- CanPassIdentity
- sa: null
where:
- ?principal has workflows.workflows.create in scope
- ?principal has iam.serviceAccounts.actAs on ?sa
emit:
source_type: Identity
target_type: Identity
source: <principal>
target: <service account>
permissions:
- workflows.workflows.create
- iam.serviceAccounts.actAs
- workflows.executions.create?
conditions:
- role_compatibility
- iam_permission
state_logic: "ACTIVE when the principal holds workflows.workflows.create AND actAs on ?sa AND can invoke\
\ the new workflow (workflows.executions.create \u2014 which the creator typically holds in scope).\
\ POTENTIAL(role_compatibility) when actAs on ?sa is unknown/unresolved."
derived_from:
- ?principal CanPassIdentity ?sa (gcp-workflows-passidentity-actas)
false_positive_note: actAs must apply to the chosen SA. Without actAs -> POTENTIAL. The creator can
set themselves as invoker (or grant allAuthenticatedUsers) on the new workflow's IAM policy to ensure
a run path. Dedupes with can-execute-as execute-as-via-new-workload when feeding CanExecuteAs.
narrative: '{principal.name} can create a workflow bound to {sa.name} (workflows.workflows.create +
iam.serviceAccounts.actAs), then invoke it to execute attacker logic as {sa.name}.'