Reach a service privately on Google Cloud, without peering the networks

Six steps to a private path from a consumer workload to a producer service: decide endpoint or backend, reserve the consumer address, have the producer publish a service attachment with an accept list and NAT subnets, connect, allow the egress, then verify by proving the path is internal.

markdownguidev1ENA4-6BSKstage: buildtrust: officialfamily: networkingservice: private-service-connectinterface: anyprivate service connectendpointbackendservice attachmentaccept listNAT subnetinternal IP addressprivate accessVPC peering alternative

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

Reach a service privately

Use this instead of peering whenever the thing you need is a service, not a network. Peering joins whole address spaces, is not transitive, and fails outright on overlapping ranges; Private Service Connect joins one service to one internal address and does none of those things.

Step 1 — endpoint or backend

ChooseWhen
endpointthe workload just needs to call the service. One forwarding rule, one internal IP address. This is the default answer
backendyou want the service behind your own load balancer — so your own policies, including a Cloud Armor security policy on a regional internal Application Load Balancer, sit in front of it

A backend is more objects and more control. Do not reach for it unless you want the load balancer for a reason you can name.

Step 2 — reserve the consumer-side address

An endpoint consumes an internal IP address from a subnet in the consumer's VPC network. Reserve it deliberately, in the subnet the calling workload lives in, and record it in the address plan.

At one or two connections this is invisible. At a hundred it is a real allocation, and it is the line most often missing from a migrated address plan.

Step 3 — the producer publishes a service attachment

On the producer side (which may be another team, or another company):

  • a service attachment targeting the producer's load balancer;
  • a consumer accept list — who is allowed to connect;
  • NAT subnets for the translated traffic.

The accept list is the authorisation boundary. The consumer cannot connect without being on it, and the producer does not have to trust the consumer's network to let them in.

If the producer also needs to initiate calls into the consumer — a managed data plane reading a customer database — that is a producer-side interface, the reverse-direction object, and not a second endpoint.

Step 4 — connect, and confirm which object you got

The consumer creates the endpoint (or the backend) against the attachment. Confirm the connection's state on both sides before testing anything: a pending accept-list approval looks exactly like a network fault from the consumer's side.

Step 5 — allow the egress

Egress is implied-allow on a fresh VPC network, so this step is a no-op there. On a hardened network with explicit egress rules it is not: add the rule to the endpoint's address. This is the step people skip because it worked in the sandbox.

Step 6 — verify that the path is actually private

CheckExpected
resolve and connect to the endpoint address from the consumer workloadsuccess, on an internal address from your own subnet
confirm the workload needs no external IP and no NAT for this callcorrect — the traffic stays within Google Cloud
remove the consumer from the accept list and retrythe connection fails

The third row is the one that proves it. A path that still works after you revoke the authorisation was never going through the mechanism you think it was.

For a migration

This is the counterpart of AWS PrivateLink and Azure Private Link, and Microsoft's own mapping table pairs it with Private Link. Designs port. What does not port automatically is the address plan: every private connection consumes a consumer-side address on all three clouds. Count them before you commit a subnet size. See guides/parity/networking.md.

Read this document as markdown — the same bytes an agent receives.