Skip to content
Mekas Cloud Services
Security

VPC vs. VPC Service Controls: A Complete Guide to Protecting Your Google Cloud Workloads

Raj Meka and Mekas Cloud Services
Diagram-style illustration representing a security perimeter around Google Cloud data services

Executive summary: “VPC” and “VPC Service Controls” share three letters and almost nothing else, and that naming collision is the single biggest source of confusion for engineers arriving at Google Cloud from traditional data-center networking, AWS, or Azure. A VPC is a network — subnets, routes, firewall rules. VPC Service Controls is an API-level perimeter that stops data from leaving a defined boundary of Google-managed services, whether or not a VPC network is involved at all. This guide untangles the two, explains Context-Aware Access and how it shares infrastructure with VPC-SC, walks through configuration from a first single-project perimeter to a multi-perimeter enterprise architecture with working gcloud commands, covers five real use cases from a 15-person startup to a multinational conglomerate, and closes with the pros, cons, and a decision framework for whether you actually need it — or whether a lighter-weight alternative gets you most of the protection with a fraction of the operational cost.

Table of contents

  1. The confusion, named
  2. What a VPC actually is
  3. What VPC Service Controls actually is
  4. The building blocks
  5. Context-Aware Access
  6. Basic configuration: your first perimeter
  7. Intermediate configuration: multiple projects and exceptions
  8. Advanced configuration: multi-perimeter architecture
  9. Use cases by size and industry
  10. Pros and cons for internal users
  11. Pros and cons for external users
  12. Do you actually need VPC Service Controls?
  13. Alternatives and complements to VPC-SC
  14. Common mistakes
  15. Best practices checklist
  16. Next steps
  17. FAQ
  18. References

The confusion, named

If you’ve spent years running networks in a data center, on AWS, or on Azure, “VPC” already means something very specific to you: a virtual network, subnets, route tables, security groups or firewall rules, maybe some peering. Google Cloud’s VPC is that same concept, mostly — global by default instead of regional, but conceptually familiar.

Then someone mentions VPC Service Controls in the same breath, and the natural assumption is that it’s a more advanced version of the same thing — better firewall rules, maybe, or a stricter routing policy. It isn’t. VPC Service Controls (VPC-SC) has almost nothing to do with network routing. It’s a perimeter around API access to Google-managed services — Cloud Storage, BigQuery, Vertex AI, Pub/Sub, and dozens of others — that blocks data from crossing a boundary you define, independent of network topology, and in most cases independent of IAM as well. Google’s own documentation is explicit about this: VPC Service Controls doesn’t require you to have a VPC network at all.

That single fact resolves most of the confusion on its own. A VPC is infrastructure you build. VPC Service Controls is a policy you declare, enforced by Google’s infrastructure, about which projects and networks are allowed to talk to which managed services. You can — and in plenty of real architectures, do — have projects protected by VPC-SC with no custom VPC network in them whatsoever, because the thing being protected (a Cloud Storage bucket, a BigQuery dataset) was never “in” a VPC in the first place. It’s a Google-managed resource reached over an API, and that API is exactly what the perimeter governs.

If you’re coming from AWS, the closest single-service comparison is a combination of VPC endpoint policies and Service Control Policies — endpoint policies scope what an API call reaching a VPC endpoint can do, SCPs scope what an entire account or OU can do — but neither one, alone or combined, gives you a single perimeter object with dry-run testing and cross-service ingress/egress rules the way VPC-SC does. If you’re coming from Azure, the newer Azure Network Security Perimeter (generally available for services like Blob Storage and SQL Database) is a genuinely close conceptual match — a logical boundary around PaaS resources with its own enforced/transition modes — and is the best mental model to borrow if you already know it.

What a VPC actually is

Quickly, for completeness, since it’s the term everyone already half-knows: a Google Cloud VPC network is a global, project-scoped (or Shared-VPC-scoped) virtual network providing connectivity for your Compute Engine VMs, GKE clusters, and other network-attached resources. It has subnets (regional, unlike AWS’s zonal subnets), routes, firewall rules or firewall policies, and can be extended with peering, Private Service Connect, Cloud VPN, or Interconnect. Every VM you run, every internal load balancer, every GKE pod’s networking — that’s VPC territory.

