VPC Service Controls in GCP: Stop Data Exfiltration at the API Layer

IAM can confirm that a user has permission to read a BigQuery dataset. It cannot prevent that user from querying it from a personal laptop at a coffee shop, then exporting the results to a Cloud Storage bucket in another organisation. VPC Service Controls closes that gap. It evaluates the context of every API call — source network, device state, and identity origin — and blocks requests that fall outside your trusted boundaries, even when IAM would otherwise permit them.

What is VPC Service Controls?

VPC Service Controls (VPC-SC) is a Google Cloud feature that lets you define security perimeters around GCP service APIs. Once a service like BigQuery or Cloud Storage is protected by a perimeter, API calls that cross the perimeter boundary are blocked unless the request meets a defined set of trust conditions.

Those conditions go beyond identity. VPC-SC can require that a request originates from a specific IP range, a managed corporate device, or a specific set of GCP projects. A user with valid IAM credentials but calling from an unrecognised network is still denied.

That is the key distinction: IAM asks who is making the request. VPC-SC asks where and how.

The feature is built to prevent data exfiltration: the risk that an authorised identity, whether compromised, careless, or malicious, uses legitimate API calls to move sensitive data out of your organisation. For environments handling regulated data, VPC-SC is typically a foundational control alongside IAM least privilege and organisation policies.

Analogy

Think of a government building with two separate security checks. The first check (IAM) verifies your badge and confirms you have clearance for the floor you want. The second check (VPC-SC) verifies that you arrived through an authorised entrance, not a side door from a back alley, even if your badge would technically scan. Both checks must pass. Failing either one means you are not getting in.

Why IAM alone is not enough

IAM in GCP answers one question: does this identity have permission to perform this action? It does not ask where the request originated, whether the device is managed, or whether the destination is inside your organisation.

A user with roles/bigquery.dataViewer can query your most sensitive tables from any network, on any device, and export the results to any Cloud Storage bucket they have write access to, including buckets in entirely different GCP organisations. IAM issued the permission. Nothing in IAM prevents the data from going somewhere it should not.

VPC Service Controls adds a second check: is this request coming from a trusted context? Even if the IAM check passes, the perimeter can enforce that the request must originate from an approved IP range, a managed device, or a specific set of GCP projects. Requests outside those contexts are blocked at the API layer before the action is performed.

How IAM Conditions fit in

IAM Conditions can also add context-aware restrictions to individual permission bindings, but they require per-binding configuration. VPC-SC operates at the API perimeter layer and covers entire services for all identities in scope. Use both: IAM Conditions for per-resource rules, VPC-SC for perimeter-wide protection.

How VPC Service Controls works

When a principal makes an API call to a protected service, GCP evaluates the request in this order:

  1. IAM check: does this identity have permission to perform the action?
  2. VPC-SC check: is this request crossing a perimeter boundary?
  3. Access level evaluation: if the request crosses a boundary, does it satisfy a matching access level (IP range, device policy, or identity type)?
  4. Ingress and egress rule evaluation: are there explicit rules that allow this specific cross-perimeter flow?
  5. Outcome: if all checks pass, the call proceeds. If VPC-SC blocks it, the request is denied. In dry-run mode it is permitted but logged instead.

Both the IAM check and the VPC-SC check must pass. Failing either one blocks the request.

Access policy

The access policy is the top-level container for all VPC Service Controls configuration in a GCP organisation. It holds perimeters, access levels, and ingress/egress rules. There is typically one access policy per organisation. You must create or identify an access policy before configuring any perimeters.

gcloud access-context-manager policies list --organization=ORGANIZATION_ID

Service perimeter

A service perimeter defines a boundary around one or more GCP projects and specifies which services are restricted. API calls to those services that cross the perimeter boundary are blocked unless a matching access level or ingress/egress rule permits them.

Perimeters run in either enforced mode (requests blocked) or dry-run mode (requests logged but permitted). Always configure and validate in dry-run mode first.

Access level

An access level defines the conditions a request must satisfy to be trusted when crossing a perimeter. Common conditions include:

  • Source IP address or IP range (corporate VPN, office network)
  • Device policy, requiring a managed endpoint verified via BeyondCorp endpoint verification
  • Identity type, restricting to service accounts or specific user identities

Ingress rules

Ingress rules explicitly allow specific external identities or projects to call APIs inside the perimeter. Use these for CI/CD pipelines, monitoring agents, or external services that need legitimate access to protected resources. Ingress rules are more precise and auditable than broad access levels.

