VPC Service Controls for BigQuery
This page explains how to enhance security around BigQuery resources by
creating perimeters with VPC Service Controls. These perimeters restrict access to
and from BigQuery and are independent from
Identity and Access Management (IAM) controls. They're useful in the following use cases:
- Preventing data leakage by restricting access to resources, except those
specifically allowed in the ingress and egress rules.
- Securely loading data into BigQuery from third-party sources
or Trusted Cloud by S3NS services, such as Cloud Storage.
- Controlling data export from BigQuery to Cloud Storage or
other targets.
For more information, see the overview of VPC Service Controls.
Before you begin
Create the VPC Service Controls perimeter
The following example shows how to create a VPC Service Controls perimeter
that limits the range of external IP addresses that can access a
BigQuery project.
Create an access level that only allows access to a specified range of IP
addresses—for example, those within a corporate network. To create it, use
the gcloud access-context-manager levels create
command:
echo """
- ipSubnetworks:
- 162.222.181.0/24
- 2001:db8::/48
""" > level.yaml
gcloud access-context-manager levels create ACCESS_LEVEL_NAME \
--title="TITLE" --basic-level-spec=level.yaml
Replace the following:
ACCESS_LEVEL_NAME
: the ID of the access level
TITLE
: the human-readable title for the
service perimeter
For more information about creating access levels, see the example
implementations.
Protect the BigQuery resource by creating or updating a
perimeter. The following examples protect a project. For other use
cases, such as protecting data transfer from a Cloud Storage
bucket in another project, see the use cases.
Create perimeter
To create a new perimeter to protect the BigQuery project,
use the gcloud access-context-manager perimeters create
command:
echo """
- ingressFrom:
identityType: ANY_IDENTITY
sources:
- accessLevel: accessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME
ingressTo:
operations:
- methodSelectors:
- method: '*'
serviceName: bigquery.googleapis.com
resources:
- '*'
""" > ingress.yaml
gcloud access-context-manager perimeters create BIGQUERY_PERIMETER --title="TITLE" \
--resources=BIGQUERY_PROJECT_NUMBER \
--restricted-services=bigquery.googleapis.com \
--ingress-policies=ingress.yaml
--policy=POLICY_NAME
Replace the following:
POLICY_NAME
: the ID of the access policy
ACCESS_LEVEL_NAME
: the ID of the access level
PERIMETER
: the ID of the perimeter
TITLE
: the short, human-readable title for the
service perimeter
BIGQUERY_PROJECT_NUMBER
: the ID of
BigQuery project
POLICY_NAME
: the ID of the access policy
Update perimeter
To update an existing perimeter, use the gcloud access-context-manager perimeters update
command:
gcloud access-context-manager perimeters update BIGQUERY_PERIMETER --set-ingress-policies=ingress.yaml
Replace BIGQUERY_PERIMETER
with the ID of the perimeter
protecting the BigQuery resource.
Test the perimeter
Test your VPC Service Controls perimeter before enforcing it. For more
information, see Dry run mode for service
perimeters and Using dry-run
mode to test ingress or egress
policies.
Use cases
The following use case examples show how to protect data going in and out of
BigQuery with VPC Service Controls.
Query external table data from a Cloud Storage bucket in another project
The following examples show how to selectively allow communication between the
BigQuery and Cloud Storage projects when they are
separated by perimeters.
Allow the BigQuery project to access the
Cloud Storage project by updating the egress rules for the perimeter
around the Cloud Storage project:
echo """
- egressFrom:
identityType: ANY_IDENTITY
egressTo:
operations:
- methodSelectors:
- method: '*'
serviceName: storage.googleapis.com
resources:
- projects/BIGQUERY_PROJECT_NUMBER
""" > egress.yaml
gcloud access-context-manager perimeters update CLOUD_STORAGE_PERIMETER --policy=POLICY_NAME --set-egress-policies=egress.yaml
Replace the following:
BIGQUERY_PROJECT_NUMBER
: the ID of
BigQuery project
CLOUD_STORAGE_PERIMETER
: the ID of the perimeter
protecting the Cloud Storage resources
POLICY_NAME
: the ID of the access policy
Allow the Cloud Storage project to access the
BigQuery project by updating the egress rules for the
perimeter around the BigQuery project:
echo """
- egressFrom:
identityType: ANY_IDENTITY
egressTo:
operations:
- methodSelectors:
- method: '*'
serviceName: storage.googleapis.com
resources:
- projects/CLOUD_STORAGE_PROJECT_NUMBER
""" > egress1.yaml
gcloud access-context-manager perimeters update BIGQUERY_PERIMETER --policy=POLICY_NAME --set-egress-policies=egress1.yaml
Replace the following:
CLOUD_STORAGE_PROJECT_NUMBER
: the ID of Cloud Storage project
PERIMETER
: the ID of the perimeter
POLICY_NAME
: the ID of the access policy
Optional: if the perimeter protecting the BigQuery project
includes storage.googleapis.com
as a restricted service, you must update
the ingress rule:
echo """
- ingressFrom:
identityType: ANY_IDENTITY
sources:
- accessLevel: accessPolicies/POLICY_NAME/accessLevels/ACCESS_LEVEL_NAME
ingressTo:
operations:
- methodSelectors:
- method: '*'
serviceName: bigquery.googleapis.com
- methodSelectors:
- method: '*'
serviceName: storage.googleapis.com
resources:
- '*'
""" > ingress.yaml
gcloud access-context-manager perimeters create BIGQUERY_PERIMETER --title="TITLE" \
--resources=BIGQUERY_PROJECT_NUMBER \
--restricted-services=bigquery.googleapis.com \
--ingress-policies=ingress.yaml
--policy=POLICY_NAME
Import and export data from BigQuery Omni
As an extra layer of defense, you can use VPC Service Controls perimeters to
restrict access between BigQuery Omni and an external cloud
service. For more information and examples, see the
VPC Service Controls
configuration for when you create an Azure Blob Storage BigLake table.
What's next
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-08-25 UTC.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-08-25 UTC."],[[["\u003cp\u003eVPC Service Controls enhance BigQuery security by establishing perimeters that restrict access to and from BigQuery resources, independent of IAM controls.\u003c/p\u003e\n"],["\u003cp\u003eThese perimeters help prevent data leakage by limiting access to resources based on defined ingress and egress rules.\u003c/p\u003e\n"],["\u003cp\u003eVPC Service Controls facilitate secure data loading into BigQuery from third-party or Google Cloud services, and control data export to other services.\u003c/p\u003e\n"],["\u003cp\u003eCreating a perimeter involves defining an access level with specific IP address ranges and then protecting a BigQuery resource by creating or updating a perimeter with appropriate ingress and egress rules.\u003c/p\u003e\n"],["\u003cp\u003eVPC Service Controls can be used to selectively allow or restrict communication between BigQuery and other services like Cloud Storage, even across different projects and perimeters, by managing egress and ingress rules.\u003c/p\u003e\n"]]],[],null,["# VPC Service Controls for BigQuery\n=================================\n\nThis page explains how to enhance security around BigQuery resources by\ncreating perimeters with VPC Service Controls. These perimeters restrict access to\nand from BigQuery and are independent from\nIdentity and Access Management (IAM) controls. They're useful in the following use cases:\n\n- Preventing data leakage by restricting access to resources, except those specifically allowed in the ingress and egress rules.\n- Securely loading data into BigQuery from third-party sources or Google Cloud services, such as Cloud Storage.\n- Controlling data export from BigQuery to Cloud Storage or other targets.\n\nFor more information, see the [overview of VPC Service Controls](/vpc-service-controls/docs/overview).\n\nBefore you begin\n----------------\n\n- To get the permissions that you need to configure service perimeters, see [Access control with\n IAM](/vpc-service-controls/docs/access-control) for VPC Service Controls.\n- You must have an access policy for your organization. For more information, see [Create an access\n policy](/access-context-manager/docs/create-access-policy).\n\nCreate the VPC Service Controls perimeter\n-----------------------------------------\n\nThe following example shows how to create a VPC Service Controls perimeter\nthat limits the range of external IP addresses that can access a\nBigQuery project.\n\n1. Create an *access level* that only allows access to a specified range of IP\n addresses---for example, those within a corporate network. To create it, use\n the [`gcloud access-context-manager levels create`](/sdk/gcloud/reference/access-context-manager/levels/create) command:\n\n echo \"\"\"\n - ipSubnetworks:\n - 162.222.181.0/24\n - 2001:db8::/48\n \"\"\" \u003e level.yaml\n\n gcloud access-context-manager levels create \u003cvar translate=\"no\"\u003eACCESS_LEVEL_NAME\u003c/var\u003e \\\n --title=\"\u003cvar translate=\"no\"\u003eTITLE\u003c/var\u003e\" --basic-level-spec=level.yaml\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003eACCESS_LEVEL_NAME\u003c/var\u003e: the ID of the access level\n - \u003cvar translate=\"no\"\u003eTITLE\u003c/var\u003e: the human-readable title for the service perimeter\n\n For more information about creating access levels, see the [example\n implementations](/access-context-manager/docs/create-basic-access-level#example_implementations).\n2. Protect the BigQuery resource by creating or updating a\n perimeter. The following examples protect a project. For other use\n cases, such as protecting data transfer from a Cloud Storage\n bucket in another project, see the [use cases](#use-cases).\n\n ### Create perimeter\n\n\n To create a new perimeter to protect the BigQuery project,\n use the [`gcloud access-context-manager perimeters create`](/sdk/gcloud/reference/access-context-manager/perimeters/create) command: \n\n echo \"\"\"\n - ingressFrom:\n identityType: ANY_IDENTITY\n sources:\n - accessLevel: accessPolicies/\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e/accessLevels/\u003cvar translate=\"no\"\u003eACCESS_LEVEL_NAME\u003c/var\u003e\n ingressTo:\n operations:\n - methodSelectors:\n - method: '*'\n serviceName: bigquery.googleapis.com\n resources:\n - '*'\n\n \"\"\" \u003e ingress.yaml\n\n gcloud access-context-manager perimeters create \u003cvar translate=\"no\"\u003eBIGQUERY_PERIMETER\u003c/var\u003e --title=\"\u003cvar translate=\"no\"\u003eTITLE\u003c/var\u003e\" \\\n --resources=\u003cvar translate=\"no\"\u003eBIGQUERY_PROJECT_NUMBER\u003c/var\u003e \\\n --restricted-services=bigquery.googleapis.com \\\n --ingress-policies=ingress.yaml\n --policy=\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e: the ID of the access policy\n - \u003cvar translate=\"no\"\u003eACCESS_LEVEL_NAME\u003c/var\u003e: the ID of the access level\n - \u003cvar translate=\"no\"\u003ePERIMETER\u003c/var\u003e: the ID of the perimeter\n - \u003cvar translate=\"no\"\u003eTITLE\u003c/var\u003e: the short, human-readable title for the service perimeter\n - \u003cvar translate=\"no\"\u003eBIGQUERY_PROJECT_NUMBER\u003c/var\u003e: the ID of BigQuery project\n - \u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e: the ID of the access policy\n\n ### Update perimeter\n\n\n To update an existing perimeter, use the [`gcloud access-context-manager perimeters update`](/sdk/gcloud/reference/access-context-manager/perimeters/update) command: \n\n gcloud access-context-manager perimeters update \u003cvar translate=\"no\"\u003eBIGQUERY_PERIMETER\u003c/var\u003e --set-ingress-policies=ingress.yaml\n\n Replace \u003cvar translate=\"no\"\u003eBIGQUERY_PERIMETER\u003c/var\u003e with the ID of the perimeter\n protecting the BigQuery resource.\n\nTest the perimeter\n------------------\n\nTest your VPC Service Controls perimeter before enforcing it. For more\ninformation, see [Dry run mode for service\nperimeters](/vpc-service-controls/docs/dry-run-mode) and [Using dry-run\nmode to test ingress or egress\npolicies](/vpc-service-controls/docs/ingress-egress-rules#using-dryrun-ingress-egress-rules).\n\nUse cases\n---------\n\nThe following use case examples show how to protect data going in and out of\nBigQuery with VPC Service Controls.\n\n### Query external table data from a Cloud Storage bucket in another project\n\nThe following examples show how to selectively allow communication between the\nBigQuery and Cloud Storage projects when they are\nseparated by perimeters.\n\n1. Allow the BigQuery project to access the\n Cloud Storage project by updating the egress rules for the perimeter\n around the Cloud Storage project:\n\n echo \"\"\"\n - egressFrom:\n identityType: ANY_IDENTITY\n egressTo:\n operations:\n - methodSelectors:\n - method: '*'\n serviceName: storage.googleapis.com\n resources:\n - projects/\u003cvar translate=\"no\"\u003eBIGQUERY_PROJECT_NUMBER\u003c/var\u003e\n \"\"\" \u003e egress.yaml\n\n gcloud access-context-manager perimeters update \u003cvar translate=\"no\"\u003eCLOUD_STORAGE_PERIMETER\u003c/var\u003e --policy=\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e --set-egress-policies=egress.yaml\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003eBIGQUERY_PROJECT_NUMBER\u003c/var\u003e: the ID of BigQuery project\n - \u003cvar translate=\"no\"\u003eCLOUD_STORAGE_PERIMETER\u003c/var\u003e: the ID of the perimeter protecting the Cloud Storage resources\n - \u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e: the ID of the access policy\n2. Allow the Cloud Storage project to access the\n BigQuery project by updating the egress rules for the\n perimeter around the BigQuery project:\n\n echo \"\"\"\n - egressFrom:\n identityType: ANY_IDENTITY\n egressTo:\n operations:\n - methodSelectors:\n - method: '*'\n serviceName: storage.googleapis.com\n resources:\n - projects/\u003cvar translate=\"no\"\u003eCLOUD_STORAGE_PROJECT_NUMBER\u003c/var\u003e\n \"\"\" \u003e egress1.yaml\n\n gcloud access-context-manager perimeters update \u003cvar translate=\"no\"\u003eBIGQUERY_PERIMETER\u003c/var\u003e --policy=\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e --set-egress-policies=egress1.yaml\n\n Replace the following:\n - \u003cvar translate=\"no\"\u003eCLOUD_STORAGE_PROJECT_NUMBER\u003c/var\u003e: the ID of Cloud Storage project\n - \u003cvar translate=\"no\"\u003ePERIMETER\u003c/var\u003e: the ID of the perimeter\n - \u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e: the ID of the access policy\n3. Optional: if the perimeter protecting the BigQuery project\n includes `storage.googleapis.com` as a restricted service, you must update\n the ingress rule:\n\n echo \"\"\"\n - ingressFrom:\n identityType: ANY_IDENTITY\n sources:\n - accessLevel: accessPolicies/\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e/accessLevels/\u003cvar translate=\"no\"\u003eACCESS_LEVEL_NAME\u003c/var\u003e\n ingressTo:\n operations:\n - methodSelectors:\n - method: '*'\n serviceName: bigquery.googleapis.com\n - methodSelectors:\n - method: '*'\n serviceName: storage.googleapis.com\n resources:\n - '*'\n\n \"\"\" \u003e ingress.yaml\n\n gcloud access-context-manager perimeters create \u003cvar translate=\"no\"\u003eBIGQUERY_PERIMETER\u003c/var\u003e --title=\"\u003cvar translate=\"no\"\u003eTITLE\u003c/var\u003e\" \\\n --resources=\u003cvar translate=\"no\"\u003eBIGQUERY_PROJECT_NUMBER\u003c/var\u003e \\\n --restricted-services=bigquery.googleapis.com \\\n --ingress-policies=ingress.yaml\n --policy=\u003cvar translate=\"no\"\u003ePOLICY_NAME\u003c/var\u003e\n\n### Import and export data from BigQuery Omni\n\nAs an extra layer of defense, you can use VPC Service Controls perimeters to\nrestrict access between BigQuery Omni and an external cloud\nservice. For more information and examples, see the\n[VPC Service Controls](/bigquery/docs/omni-azure-create-external-table#vpc-service)\nconfiguration for when you create an Azure Blob Storage BigLake table.\n\nWhat's next\n-----------\n\n- Learn more about [VPC Service Controls in Analytics\n Hub](/bigquery/docs/analytics-hub-vpc-sc-rules).\n- Learn how to [restrict BigQuery Omni access with an\n external cloud\n service.](/bigquery/docs/omni-azure-create-external-table#vpc-service)\n- Understand [risks and mitigation through\n VPC Service Controls](/security/vpc-service-controls).\n- Learn more about [VPC Service Controls support and\n limitations in BigQuery](/vpc-service-controls/docs/supported-products#table_bigquery).\n- [Troubleshoot](/vpc-service-controls/docs/troubleshooting#debugging) common issues for BigQuery and VPC Service Controls."]]