None of that is what VPC Service Controls protects. VPC-SC doesn’t care about your subnets or your firewall rules. It cares about one thing: can this caller (identified by project, network, and sometimes identity) make this API call to this managed service. That’s a fundamentally different question, answered by a fundamentally different system, that happens to share four letters of its name with the network you already know.

What VPC Service Controls actually is

The mental model that actually works: VPC Service Controls draws a boundary — a service perimeter — around a set of projects (or a whole VPC network), and by default blocks every API call to a defined list of Google-managed services if that call crosses the boundary. Inside the perimeter, everything talks freely. Cross the line — a gsutil cp from an unauthorized project trying to read a bucket inside the perimeter, a BigQuery export job trying to write to a dataset outside it — and the call is denied with a 403, no matter how permissive the caller’s IAM roles are.

That last point is the one worth sitting with: VPC Service Controls is not an IAM replacement, it’s a check that runs in addition to IAM, and it can deny a call that IAM would otherwise allow. A data scientist with roles/bigquery.admin on a project inside the perimeter still cannot export that data to a bucket in an unprotected project outside the perimeter, even though IAM alone would happily let them. This is exactly the scenario VPC-SC exists to stop: an over-permissioned identity (or a compromised one) moving data somewhere it shouldn’t go, not because IAM was misconfigured, but because IAM is the wrong control for this specific risk. IAM answers “who can do what.” VPC-SC answers “where is this data allowed to go, no matter who’s asking.”

flowchart LR
    subgraph Perimeter["Service perimeter: prod-data"]
        BQ[BigQuery]
        GCS[Cloud Storage]
        VAI[Vertex AI]
    end
    Engineer["Engineer with\nroles/bigquery.admin"] -- "allowed: inside perimeter" --> BQ
    Engineer -- "denied: crosses perimeter\neven though IAM allows it" --> External[Bucket in unprotected project]
    Outsider["Caller outside perimeter,\nno ingress rule"] -- "denied by default" --> GCS

The building blocks

A handful of primitives make up every VPC-SC design, from the simplest to the most elaborate:

  • Access policy. The top-level container for all Access Context Manager resources in your organization — access levels and service perimeters both live under it. Almost every org has exactly one.
  • Service perimeter. The boundary itself, wrapping a set of resources (projects by number, or VPC networks) and a list of restricted services — the Google APIs (storage.googleapis.com, bigquery.googleapis.com, aiplatform.googleapis.com, and dozens more on the supported products list) that get the perimeter’s protection.
  • Dry-run mode. A perimeter can run in dry-run mode, logging what would have been blocked without actually blocking anything — the only sane way to roll this out, covered in depth below.
  • Access levels. Defined once in Access Context Manager, an access level is a named condition — an IP range, a device policy requirement, a combination of both — that can be referenced by both VPC-SC ingress rules and Context-Aware Access. More on this in the next section, since it’s the piece that ties VPC-SC and Context-Aware Access together.
  • Ingress and egress rules. Directional exceptions to the default-deny boundary. An ingress rule allows a specific caller (by identity, source project, or access level) from outside the perimeter to reach specific operations inside it. An egress rule does the reverse — letting something inside the perimeter reach a specific target outside it. These replaced the older perimeter bridge pattern for most new multi-project designs.
  • VPC accessible services. A narrower, VPC-network-scoped restriction: even inside an allowed perimeter, you can limit which services are reachable from a given VPC’s network endpoints specifically, via --enable-vpc-accessible-services and --vpc-allowed-services. Most teams don’t need this on day one; it matters once you’re segmenting which workloads inside a perimeter can call which APIs.
flowchart TB
    ACM["Access Context Manager\n(one access policy per org)"]
    AL["Access Levels\n(IP range, device trust, combinations)"]
    SP["Service Perimeters\n(restricted services + resources)"]
    IE["Ingress / Egress Rules"]
    ACM --> AL
    ACM --> SP
    AL -->|referenced by| IE
    IE -->|attached to| SP
    AL -->|also referenced by| CAA["Context-Aware Access\n(console, gcloud, Workspace)"]

Context-Aware Access

This is the feature that gets tangled up with VPC-SC most often, because they genuinely do share infrastructure — just not the same enforcement point.

