gcp-vpc-shared-vpc-network-reach

A service-project service account holding compute.networkUser on a host-project subnet can create workloads whose NICs land in that subnet, giving those workloads internal-IP reachability to all other resources in the subnet (including those from other service projects).

derived gcp emits CanNetworkReach

match

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

{'sa': None} HasPermission {'host_subnet': None}

where

permission == compute.subnetworks.use (granted via roles/compute.networkUser on the subnet or host project) ?sa is a ServiceAccount or Identity in a service project ?host_subnet is a Subnet in the host project (Shared VPC host)

emit

source typeIdentity
target typeNetwork
source?sa
target<VMs / resources co-located in ?host_subnet>
permissionscompute.subnetworks.use compute.instances.create iam.serviceAccounts.actAs
conditionsnetwork_reachability iam_permission
state logicCONDITIONAL(iam_permission) — requires compute.subnetworks.use on the host subnet AND compute.instances.create + iam.serviceAccounts.actAs to materialize a workload in the subnet. CONDITIONAL(network_reachability) applies to the resulting VM's lateral reach within the subnet after the workload is created.

Narrative

Service account {sa.name} holds compute.subnetworks.use on Shared VPC subnet {subnet.name} in host project {host_project.name}. Creating a workload in this subnet places it in the same network segment as all other service-project workloads sharing that subnet, enabling internal-IP reachability to those resources.

Raw rule rules/derived/gcp/vpc.yaml

id: gcp-vpc-shared-vpc-network-reach
emits: CanNetworkReach
description: A service-project service account holding compute.networkUser on a host-project subnet can
  create workloads whose NICs land in that subnet, giving those workloads internal-IP reachability to
  all other resources in the subnet (including those from other service projects).
applies_to:
- gcp
match:
- - sa: null
  - HasPermission
  - host_subnet: null
where:
- permission == compute.subnetworks.use (granted via roles/compute.networkUser on the subnet or host project)
- ?sa is a ServiceAccount or Identity in a service project
- ?host_subnet is a Subnet in the host project (Shared VPC host)
emit:
  source_type: Identity
  target_type: Network
  source: ?sa
  target: <VMs / resources co-located in ?host_subnet>
  permissions:
  - compute.subnetworks.use
  - compute.instances.create
  - iam.serviceAccounts.actAs
  conditions:
  - network_reachability
  - iam_permission
  state_logic: "CONDITIONAL(iam_permission) \u2014 requires compute.subnetworks.use on the host subnet\
    \ AND compute.instances.create + iam.serviceAccounts.actAs to materialize a workload in the subnet.\
    \ CONDITIONAL(network_reachability) applies to the resulting VM's lateral reach within the subnet\
    \ after the workload is created."
  confidence: '0.80'
  derived_from:
  - "<CrossProjectTrust: service_project \u2192 host_project>"
  - '<HasPermission: ?sa compute.subnetworks.use on ?host_subnet>'
  false_positive_note: (1) compute.subnetworks.use alone does not create network reachability; the SA
    must also be able to create (or already have) a compute instance in the subnet (compute.instances.create
    + iam.serviceAccounts.actAs). If only subnetworks.use is held, downgrade to POTENTIAL(iam_permission).
    (2) Firewall rules in the host project apply to all tenant workloads in the subnet. A deny-all-intra-subnet
    rule would block lateral movement even within the same subnet. (3) Shared VPC subnets from different
    regions are NOT in the same L2 domain; region matters for direct L3 adjacency.
  narrative: Service account {sa.name} holds compute.subnetworks.use on Shared VPC subnet {subnet.name}
    in host project {host_project.name}. Creating a workload in this subnet places it in the same network
    segment as all other service-project workloads sharing that subnet, enabling internal-IP reachability
    to those resources.
move · open · esc close