Egress rules

Egress rules allow resources inside the perimeter to call APIs outside it. Use these when workloads inside the perimeter need to write to external services, call external APIs, or deliver data to destinations outside the perimeter boundary.

Dry-run mode

In dry-run mode, the perimeter is configured but not enforced. Requests that would be blocked are permitted but recorded as Policy Denied entries in Cloud Audit Logs. This gives you a complete impact picture before enforcement causes outages. Always run dry-run mode for at least two weeks.

Bridge perimeter

A bridge perimeter creates an auditable data path between two otherwise separate service perimeters. Use it when you need a specific, controlled flow between a production perimeter and an analytics perimeter, for example, without merging the two. Without a bridge, cross-perimeter service calls are blocked even when both sides have valid IAM permissions. Keep bridge perimeters narrow — each bridge is a controlled gap between two security zones.

When to use VPC Service Controls

VPC-SC is most valuable when data exfiltration through authorised API calls is a realistic risk. Common scenarios:

  • Sensitive BigQuery datasets containing PII, financial records, or healthcare data. See BigQuery overview for how BigQuery handles access at the data layer.

  • Regulated Cloud Storage buckets subject to HIPAA, PCI-DSS, or similar requirements where the destination of a copy or export matters as much as who initiated it.

  • Multi-project analytics environments where raw data, transformed data, and outputs live in separate projects that all need perimeter coverage together.

  • Production environments with external contractors or vendors who have legitimate IAM access but whose requests should only be trusted from specific networks or managed devices.

  • Organisations with managed device requirements where regulatory standards require that data access is limited to company-controlled endpoints.

When VPC Service Controls may not be enough on its own

VPC-SC is a powerful control, but it has clear limits:

  • It does not replace IAM least privilege. An account with storage.admin inside the perimeter can still delete buckets. VPC-SC controls access context. IAM controls access rights. See least privilege in GCP.

  • It does not replace organisation policies. Organisation policies prevent risky configurations — like allowing public buckets or disabling required APIs — that VPC-SC does not govern.

  • It does not replace audit logging and monitoring. VPC-SC blocks requests but does not alert you when someone is probing your perimeter. Pair it with Cloud Audit Logs to detect and investigate access patterns.

  • It is not the same as VPC firewalling. Firewalls protect network traffic to virtual machines. VPC-SC protects API calls to managed Google Cloud services. Both layers are needed in most production architectures.

  • Its effectiveness depends on correct perimeter design. A perimeter with overly broad access levels, or one that leaves key projects unprotected, provides weak guarantees. Design matters as much as configuration.

How to create a VPC Service Controls perimeter

These steps walk through creating a basic perimeter starting in dry-run mode. Never skip dry-run. Enforcement without prior log analysis reliably breaks legitimate workloads. For broader context on securing production systems, see securing production systems in GCP.

# Step 1: Find your organisation's Access Policy ID
# You need this ID for every subsequent VPC-SC command.
gcloud access-context-manager policies list \
  --organization=ORGANIZATION_ID
# Step 2: Define trusted source IPs in an access level spec file.
# Create access-level-spec.yaml:
# - ipSubnetworks:
#   - 203.0.113.0/24   # corporate VPN exit IP
#   - 10.0.0.0/8       # internal corporate network

gcloud access-context-manager levels create corporate-network \
  --policy=ACCESS_POLICY_ID \
  --title="Corporate Network" \
  --basic-level-spec=access-level-spec.yaml
# Step 3: Create the perimeter in dry-run mode.
# --use-explicit-dry-run-spec creates it without enforcing it.
# Nothing is blocked yet. Requests are only logged.
gcloud access-context-manager perimeters create prod-data-perimeter \
  --policy=ACCESS_POLICY_ID \
  --title="Production Data Perimeter" \
  --resources=projects/123456789012,projects/234567890123 \
  --restricted-services=storage.googleapis.com,bigquery.googleapis.com \
  --use-explicit-dry-run-spec
# Step 4: Review Policy Denied logs to see what would be blocked.
# Run this query across at least 2 full weeks of traffic.
gcloud logging read \
  'logName="projects/my-app-prod/logs/cloudaudit.googleapis.com%2Fpolicy" AND protoPayload.status.code=7' \
  --project=my-app-prod \
  --limit=100 \
  --format='table(timestamp,protoPayload.authenticationInfo.principalEmail,protoPayload.resourceName)'