Context-Aware Access (delivered through Chrome Enterprise Premium, the current name for what was previously branded BeyondCorp Enterprise) lets you gate access to Google Cloud console, the gcloud CLI, Google APIs, and Google Workspace apps based on the context of the request — the user’s IP range, whether their device is a managed, encrypted, screen-locked corporate laptop, their location, and more — rather than just their password and a static IP allowlist. It’s Google’s implementation of BeyondCorp-style Zero Trust access: identity and device posture replace network location as the basis for trust.

The connection to VPC-SC is this: both features consume access levels defined in the same place, Access Context Manager. Define an access level called corp-managed-devices once — a combination of a corporate IP range and a device policy requiring encryption and a screen lock — and you can:

  • Attach it to Context-Aware Access so that only requests satisfying it can open the Cloud console or run gcloud commands, and
  • Reference that same access level inside a VPC-SC ingress rule, so that only callers satisfying it can reach a protected Cloud Storage bucket from outside the perimeter.

They’re not the same control wearing two names — they enforce at genuinely different layers, and you’ll frequently want both, deliberately configured separately. Context-Aware Access is about who gets into the console and APIs in the first place. VPC-SC is about where data inside those APIs is allowed to move once someone’s in. A contractor on an unmanaged laptop might be correctly blocked by Context-Aware Access before they ever authenticate to the console; an already-authenticated, fully-trusted internal engineer with an overly broad IAM role is exactly who VPC-SC is there to stop from exfiltrating a dataset to their personal project. Different threat, different layer, same underlying access-level primitive — that shared primitive is the detail that resolves most of the “wait, isn’t this the same thing” confusion once it clicks.

Basic configuration: your first perimeter

Everything below assumes Organization Admin or Access Context Manager Admin (roles/accesscontextmanager.policyAdmin) permissions, and that the Access Context Manager API is enabled. Service perimeters are organization-level resources — you can’t create one scoped to just a project the way you’d create a firewall rule; even a single-project pilot creates an org-level object.

Step 1 — Create the access policy

Most orgs need exactly one of these, ever:

gcloud access-context-manager policies create \
  --organization=YOUR_ORG_ID \
  --title="Primary access policy"

Note the numeric policy ID it returns — every command from here references it as --policy=POLICY_ID.

Step 2 — Create a basic access level

Start simple: an access level satisfied by requests from your corporate IP range.

cat > corp-network.yaml << 'EOF'
- ipSubnetworks:
    - 203.0.113.0/24
EOF

gcloud access-context-manager levels create corp_network \
  --policy=POLICY_ID \
  --title="Corporate network" \
  --basic-level-spec=corp-network.yaml

Step 3 — Create the perimeter in dry-run mode

Protect a single project’s Cloud Storage and BigQuery access, without blocking anything yet:

gcloud access-context-manager perimeters dry-run create prod_data_perimeter \
  --policy=POLICY_ID \
  --perimeter-title="Production data perimeter" \
  --perimeter-type=regular \
  --perimeter-resources=projects/PROJECT_NUMBER \
  --perimeter-restricted-services=storage.googleapis.com,bigquery.googleapis.com

Replace PROJECT_NUMBER with the numeric project number (not the project ID string) — a detail that trips up almost everyone the first time, since every other gcloud command you’re used to takes the project ID.

Step 4 — Watch the dry-run violations

Give it real production traffic for at least a few days — a week is safer — and review what would have been blocked, either in the Access Context Manager dry-run violations view in the console, or via Cloud Logging with the policy_violated label on VpcServiceControlAuditMetadata entries. This is where you discover the BI tool, the CI pipeline, or the on-call engineer’s laptop that would have broken the moment you enforced.

Step 5 — Promote to enforced mode

Once dry-run is clean (or you’ve written the ingress/egress rules to cover every legitimate exception you found):

gcloud access-context-manager perimeters dry-run enforce prod_data_perimeter \
  --policy=POLICY_ID

That’s a complete, working, single-project perimeter — the entire “basic” tier most teams need to get real protection on their most sensitive project.

Intermediate configuration: multiple projects and exceptions

A single project’s perimeter rarely stays that simple for long. Two things change at this tier: more than one project needs to be inside the same perimeter, and something legitimate needs to cross the boundary.

Adding more projects to the perimeter

gcloud access-context-manager perimeters update prod_data_perimeter \
  --policy=POLICY_ID \
  --add-resources=projects/SECOND_PROJECT_NUMBER

Every project added shares the same restricted-services list and the same default-deny boundary — this is the right model when several projects genuinely form one trust zone (say, a data warehouse project and the ETL project that feeds it), not a way to just group unrelated projects for convenience.

