Private Google Access in GCP Explained | Reach Google APIs Without External IPs
Remove external IPs from your VMs and they immediately lose access to Cloud Storage, BigQuery, Pub/Sub, and every other Google API. Private Google Access fixes this. It is a per-subnet flag that opens an internal path to Google APIs — no external IP required, no internet transit, and nothing exposed.
Simple explanation
Private Google Access is a setting you enable on a subnet. When it is on, VMs in that subnet can reach Google Cloud APIs — Cloud Storage, BigQuery, Pub/Sub, and similar — even if those VMs have no external IP address. The traffic travels over Google’s internal network, not the public internet.
- It does not give your VMs general internet access — that requires Cloud NAT
- It does not expose your VMs to inbound traffic from the internet
- It does not cover non-Google destinations (third-party APIs, package repositories, etc.)
- It is not the same as Private Service Connect, which uses discrete private endpoints per service
Why Private Google Access exists
A solid security baseline for GCP VMs is to remove external IP addresses. Every public IP is a potential target: it can be scanned, probed, and subjected to brute-force attempts. The network security best practices page covers this in more detail.
But removing external IPs creates an immediate problem. A VM processing data might need to read from Cloud Storage, write results to BigQuery, or publish messages to Pub/Sub. Without an external IP, and without Private Google Access, those API calls fail — the VM has no route to the internet and no other way to reach Google’s API endpoints.
Private Google Access solves this with a dedicated internal route. Your VMs stay off the internet entirely, and Google API traffic stays on Google’s network. You get the security benefit without sacrificing the ability to use the services.
Think of it like a staff-only corridor in a large building. Employees (VMs) without visitor badges (external IPs) cannot use the public entrance. Private Google Access opens a back corridor that leads directly to the company canteen (Google APIs) — but only the canteen, not the street outside.
How it works
Private Google Access is configured at the subnet level, not the VPC level. Enabling it on a subnet makes two virtual IP ranges reachable from VMs in that subnet:
- 199.36.153.8/30 —
private.googleapis.com: standard private access to Google APIs - 199.36.153.4/30 —
restricted.googleapis.com: for VPC Service Controls-protected access
When a VM in that subnet calls a Google API, the traffic is routed to one of these virtual IPs. Google’s infrastructure receives the request and forwards it to the appropriate service. The VM never needs a public IP, and the traffic does not leave Google’s network.
Key boundaries to understand:
- Subnet-level, not VPC-level. Enabling it on one subnet does not enable it on others. Each subnet you want to use must be configured individually.
- Outbound only. This feature controls outbound API calls from your VMs. It has no effect on inbound traffic.
- Google APIs only. Private Google Access covers Google Cloud services. It does not cover Google Workspace APIs (Gmail, Drive, etc.) or any non-Google internet destinations.
Private Google Access does not modify your VPC routes. The default route to the internet gateway still exists. It is the VM’s lack of an external IP that prevents internet traffic — not a routing change. Private Google Access adds the internal path to the Google VIP ranges on top of this.
When to use Private Google Access
Enable Private Google Access whenever private VMs need to reach Google APIs. Common scenarios:
- Compute Engine VMs with no external IP that read from Cloud Storage, write to BigQuery, or publish to Pub/Sub
- Hardened subnets where external IPs have been removed as a baseline security measure
- VPC Service Controls environments — required when you want API traffic to stay within your service perimeters (use
restricted.googleapis.comin this case) - Data processing workloads in isolated subnets that should not have general internet access but still need to call managed Google services
- Architectures that enforce no external IPs by default via an organisation policy
- If your VMs also need to reach the public internet (package managers, third-party APIs), pair it with Cloud NAT
- If you have deny-all egress firewall rules, you also need explicit allow rules for the Google VIP ranges
- If you need fine-grained private connectivity to a specific service through its own endpoint, look at Private Service Connect instead
Private Google Access vs Cloud NAT
These two are often confused because both deal with private VMs that lack external IPs. They solve different problems and are not interchangeable.
| Private Google Access | Cloud NAT | |
|---|---|---|
| What it covers | Google APIs and services only | Any public internet destination |
| Traffic path | Stays on Google’s internal network | Goes out to the public internet |
| Configuration | Flag on each subnet | NAT gateway on a Cloud Router, per region |
| Typical use case | Cloud Storage, BigQuery, Pub/Sub | OS patches, container images, third-party APIs |
| Cost | No charge for the feature itself | Billed per gateway and data processed |
Many production architectures use both. Private Google Access covers Google API calls. Cloud NAT covers everything else outbound. They work independently — enabling one does not affect the other.
Private Google Access is like a private tunnel from your office directly to the company’s internal services — fast, direct, and never touches the public road. Cloud NAT is like giving your office a company car to go anywhere in the city. You might need both, but they are for very different trips.
Calls to storage.googleapis.com and similar hostnames that go through Cloud NAT travel out to the internet and back. This costs more in egress fees and can bypass VPC Service Controls perimeters. Use Private Google Access for Google APIs — that is exactly what it is for.
Private Google Access vs Private Service Connect
Private Google Access and Private Service Connect are frequently confused because both involve private connectivity to Google services. They are distinct features with different scopes.
Private Google Access is a subnet-level flag. Enable it and all VMs in that subnet can reach any Google-managed API through well-known virtual IP ranges. There are no individual endpoints to create and no extra resources to manage. It works uniformly across all Google Cloud APIs.
Private Service Connect is a more granular endpoint model. You create a specific private endpoint — with its own internal IP — that forwards traffic to a particular service. That service might be a Google API, or it might be a service published by another team or organisation inside your network. Each endpoint is a distinct resource and can be controlled independently with its own firewall rules and access policies.
In practice:
- Private Google Access is simpler to set up and sufficient for most workloads that need to call Google APIs privately
- Private Service Connect gives finer control — useful when you need to pin traffic to a specific endpoint, apply per-endpoint policies, or access third-party services published inside your network
- The two can coexist — some subnets use Private Google Access broadly, while specific services use Private Service Connect endpoints alongside it
DNS and restricted access
For most workloads, Private Google Access works without any DNS changes. VMs resolve API hostnames (like storage.googleapis.com) to public Google IPs by default, but the traffic is still routed internally because of how the virtual IP ranges are handled at the VPC edge.
When you use VPC Service Controls, DNS configuration becomes critical. Your VMs must resolve API hostnames to the restricted.googleapis.com range (199.36.153.4/30), not to public Google IPs. If they resolve to a public IP, that traffic bypasses your service perimeters entirely — defeating their data exfiltration protection.
The fix is a private DNS zone in Cloud DNS that overrides googleapis.com resolution inside the VPC:
# Create a private DNS zone to override googleapis.com resolution
gcloud dns managed-zones create googleapis-private \
--dns-name=googleapis.com. \
--description="Redirect googleapis.com to restricted VIPs" \
--visibility=private \
--networks=my-vpc
# Point *.googleapis.com to restricted.googleapis.com
gcloud dns record-sets create "*.googleapis.com." \
--zone=googleapis-private \
--type=CNAME \
--ttl=300 \
--rrdatas=restricted.googleapis.com.
# Add A records for restricted.googleapis.com (199.36.153.4/30)
gcloud dns record-sets create "restricted.googleapis.com." \
--zone=googleapis-private \
--type=A \
--ttl=300 \
--rrdatas="199.36.153.4,199.36.153.5,199.36.153.6,199.36.153.7"If you are using VPC Service Controls, always route API traffic through restricted.googleapis.com (199.36.153.4/30). This guarantees that traffic cannot bypass your service perimeters by resolving to a public Google IP instead.
The CNAME causes all *.googleapis.com queries inside the VPC to resolve to restricted.googleapis.com, which then resolves to the VIP A records. VMs outside this private zone are unaffected — the override is VPC-scoped.
Without it, VMs still reach Google APIs — but through public IP resolution, which bypasses your service perimeters entirely. The subnet flag alone does not prevent this. If you are running VPC Service Controls and skip the DNS zone, your perimeter has a silent gap.
Firewall and routing considerations
In most VPCs, enabling the subnet flag is sufficient. GCP’s default VPC allows all egress traffic, so no additional firewall rule is needed.
If your VPC has a deny-all egress rule as a hardening baseline — which is a sensible practice for sensitive workloads — you must also add an explicit allow rule for the Google API VIP ranges. Without it, the subnet setting has no practical effect: the egress firewall drops the traffic before it can reach the VIP.
# Allow egress to both Google API VIP ranges on HTTPS
gcloud compute firewall-rules create allow-egress-private-google-access \
--network=my-vpc \
--direction=EGRESS \
--action=ALLOW \
--rules=tcp:443 \
--destination-ranges=199.36.153.8/30,199.36.153.4/30 \
--priority=100 \
--description="Allow egress to Google APIs via Private Google Access"Even if your current VPC allows all egress, it is worth adding this rule explicitly. It documents the intent and prevents a silent breakage if you tighten egress policy later. Private Google Access is easy to forget when writing a new deny-all baseline rule.
How to enable Private Google Access
You can enable Private Google Access on an existing subnet or at creation time. The change takes effect immediately for all VMs in that subnet.
# Enable on an existing subnet
gcloud compute networks subnets update my-subnet \
--region=europe-west1 \
--enable-private-ip-google-access
# Verify the setting
gcloud compute networks subnets describe my-subnet \
--region=europe-west1 \
--format="get(privateIpGoogleAccess)"
# Create a new subnet with Private Google Access already enabled
gcloud compute networks subnets create my-new-subnet \
--network=my-vpc \
--region=europe-west1 \
--range=10.10.20.0/24 \
--enable-private-ip-google-accessThe verify command returns True when enabled and False when disabled. If you see False on a subnet where you expected it enabled, confirm you are using the correct region — subnet names are not globally unique across regions.
How to verify it is working
SSH into a VM that has no external IP — use Identity-Aware Proxy or a bastion to access it — and test connectivity to a Google API directly:
# SSH to a private VM using IAP tunnel
gcloud compute ssh my-private-vm \
--zone=europe-west1-b \
--tunnel-through-iap
# From inside the VM: test API reachability
curl -o /dev/null -s -w "%{http_code}\n" \
https://storage.googleapis.com/storage/v1/b?project=my-project
# A 200 or 401 both confirm the network path is working
# 200 = authenticated and succeeded
# 401 = auth failed, but the VM reached the API endpoint
# Alternatively, test with the VM's attached service account
gsutil ls gs://my-bucket/A 401 response is still good news for network testing — it means the VM reached the Storage API and received an HTTP response, which confirms the internal path is open. A connection timeout or Could not connect error indicates a network-level failure: Private Google Access may not be enabled on the subnet, the egress firewall may be blocking the traffic, or the DNS resolution is returning an unreachable IP.
For a systematic approach to diagnosing why a private VM cannot reach Google APIs, see Troubleshooting Network Issues.
Common mistakes
- Enabling it on the wrong subnet. Private Google Access is per-subnet. If your VM is in
subnet-band you enable it onsubnet-a, nothing changes for that VM. Always check which subnet a VM belongs to before enabling — especially in multi-subnet VPCs. - Confusing it with Cloud NAT. Cloud NAT provides general internet access for private VMs. Private Google Access provides internal access to Google APIs only. A VM that needs both requires both features. Enabling only one of them leaves the other category of traffic broken.
- Confusing it with Private Service Connect. Private Service Connect creates discrete private endpoints for specific services. Private Google Access is a subnet flag that covers all Google APIs broadly. Using one when you need the other leads to unexpected connectivity failures that can be hard to diagnose.
- Forgetting egress firewall rules in hardened VPCs. In a VPC with deny-all egress as the baseline, enabling the subnet flag alone does nothing. You must also add an explicit allow rule for the Google VIP ranges (199.36.153.8/30 and 199.36.153.4/30) on port 443.
- Skipping DNS overrides when using VPC Service Controls. Without a private DNS zone overriding
googleapis.com, VMs may resolve API hostnames to public Google IPs. That traffic bypasses VPC Service Controls perimeters entirely, creating a gap in your data exfiltration protection. - Assuming it provides general internet access. Private Google Access does not give your VMs any access to the public internet. A VM with Private Google Access and no external IP cannot reach PyPI, Docker Hub, GitHub, or any non-Google destination.
Summary
- Private Google Access is a per-subnet flag that lets VMs without external IPs reach Google APIs over Google’s internal network
- Traffic is routed to virtual IP ranges: 199.36.153.8/30 (private.googleapis.com) or 199.36.153.4/30 (restricted.googleapis.com, for VPC Service Controls)
- Enable it with
gcloud compute networks subnets update —enable-private-ip-google-access - In hardened VPCs with deny-all egress rules, also add an explicit allow rule for both Google VIP ranges on port 443
- Use
restricted.googleapis.comwith a private DNS zone override when VPC Service Controls are in use - Pair with Cloud NAT when VMs also need general internet access — the two are complementary, not competing
- Not the same as Private Service Connect or Cloud NAT — each feature solves a different connectivity problem
Frequently asked questions
What does Private Google Access do in GCP?
Private Google Access allows VM instances with no external IP address to reach Google APIs and services — such as Cloud Storage, BigQuery, and Pub/Sub — over Google's internal network. Without it, a private VM has no path to these APIs and all API calls will fail.
Do I need Cloud NAT as well?
It depends on what your VMs need to reach. Private Google Access only covers Google-managed APIs. If your VMs also need to reach the public internet — for OS patches, container images, or third-party APIs — you need Cloud NAT as well. The two features are complementary, not competing, and many architectures use both.
Does Private Google Access expose my VM to the internet?
No. Enabling Private Google Access on a subnet does not assign external IPs to your VMs or expose them to inbound internet traffic. It only opens an outbound path to Google API endpoints. The VM remains unreachable from the internet.
Is Private Google Access enabled per subnet or per VPC?
Per subnet. You enable or disable it on each subnet individually. If you have three subnets and only enable it on one, VMs in the other two cannot reach Google APIs without an external IP. This is a common source of confusion when working with multi-subnet VPCs.
What is the difference between private.googleapis.com and restricted.googleapis.com?
Both are virtual IP ranges for reaching Google APIs without internet transit. restricted.googleapis.com (199.36.153.4/30) is specifically designed for VPC Service Controls environments — routing through it ensures API traffic cannot bypass your service perimeters. Use private.googleapis.com (199.36.153.8/30) when you are not using VPC Service Controls.