# Step 5: Attach the access level to the perimeter.
# This allows requests from the corporate-network level to cross the boundary.
gcloud access-context-manager perimeters update prod-data-perimeter \
  --policy=ACCESS_POLICY_ID \
  --add-access-levels=accessPolicies/ACCESS_POLICY_ID/accessLevels/corporate-network
# Step 6: Only when confident — switch from dry-run to enforcement.
gcloud access-context-manager perimeters update prod-data-perimeter \
  --policy=ACCESS_POLICY_ID \
  --clear-dry-run-spec
Run dry-run mode for at least two weeks

Scheduled batch jobs, monthly reporting pipelines, and infrequent maintenance tasks may only run once a week or once a month. A shorter dry-run window will miss these entirely. Review Policy Denied logs over a period that covers at least one full cycle of all your scheduled processes. Discovering a blocked monthly job the day after enforcement is far more disruptive than a longer dry-run phase.

Organisation-level permissions required

Managing VPC-SC perimeters requires roles/accesscontextmanager.policyAdmin at the organisation level. The Access Context Manager API must be enabled. These are organisation-level operations, not project-level, because perimeters span projects and are governed by the organisation’s access policy.

What to check before enforcing a perimeter

Before switching from dry-run to enforcement, work through this list for every project inside the perimeter:

  • Scheduled jobs: Cloud Scheduler and Cloud Composer tasks may run at off-peak hours. Check logs over full weekly and monthly cycles, not just peak usage windows.

  • CI/CD pipelines: deployment systems that push to Cloud Storage, read from Artifact Registry, or call BigQuery during test runs need explicit ingress rules or access levels.

  • Monitoring and observability agents: agents that export metrics, traces, or logs to managed services from inside the perimeter need egress rules if those destinations are outside the boundary.

  • Third-party integrations: SaaS tools, data partners, and external analytics platforms that access your data via API need planned access exceptions before enforcement. If you see unfamiliar principals in dry-run logs, investigate before dismissing them.

  • Cross-project data flows: any service in project A that reads from or writes to a service in project B must have both projects inside the perimeter, or have an explicit ingress/egress rule.

  • Infrequent workloads: quarterly compliance exports, annual data archival jobs, and low-frequency maintenance scripts are the most commonly missed. Extend the dry-run period or check job schedules manually.

Designing VPC Service Controls for multi-project architectures

The most consequential design decision is which projects belong inside the perimeter. Every project that participates in a data flow — source, processing, and destination — must be included. Missing any one of them creates an exit route.

Why partial coverage fails

Concrete example

A Dataflow job in project A reads from BigQuery in project B and writes results to Cloud Storage in project C. If only project B is inside the perimeter, the perimeter protects the source but not the output. The Dataflow job reads data through a trusted context (it is inside the perimeter), then writes to project C, which has no perimeter at all. The data exits freely. All three projects must be inside the same perimeter for the protection to be complete.

This is not a theoretical concern. It is the most common real-world VPC-SC misconfiguration. Audit the complete data flow, including intermediate transformation steps, before finalising the perimeter scope.

Bridge perimeters for controlled cross-perimeter flows

When you operate two separate perimeters, say a production data perimeter and an analytics perimeter, and need a specific governed data path between them, use a bridge perimeter. A bridge creates an auditable connection between the two without merging them or relaxing their individual controls.

Keep bridge perimeters narrow. Each bridge is a controlled gap. A broad bridge undermines the separation you are trying to maintain. Scope bridges to the minimum set of projects and services required for the specific flow.

Common enterprise design mistakes

  • Protecting only the data warehouse project while leaving transformation projects unprotected
  • Designing the perimeter around the current state of projects, without accounting for new projects added later
  • Using one large perimeter for all projects, which reduces the isolation value of the control
  • Creating overly broad bridge perimeters that effectively merge what should be separate security zones

VPC Service Controls vs VPC firewalls

These two controls are often confused because both mention VPC in their names. They operate at entirely different layers and protect different things. See firewall rules in GCP and VPC networks explained for how the network layer works.

VPC FirewallsVPC Service Controls
LayerNetwork (L3/L4)Google Cloud API layer
ProtectsVM-to-VM and VM-to-internet trafficManaged service APIs (BigQuery, Cloud Storage, etc.)
Traffic typeTCP/UDP/ICMP by port and protocolHTTPS API calls
Identity-awareNo — based on IPs, tags, service accountsYes — evaluated per identity and context
Main threatLateral movement, external intrusionData exfiltration via authorised API calls
Where rules livePer VPC networkOrganisation-wide access policy
Typical useControl traffic to Compute Engine VMsRestrict access to serverless and managed services