Allowing a specific external caller in — an ingress rule

The most common real request: “our BI tool (or a specific vendor, or a specific service account) needs to query BigQuery inside the perimeter from outside it.” Define it narrowly, by service account and method, not with a blanket allow:

# ingress.yaml
- ingressFrom:
    identityType: IDENTITY_TYPE_UNSPECIFIED
    identities:
      - serviceAccount:[email protected]
    sources:
      - resource: projects/VENDOR_PROJECT_NUMBER
  ingressTo:
    operations:
      - serviceName: bigquery.googleapis.com
        methodSelectors:
          - method: google.cloud.bigquery.v2.TableDataService.List
    resources:
      - projects/PROJECT_NUMBER
gcloud access-context-manager perimeters update prod_data_perimeter \
  --policy=POLICY_ID \
  --set-ingress-policies=ingress.yaml

Letting something inside the perimeter reach out — an egress rule

The mirror case: a Cloud Function inside the perimeter needs to write export files to a bucket in a separate, unprotected logging project.

# egress.yaml
- egressFrom:
    identityType: IDENTITY_TYPE_UNSPECIFIED
    identities:
      - serviceAccount:exporter@PROJECT_ID.iam.gserviceaccount.com
  egressTo:
    operations:
      - serviceName: storage.googleapis.com
        methodSelectors:
          - method: google.storage.objects.create
    resources:
      - projects/LOGGING_PROJECT_NUMBER
gcloud access-context-manager perimeters update prod_data_perimeter \
  --policy=POLICY_ID \
  --set-egress-policies=egress.yaml

Giving remote employees access without opening the whole perimeter

If your access level is a static corporate IP range, remote and hybrid employees will fail it the moment they’re not on the office network or VPN. Rather than widening the perimeter’s ingress broadly, build a richer access level combining IP range OR a managed, encrypted, verified device — then reference that access level in both Context-Aware Access (for console/API login) and the perimeter’s ingress rule (for the data path), so the same policy governs both consistently.

Advanced configuration: multi-perimeter architecture

Past a certain scale — multiple business units, multiple compliance scopes, multiple environments — a single perimeter stops being the right shape. The advanced pattern is one perimeter per trust boundary, connected deliberately.

flowchart TB
    subgraph OrgFolder["Organization"]
        subgraph Prod["Perimeter: production"]
            ProdBU1[BU1 prod projects]
            ProdBU2[BU2 prod projects]
        end
        subgraph NonProd["Perimeter: non-production"]
            Dev[Dev/staging projects]
        end
        subgraph Regulated["Perimeter: PCI scope"]
            Payments[Payments processing]
        end
    end
    NonProd -. "no default path —\nexplicit ingress/egress only" .-> Prod
    Prod -. "explicit egress rule,\nnarrow scope" .-> Regulated

A few patterns that show up specifically at this tier:

  • Folder-aligned perimeters. Map perimeters to your existing folder structure (by environment, by business unit, by compliance scope) rather than inventing a parallel grouping — it keeps IAM, Organization Policy, and VPC-SC reasoning about the same boundaries.
  • Terraform for perimeter state, once you have more than two or three perimeters to reason about by hand:
