gcp-psc-private-reach-producer
A PSC consumer forwarding rule targeting a Service Attachment (producer-published service) gives workloads in the consumer VPC private IP access to the producer's Internal Load Balancer backend (Cloud SQL, Cloud Run, GCE-based service, etc.). An in-network attacker can reach the producer backend over this private channel without traversing the public internet.
match (record)
{
"field": "purpose",
"resource_type": "compute.googleapis.com/ForwardingRule",
"value": "PRIVATE_SERVICE_CONNECT"
}
where
forwardingRule.target matches a compute.googleapis.com/ServiceAttachment URI
ServiceAttachment.connectionStatus == ACCEPTED (for ACCEPT_MANUAL) OR connectionPreference == ACCEPT_AUTOMATIC
forwardingRule is in an ACTIVE / operational state
emit
| source type | Compute |
|---|---|
| target type | PrivateEndpoint |
| source | <workload in the consumer VPC subnet of the forwarding rule> |
| target | <PSC consumer endpoint (ForwardingRule) -> Service Attachment> |
| conditions | network_reachability service_state |
| state logic | CONDITIONAL(network_reachability) — the consumer endpoint exists and the Service Attachment has ACCEPTED the connection; network reach to the PSC endpoint IP from the attacker's foothold is still required. BLOCKED if connectionStatus is PENDING or REJECTED or the forwarding rule is deleted. |
Narrative
PSC forwarding rule {forwarding_rule.name} in {consumer_vpc.name} routes to Service Attachment {service_attachment.name} (producer project: {producer_project}). Any workload in the consumer VPC can reach the producer's Internal LB backend privately via the PSC endpoint IP {forwarding_rule.IPAddress}.
Raw rule rules/derived/gcp/psc.yaml
id: gcp-psc-private-reach-producer
emits: PrivateReachability
description: A PSC consumer forwarding rule targeting a Service Attachment (producer-published service)
gives workloads in the consumer VPC private IP access to the producer's Internal Load Balancer backend
(Cloud SQL, Cloud Run, GCE-based service, etc.). An in-network attacker can reach the producer backend
over this private channel without traversing the public internet.
match_record:
resource_type: compute.googleapis.com/ForwardingRule
field: purpose
value: PRIVATE_SERVICE_CONNECT
where:
- forwardingRule.target matches a compute.googleapis.com/ServiceAttachment URI
- ServiceAttachment.connectionStatus == ACCEPTED (for ACCEPT_MANUAL) OR connectionPreference == ACCEPT_AUTOMATIC
- forwardingRule is in an ACTIVE / operational state
emit:
source_type: Compute
target_type: PrivateEndpoint
source: <workload in the consumer VPC subnet of the forwarding rule>
target: <PSC consumer endpoint (ForwardingRule) -> Service Attachment>
permissions: []
conditions:
- network_reachability
- service_state
state_logic: "CONDITIONAL(network_reachability) \u2014 the consumer endpoint exists and the Service\
\ Attachment has ACCEPTED the connection; network reach to the PSC endpoint IP from the attacker's\
\ foothold is still required. BLOCKED if connectionStatus is PENDING or REJECTED or the forwarding\
\ rule is deleted."
derived_from:
- '<ForwardingRule resource: purpose=PRIVATE_SERVICE_CONNECT, target=serviceAttachment URI>'
- '<ServiceAttachment: connectionStatus=ACCEPTED or connectionPreference=ACCEPT_AUTOMATIC>'
false_positive_note: "ACCEPT_MANUAL connections with status != ACCEPTED are BLOCKED \u2014 do not emit.\
\ The producer's backend still enforces application-layer auth (IAM, DB credentials, mTLS, etc.);\
\ PrivateReachability only models the network path. State is CONDITIONAL(network_reachability) in\
\ all cases \u2014 a foothold in the consumer subnet is a hard prerequisite. NOTE: source_type is\
\ Compute per schema, but at graph-construction time the source may be instantiated as a VirtualNetwork\
\ or Subnet node if no specific workload is identified \u2014 the reachability applies to any node\
\ in the consumer subnet that can reach the PSC endpoint IP. Ensure graph source node resolves to\
\ a valid PrivateReachability source type (Compute, Messaging)."
narrative: 'PSC forwarding rule {forwarding_rule.name} in {consumer_vpc.name} routes to Service Attachment
{service_attachment.name} (producer project: {producer_project}). Any workload in the consumer VPC
can reach the producer''s Internal LB backend privately via the PSC endpoint IP {forwarding_rule.IPAddress}.'