In most production environments, both are needed. Firewalls protect compute workloads. VPC-SC protects managed data services. Neither replaces the other.

Related controls worth knowing

IAM Conditions add context-aware restrictions at the permission-grant layer and work well for per-resource access rules. Organisation Policies prevent risky configurations at scale. VPC-SC, IAM Conditions, and Organisation Policies each address a different attack surface. They complement each other rather than overlap.

Common mistakes with VPC Service Controls

  1. Enforcing before reviewing dry-run logs thoroughly. This is the most common cause of outages when enabling VPC-SC. The Policy Denied logs from dry-run mode are not optional. They tell you exactly which workloads will break. If you see unfamiliar principals in those logs, investigate before enforcement. They are often legitimate services that simply were not planned for. If you hit unexpected permission errors after enforcement, see troubleshooting permission denied errors.

  2. Treating VPC-SC as a replacement for IAM least privilege. VPC-SC restricts access context. IAM controls access rights. An account with storage.admin inside the perimeter retains full admin rights within that context — it can delete buckets, change ACLs, and move data freely. Apply IAM least privilege within the perimeter, not instead of it.

  3. Protecting only one project in a multi-project pipeline. If your source data is in project A and your output destination is in project B, both must be inside the perimeter. Protecting only project A leaves a clear exit through project B. Audit the full data flow before finalising the perimeter scope.

  4. Forgetting external integrations during dry-run review. Third-party tools, data partners, and external APIs that legitimately access your data need planned exceptions before enforcement. If you have Cloud Storage access issues after enforcement, see troubleshooting storage access denied errors.

  5. Not verifying which services VPC-SC supports. Not all GCP services are VPC-SC compatible. Restricting an unsupported service will not protect it and may produce unexpected behaviour. Always verify that the services you intend to protect appear on Google’s supported products list before designing the perimeter.

  6. Writing broad exceptions that weaken the perimeter. An access level that permits any IP or any identity provides no protection. Access levels should be as specific as possible. Broad exceptions introduced to resolve dry-run log entries often indicate that the underlying access pattern needs proper ingress or egress rules, not a blanket exception.

Frequently asked questions

What is VPC Service Controls in Google Cloud?

VPC Service Controls create a security perimeter around Google Cloud service APIs such as BigQuery, Cloud Storage, and Pub/Sub. They restrict access based on trusted context, not just identity. Even a principal with valid IAM permissions is blocked if their request comes from outside the perimeter: wrong network, unmanaged device, or untrusted project. The primary goal is to prevent data exfiltration through authorised API calls, a threat that IAM alone cannot address.

What is the difference between VPC Service Controls and VPC firewalls?

VPC firewalls operate at the network layer and control traffic to and from virtual machines based on IP, port, and protocol. VPC Service Controls operate at the Google Cloud API layer. They control which identities and networks can call GCP service APIs regardless of the network path. A request that travels entirely within a private network can still be blocked by VPC-SC if the calling context does not satisfy the access level criteria. Both controls address different threat surfaces and are typically used together.

Does VPC Service Controls replace IAM?

No. VPC-SC restricts the context from which APIs can be called: source network, device state, and identity origin. IAM controls what an authorised identity can do. An account with storage.admin inside the perimeter retains full admin rights within that context. VPC-SC and IAM least privilege are complementary controls that address different threat vectors. Both are required for a complete security posture.

What is dry-run mode in VPC Service Controls?

Dry-run mode lets you test a perimeter configuration without blocking any traffic. Requests that would be denied in enforced mode are instead permitted but logged as Policy Denied entries in Cloud Audit Logs. Reviewing these logs reveals exactly which workloads would break if you enforced the perimeter. Always run dry-run mode for at least two weeks before enforcement to capture infrequent traffic patterns such as monthly batch jobs and weekly reporting pipelines.

When should I use a bridge perimeter?

Use a bridge perimeter when you need a controlled, auditable data path between two separate service perimeters, for example between a production data perimeter and an analytics perimeter. A bridge creates a specific connection between them without merging the two perimeters. Without a bridge, service-to-service calls that cross perimeter boundaries are blocked even if both projects have valid IAM permissions. Bridges should be scoped as narrowly as possible to limit the exposed surface between perimeters.

Last verified: 22 March 2026 Cloud services change frequently. Verify details against official documentation before making infrastructure decisions.