resource "google_access_context_manager_service_perimeter" "prod_data" {
  parent = "accessPolicies/${var.access_policy_id}"
  name   = "accessPolicies/${var.access_policy_id}/servicePerimeters/prod_data_perimeter"
  title  = "Production data perimeter"

  status {
    resources           = ["projects/${var.prod_project_number}"]
    restricted_services  = ["storage.googleapis.com", "bigquery.googleapis.com", "aiplatform.googleapis.com"]

    ingress_policies {
      ingress_from {
        sources {
          access_level = google_access_context_manager_access_level.corp_network.name
        }
        identity_type = "ANY_IDENTITY"
      }
      ingress_to {
        resources = ["*"]
        operations {
          service_name = "storage.googleapis.com"
          method_selectors { method = "*" }
        }
      }
    }
  }
}
  • Combining with Private Service Connect for AI/agent workloads. If you’re also running Vertex AI agents that need to reach on-premises resources or the public internet (patterns covered in our earlier PSC interface walkthrough and private network architecture for Gemini Enterprise posts), remember that VPC-SC and PSC solve different problems that compose together: PSC controls network reachability, VPC-SC controls API-level data movement. An agent can have a perfectly valid PSC interface to an on-premises database and still be correctly blocked by VPC-SC from exporting a protected BigQuery table to an unapproved destination — that’s not a bug, that’s two independent controls both doing their job.
  • Troubleshooting a 403 that shouldn’t be there. The single highest-leverage advanced tool is the Policy Troubleshooter combined with the VPC-SC-specific audit log entries (policy_violated on the AuditLog for the denied service) — resist the urge to guess and widen the perimeter; find the exact denied operation and identity from the log first, then write the narrowest rule that fixes it. The VPC Service Controls Recommender will also proactively suggest tightening or loosening restricted-services lists based on observed traffic, which is worth reviewing quarterly rather than only at initial rollout.
  • VPC accessible services for workload segmentation. Once a perimeter holds workloads with genuinely different needs — a GKE cluster that should only ever call Cloud Storage and Pub/Sub, sitting in the same perimeter as a data science VM that needs BigQuery and Vertex AI too — --enable-vpc-accessible-services with a scoped --vpc-allowed-services list lets you narrow what’s reachable from each VPC network’s endpoints specifically, without splitting them into separate perimeters.

Use cases by size and industry

Abstract configuration only goes so far — here’s how the decision and the design actually play out at different scales.

A 15-person healthtech startup storing PHI. Cloud Storage and BigQuery hold patient intake data; the whole engineering team is five people who also do DevOps. They configured one perimeter, dry-run only for the first month, around the single production project holding PHI — restricted services limited to storage.googleapis.com and bigquery.googleapis.com. No multi-project split, no custom access levels beyond the default corporate-network one, no Terraform. This is close to the minimum viable VPC-SC deployment, and it’s the right call: they carry regulated data, so skipping VPC-SC entirely wasn’t really on the table once a HIPAA-conscious enterprise customer asked about data exfiltration controls in a security questionnaire, but anything more elaborate than one perimeter would have been effort spent on architecture instead of product.

A 200-engineer payments company in PCI-DSS scope. Cardholder data touches a specific set of projects, deliberately isolated from the rest of the company’s much larger GCP footprint. They run three perimeters — production payments, non-production payments, and everything-else — with the payments perimeters requiring a Context-Aware Access level (managed device + corporate VPN) for any human console access, and narrow, individually reviewed ingress rules for the two SaaS fraud-detection vendors that need read access to specific BigQuery views. PCI-DSS’s network segmentation requirement is a direct, named reason for this shape — VPC-SC here isn’t a nice-to-have, it’s part of how they demonstrate segmentation to a QSA during assessment.

A multinational conglomerate with a dozen business units, several of them acquired. Hundreds of projects, an org hierarchy with folders per business unit, and a real, recurring integration problem: newly acquired companies show up with their own GCP orgs (or none at all) and their own data-handling norms. The pattern here is one perimeter per business-unit folder, connected through narrow, explicitly reviewed egress rules to a small number of shared-services perimeters (central data warehouse, central logging) rather than one org-wide perimeter that would force every business unit through the same restricted-services list and the same change-review process. When a new acquisition’s projects are folded in, they land inside their own new perimeter first, in dry-run, and only get ingress/egress rules to shared services after an explicit security review — never inherited automatically from being in the same org.

A federal contractor building toward FedRAMP Moderate. VPC-SC maps directly to NIST 800-53’s SC-7 (Boundary Protection) control family, and assessors specifically ask for a documented, tested perimeter around anything touching Controlled Unclassified Information. This org runs VPC-SC in enforced mode as table stakes, paired with CMEK on data at rest and a hierarchical Organization Policy denying public IPs at the folder level — for this profile, VPC-SC isn’t really a discretionary architectural decision at all; it’s closer to a compliance line item that happens to require real engineering work to satisfy correctly.

An AI company protecting proprietary training data and model weights. The threat model here is specifically insider risk and credential compromise, not an external network attacker: a data scientist (or their compromised laptop) with legitimate, broad IAM access to a training dataset in Cloud Storage and Vertex AI, who could otherwise copy that dataset to a personal Google account’s GCP project in seconds. A single perimeter around the ML platform project, restricted services covering storage.googleapis.com and aiplatform.googleapis.com, with no ingress rule granting personal-project access under any circumstance, closes exactly that gap — and does so regardless of how permissive that data scientist’s IAM roles need to be for their actual job.

