gcp-gce-create-template-as-sa
actAs + compute.instanceTemplates.create + MIG create/setInstanceTemplate -> MIG launches instances as the SA, read metadata token.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?principal has EFFECTIVE compute.instanceTemplates.create
?sa is the template's serviceAccounts[].email and is actAs-able by ?principal (iam.serviceAccounts.actAs)
?principal has compute.instanceGroupManagers.create OR compute.instanceGroupManagers.update OR compute.instanceGroupManagers.setInstanceTemplate (drive the MIG to launch from the template)
emit
| source type | Identity |
|---|---|
| target type | Identity |
| source | <principal> |
| target | <service account> |
| permissions | compute.instanceTemplates.create compute.instanceGroupManagers.create compute.instanceGroupManagers.setInstanceTemplate iam.serviceAccounts.actAs |
| conditions | iam_permission role_compatibility |
Narrative
{principal.name} can create an instance template bound to {sa.name} (compute.instanceTemplates.create + iam.serviceAccounts.actAs) and drive a MIG (compute.instanceGroupManagers.create/setInstanceTemplate) to launch instances that run as the SA and expose its metadata token.
Raw rule rules/derived/gcp/gce.yaml
id: gcp-gce-create-template-as-sa
emits: CanCreateWorkloadAs
description: actAs + compute.instanceTemplates.create + MIG create/setInstanceTemplate -> MIG launches
instances as the SA, read metadata token.
match:
- - principal: null
- CanPassIdentity
- sa: null
where:
- ?principal has EFFECTIVE compute.instanceTemplates.create
- ?sa is the template's serviceAccounts[].email and is actAs-able by ?principal (iam.serviceAccounts.actAs)
- ?principal has compute.instanceGroupManagers.create OR compute.instanceGroupManagers.update OR compute.instanceGroupManagers.setInstanceTemplate
(drive the MIG to launch from the template)
emit:
source_type: Identity
target_type: Identity
source: <principal>
target: <service account>
permissions:
- compute.instanceTemplates.create
- compute.instanceGroupManagers.create
- compute.instanceGroupManagers.setInstanceTemplate
- iam.serviceAccounts.actAs
conditions:
- iam_permission
- role_compatibility
escalation: Create an instance template bound to a privileged SA, then create/point a MIG at it so autoscaling
launches run as the SA; read the metadata token from a launched instance.
false_positive_note: compute.instanceTemplates.create alone is not SA execution; it must be paired with
iam.serviceAccounts.actAs on the template's serviceAccounts[].email. Access scopes on the template
can cap the token. setInstanceTemplate does not re-check actAs the way setServiceAccount does, so
it can bypass the stopped-instance constraint, but a MIG launch/resize must still occur.
narrative: '{principal.name} can create an instance template bound to {sa.name} (compute.instanceTemplates.create
+ iam.serviceAccounts.actAs) and drive a MIG (compute.instanceGroupManagers.create/setInstanceTemplate)
to launch instances that run as the SA and expose its metadata token.'