Pros and cons for internal users

Detail
Pro: real defense-in-depth Stops data movement that IAM alone would allow, catching the over-permissioned-identity and compromised-credential scenarios IAM reviews routinely miss.
Pro: catches misconfiguration before it leaks A bucket accidentally made public, or an IAM binding accidentally granted to allUsers, is far less dangerous inside a perimeter — VPC-SC still blocks the exfiltration path even if IAM was the thing that got it wrong.
Pro: audit trail for free Every allowed and denied cross-perimeter call is logged, giving security teams a ready-made data-movement audit trail without instrumenting anything themselves.
Con: breaks local dev workflows until fixed An engineer’s laptop running gcloud or a local script against a protected project from an unrecognized network fails with an opaque 403 the first time, every time, until an access level covers it.
Con: error messages don’t explain themselves “Request is prohibited by organization’s policy” tells you almost nothing about which rule, which service, or which identity caused it — diagnosing a denial genuinely requires knowing to go find the audit log entry, a skill most engineers don’t have on day one.
Con: real, ongoing operational overhead Access levels, ingress/egress rules, and perimeter membership all need an owner who reviews and updates them as the org changes — this isn’t a “configure once” control.
Con: partial product support Not every Google Cloud service has full VPC-SC support; check the supported products list before assuming a newly adopted service is covered, and expect the occasional legitimate exception rule for a service that isn’t.

Pros and cons for external users

Detail
Pro: a genuine compliance and sales asset For any vendor or SaaS company selling into healthcare, finance, or government, a documented, enforced VPC-SC perimeter is a concrete, verifiable answer to the data-exfiltration question that shows up in nearly every enterprise security questionnaire.
Pro: limits blast radius from third-party access If a partner’s IAM binding is over-scoped or their credentials leak, VPC-SC still stops that access from reaching data outside the intended boundary — a meaningful backstop when you don’t fully control a partner’s own security hygiene.
Con: SaaS and BI integrations need explicit, maintained rules Every third-party tool that touches a protected API needs an ingress or egress rule scoped to its service account and methods — and needs that rule updated if the vendor changes service accounts, IP ranges, or API usage patterns, which happens more often than most teams plan for.
Con: slows partner and vendor onboarding Adding a new data-sharing partner is no longer “grant an IAM role” — it’s “grant an IAM role, then write and test an ingress or egress rule,” which adds real days to onboarding timelines if the process isn’t already routine for your team.
Con: can push engineering teams toward looser workarounds If the ingress/egress rule process is slow or poorly owned, the predictable failure mode is engineers requesting broader exceptions than necessary just to unblock themselves — which quietly erodes the whole point of the perimeter. Fast, well-documented internal rule requests are what prevent this.

Do you actually need VPC Service Controls?

Work through these in order:

  1. Do you handle regulated or genuinely sensitive data in a Google-managed service — PHI, PCI cardholder data, government-controlled data, source code or model weights that are core IP? If no, skip to the alternatives section below; VPC-SC’s overhead usually isn’t justified yet.
  2. Is there a compliance framework, contractual obligation, or enterprise customer requirement naming a data exfiltration or boundary-protection control? If yes, that’s close to a mandate — HIPAA-adjacent expectations, PCI-DSS segmentation, FedRAMP SC-7, or a customer security questionnaire asking the question directly all point the same direction.
  3. Do you have someone who will actually own access levels and perimeter rules as the org changes? VPC-SC configured once and never revisited drifts into either a false sense of security (rules too broad) or constant breakage (rules too narrow, no one available to fix them). If the honest answer is “no one has time for this,” that’s a real signal to either invest in the ownership first or start with the lighter-weight alternatives below while that capacity is built.
  4. Would a data exfiltration incident be materially worse than a typical security incident for your business — regulatory fines, loss of a marquee customer, loss of core IP? The more the answer is yes, the more the operational cost of VPC-SC is worth paying even before a formal mandate exists.

If most of these point toward “yes,” start with the basic single-perimeter configuration above around your most sensitive project, in dry-run, and expand from there. If most point toward “not yet,” the alternatives below cover a meaningful fraction of the same risk with far less ongoing overhead — revisit this decision when your data sensitivity, compliance obligations, or team size change.

Alternatives and complements to VPC-SC

None of these require an org-level perimeter, and several are worth having even after you adopt VPC-SC, since they cover angles it doesn’t:

  • Domain-restricted sharing — the iam.allowedPolicyMemberDomains organization policy constraint prevents IAM bindings to any identity outside your organization’s domain, closing the “accidentally shared a bucket with a personal Gmail account” gap without touching API-level enforcement at all.
  • Cloud Storage public access prevention — an org policy constraint that outright blocks a bucket from ever being made public, regardless of IAM or ACL misconfiguration, at essentially zero operational cost.
  • IAM Conditions — scope roles to specific resources, tags, or time windows rather than granting broad project-level roles, shrinking the blast radius of a compromised or over-permissioned identity without a perimeter at all.
  • DLP API scanning — Sensitive Data Protection can classify and flag regulated data landing in Cloud Storage or BigQuery, giving you detection even where you have no exfiltration-prevention control in place yet.
  • Security Command Center findingsVPC-SC integrates with Security Command Center for organizations that already have it, but SCC’s own threat detection is useful compensating monitoring even without VPC-SC turned on.
  • Tight service-account scoping and no service-account keys — an Organization Policy constraint blocking service account key creation, combined with narrowly scoped, per-workload service accounts, removes a large share of the credential-based exfiltration risk VPC-SC is otherwise the backstop for.

A pragmatic path for a growing team: start with domain-restricted sharing, public access prevention, and tight IAM as your baseline everywhere — cheap, always-on, no ownership burden — then layer VPC-SC on top specifically for the projects that hold your most sensitive data, once question 3 above has a real answer.

Common mistakes

  • Enforcing before dry-run is clean. The single most common cause of a bad launch — every legitimate exception should be found and ruled for before enforcement, not discovered by an outage afterward.
  • Using a project ID instead of a project number in --perimeter-resources. VPC-SC resources are always referenced by project number, not the string project ID everything else in gcloud uses.
  • Treating a perimeter bridge as the default for new multi-project designs. Ingress/egress rules are the current recommended pattern; reach for bridges only when maintaining an existing environment that already uses them.
  • Granting broad ingress rules to “unblock” a request instead of scoping to the exact identity and method. A rule allowing ANY_IDENTITY because narrowing it felt slower defeats much of the point of the perimeter.
  • No owner for access levels and rules after initial rollout. Perimeters that no one revisits either rot into uselessly broad exceptions or break the first time the org changes.
  • Assuming every Google Cloud service is covered. Always check the supported products list before designing around a specific service — partial or no support for a newly adopted product is a common late surprise.
  • Conflating Context-Aware Access with VPC-SC and configuring only one. They protect different things; a design that only gates console/API login but never the data-plane API calls (or vice versa) has a real gap.

Best practices checklist

Rollout

  • Every perimeter starts in dry-run mode, reviewed for at least a week of real traffic before enforcement
  • PROJECT_NUMBER, not project ID, used consistently in --perimeter-resources
  • Ingress/egress rules scoped to specific identities and methods, never ANY_IDENTITY as a default

Architecture

  • Perimeters aligned to existing folder/business-unit/compliance-scope boundaries, not an invented parallel grouping
  • Ingress/egress rules used for new multi-project designs; bridges reserved for maintaining existing ones
  • Access levels shared deliberately between Context-Aware Access and VPC-SC ingress rules where the same trust condition applies to both

Operations

  • A named owner for access levels and perimeter rule changes, not an ad hoc “whoever’s free” process
  • VPC-SC Recommender reviewed on a quarterly cadence, not just at initial rollout
  • Cloud Logging alerting on policy_violated entries in enforced perimeters, not just passive log retention

Compliance

  • Perimeter design documented against the specific compliance requirement driving it (PCI segmentation, FedRAMP SC-7, etc.), not just “security best practice”
  • Regulated-data projects isolated in their own perimeter, not sharing one with lower-sensitivity workloads

Before you build one at all

  • Domain-restricted sharing, public access prevention, and IAM Conditions already in place as the baseline everywhere
  • A real answer to “who owns this after launch” before starting configuration, not after

Next steps

  1. Answer the four decision questions above honestly before writing a single gcloud command — the biggest waste of engineering time here is building a perimeter for data that didn’t need one, or skipping one that a compliance conversation will force in six months anyway.
  2. If you’re moving forward, start with the baseline alternatives — domain-restricted sharing, public access prevention, tight IAM — even if VPC-SC is the end goal, since they cost almost nothing and cover gaps VPC-SC doesn’t.
  3. Pilot one perimeter, in dry-run, around your single most sensitive project before designing the multi-perimeter architecture — the dry-run violations you find there will teach you more about your real integration surface than any amount of upfront design.
  4. Name an owner for access levels and rules before enforcing anything — a perimeter with no owner is a perimeter that will either rot open or break production within a year.

If you’d rather have an experienced team assess whether VPC-SC is the right control for your workload — or design and roll out the perimeter itself — our Cloud Security team does exactly this kind of Google Cloud architecture work. Get in touch to talk through your specific environment.

FAQ

See the frequently asked questions section below this article for schema-formatted answers to the questions engineers ask most when evaluating VPC Service Controls for the first time.

References

Share this post
FAQ

Frequently asked questions

Is VPC Service Controls just a fancier firewall rule?

No, and that assumption causes most of the confusion. A firewall rule (in a VPC or anywhere else) controls network packets — IP addresses, ports, protocols. VPC Service Controls controls API calls to Google-managed services like Cloud Storage and BigQuery, based on which project or network the caller is in and what identity they're using, regardless of what network path the call took. A request from the right IP through the wrong project is blocked; a request from an unexpected IP through the right project and identity is allowed. It's an authorization boundary, not a packet filter.

Do I need a VPC network to use VPC Service Controls?

No. This surprises almost everyone coming from traditional networking. VPC Service Controls perimeters are defined around projects (by project number) or VPC networks, but the underlying resource being protected — Cloud Storage, BigQuery, Vertex AI — is a Google-managed multi-tenant service, not something living inside your VPC. You can put a project with no custom VPC at all inside a service perimeter and it works exactly the same way.

What's the actual difference between Context-Aware Access and VPC Service Controls?

They share the same underlying building block — an access level, defined once in Access Context Manager — but enforce it in different places. Context-Aware Access applies that access level to human access paths: the Google Cloud console, gcloud CLI, and (through Chrome Enterprise Premium) Google Workspace apps. VPC Service Controls applies the same access level inside a service perimeter's ingress rules, gating API calls to protected services regardless of whether a human or a service account is making them. Define the access level once, then decide which of the two enforcement points needs it — often both.

Does turning on VPC Service Controls add latency to API calls?

No meaningful data-plane latency. The perimeter check happens as an authorization decision at the same point Google's infrastructure already evaluates IAM — it isn't a proxy sitting in the request path adding a network hop. The real cost isn't latency, it's the review overhead: every new integration, every new engineer's laptop, every new third-party tool now needs an access level or an ingress/egress rule before it works, and that process takes real calendar time if nobody owns it.

Can a small startup just skip VPC Service Controls?

Often, yes — at least at first. If you're not handling regulated data (PHI, PCI cardholder data, government-controlled data) and have no compliance mandate requiring a documented exfiltration control, the operational overhead of owning access levels and perimeter changes usually isn't worth it for a five-person engineering team. Tighter IAM roles, domain-restricted sharing, Cloud Storage public access prevention, and DLP scanning cover a meaningful chunk of the same risk with far less day-to-day friction. Revisit the decision the moment you sign your first enterprise or healthcare customer, or the moment a compliance framework enters the conversation.

Will VPC Service Controls break our BI tool or SaaS integrations?

It will require you to explicitly allow them, which reads as "breaking" until you've done it once. Any third-party tool that calls a protected API from outside your perimeter — a BI tool querying BigQuery, a reverse-ETL tool writing to Cloud Storage — needs an egress rule (if the call originates inside the perimeter going out) or, more commonly, the vendor's access needs to be modeled with an ingress rule scoped to their service account and the specific methods they call. Budget real time for this during rollout; it's the single most common cause of a painful VPC-SC launch.

What's a service perimeter bridge, and should I use one?

A bridge lets two separate perimeters share resources bidirectionally without merging into one perimeter — it was the original pattern for multi-project setups. Google now recommends ingress and egress rules instead for new designs: rules are directional, resource- and identity-scoped, and don't require both perimeter owners to coordinate a shared bridge resource. Bridges still work and you'll see them in older environments, but design new multi-perimeter architectures with ingress/egress rules, not bridges.

Take the next step to start your journey with us

Transform your IT challenges into tailored solutions with expert support, 24/7.