Using VPC Service Controls

VPC Service Controls is a Google Cloud feature that allows you to set up a secure perimeter to guard against data exfiltration. This page shows how to use VPC Service Controls with Cloud Build private pools to add additional security to your builds.

Before you begin

  • To use the command-line examples in this guide, install and configure the Cloud SDK.

  • Set up a private connection between your Virtual Private Cloud network and the VPC network where private pools reside. For instructions, see set up your environment to create private pools.

Setting up a private pool in the VPC Service Controls perimeter

To use VPC Service Controls with Cloud Build, you must first create and configure a service perimeter, which is done at the organization level. This setup ensures that VPC Service Controls checks are enforced when using Cloud Build and that developers can only run builds that comply with VPC Service Controls.

Creating a VPC Service Controls perimeter

Identity and Access Management permissions: To set up a service perimeter, you require the Organization Viewer and Access Context Manager Editor roles. For instructions on granting these roles, see Configuring access for project members.

To create a VPC Service Controls perimeter:

Follow the VPC Service Controls Quickstart to:

  1. Create a service perimeter.
  2. Add the project in which you're planning to create the private pool to the perimeter.

  3. Restrict the Cloud Build API.

After setting up your service perimeter, all calls to the Cloud Build API are checked to ensure that the calls originate from within the same perimeter.

Optional: Enabling perimeter access for development machines

Because VPC Service Controls checks are enforced for the Cloud Build API, calls to the Cloud Build API fail unless they originate from within the service perimeter. Therefore, to manage builds with the Cloud Build API, the Cloud Build UI in the Cloud Console, or the gcloud command-line tool, choose one of the following options:

  • Use a machine inside the VPC Service Controls perimeter. For example, you can use a Compute Engine VM or an on-premises machine connected to your VPC network via VPN.

  • Grant developers access to the perimeter. For example, you can create access levels that enable perimeter access based on IP address or user identity. For more information, see Allowing access to protected resources from outside a perimeter.

Optional: Setting up organization policy constraints

You can restrict builds in a Google Cloud organization to only use the specified private pools by setting the constraints/cloudbuild.allowedWorkerPools organization policy constraint. You can apply the organization policy to the entire organization, or to a project or a folder in the organization. For example, your organization policy can specify that:

  • All builds in the organization use the specified private pools.
  • All builds in a folder use the specified private pools.
  • All builds in a project use the specified private pools.

IAM permissions: To manage organization policies, you need the Organization Policy Administrator (roles/orgpolicy.policyAdmin) role. For instructions on granting a role, see Configuring access for project members.

The gcloud resource-manager org-policies allow command sets an organization policy that requires the builds in the organization to only use the specified private pool:

 gcloud resource-manager org-policies allow \
     cloudbuild.allowedWorkerPools \
     projects/WORKERPOOL_PROJECT_ID/locations/LOCATION/workerPools/WORKERPOOL_ID \
     --organization ORGANIZATION_ID

Replace the placeholder values in the above commands with the following:

  • WORKERPOOL_ID: is the ID of the private pool to run builds.

  • WORKERPOOL_PROJECT_ID: the ID of the Cloud project that contains the private pool.

  • LOCATION: the region that contains the private pool.

  • ORGANIZATION_ID: the ID of the Organization where you're running builds.

The command supports under: and is prefixes.

To set organization policy that requires all builds in the organization to use any private pool under that organization:

 gcloud resource-manager org-policies allow \
     cloudbuild.allowedWorkerPools under:organizations/ORGANIZATION_ID \
     --organization ORGANIZATION_ID

Where, ORGANIZATION_ID is the ID of the organization that contains the private pools.

To set an organization policy that requires all builds in the projects under a folder to use any private pool in the specified project:

 gcloud resource-manager org-policies allow \
     cloudbuild.allowedWorkerPools under:projects/PROJECT_ID \
     --folder FOLDER_ID

Where PROJECT_ID is the ID of the project that contains the private pools and FOLDER_ID contains the projects where you're running the builds.

To set an organization policy that requires all builds in a project to use any private pool in the specified project:

 gcloud resource-manager org-policies allow \
     cloudbuild.allowedWorkerPools under:projects/WORKERPOOL_PROJECT_ID \
     --project BUILD_PROJECT_ID

Where WORKERPOOL_PROJECT_ID is the ID of the project that contains the private pools and BUILD_PROJECT_ID is the ID of the project where you're running the builds.

Keep the following considerations in mind when enforcing the constraints/cloudbuild.allowedWorkerPools organization policy constraint:

  • If you apply this organization policy constraint to a Cloud project, ensure that all builds in the project use the private pool; builds attempting to use the default shared pool will fail.

  • If your Google Cloud organization contains services such as App Engine or Cloud Functions that implicitly use Cloud Build, enforcing this the organization policy constraint may cause these services to not work as expected.

Granting the Cloud Build service account access to the VPC Service Controls perimeter

Cloud Build uses the Cloud Build service account to execute builds on your behalf. By default, the Cloud Build service account remains outside the VPC Service Controls perimeter, even if the Cloud project where it is contained is inside the perimeter. Because of this, for your builds to access resources within the perimeter, you must grant the Cloud Build service account access to the VPC Service Controls perimeter. If you want to avoid this step, use user-specified service accounts instead of the Cloud Build service account. A user-specified service account is inside the VPC Service Controls perimeter if the corresponding Cloud project is inside the perimeter.

To grant the Cloud Build service account access to the VPC Service Controls perimeter:

  1. Get the email address of your Cloud Build service account:

    1. Open the IAM page:

      Open the IAM page

    2. Select the project that you added to the service perimeter.

    3. In the permissions table, locate the email address ending with @cloudbuild.gserviceaccount.com and note it down. This is your Cloud Build service account.

  2. Create an access level for your Cloud Build service account by following the instructions at Limit access by user or service account.

  3. Add the access level to your service perimeter by following the instructions at Adding an access level to an existing perimeter.

Creating a private pool in the service perimeter

Console

  1. Open the Worker Pool page in the Google Cloud Console:

    Open the Cloud Build worker pool page

  2. Select the project where you want to create the private pool.

  3. In the Worker pool page, click Create.

  4. In the Create private pool side panel:

    1. Enter a name for your private pool.

    2. Select the region in which you want the private pool to be created.

    3. Select the Compute Engine machine type you want to use for your private pool.

    4. Enter the project number of the Cloud project where you created your VPC network.

    5. Enter the name of your VPC network.

    6. Uncheck Assign external IPs.

    7. Click Create.

gcloud

  1. Create a worker pool config file in the YAML or the JSON format, and set the egressOption flag to NO_PUBLIC_EGRESS:

    privatePoolV1Config:
      networkConfig:
        egressOption: NO_PUBLIC_EGRESS
        peeredNetwork: PEERED_NETWORK
    workerConfig:
      diskSizeGb: 'WORKER_POOL_DISK_SIZE'
      machineType: WORKER_POOL_MACHINE_TYPE
    

    Where:

    • PEERED_NETWORK is the network resource URL of the network that is peered to the service provider network. PEERED_NETWORK must be of the format projects/NETWORK_PROJECT_ID/global/networks/NETWORK_NAME, where NETWORK_PROJECT_ID is the project ID of the Cloud project that holds your VPC network and NETWORK_NAME is the name of your VPC network.
    • WORKER_POOL_MACHINE_TYPE is the Compute Engine machine type for private pool instance. For supported machine types, see Worker pool config file schema.
    • WORKER_POOL_DISK_SIZE is disk size for private pool instance in GB. Specify a value greater than or equal to 100 and less than or equal to 1000. If you specify 0, Cloud Build uses the default value of 100.
    • egressOption is the flag to enable VPC Service Controls perimeter for your private pool. Set this to NO_PUBLIC_EGRESS to create your private pool within the VPC Service Controls perimeter.
  2. Run the following gcloud command, where WORKERPOOL_ID is a unique identifier for your private pool, WORKERPOOL_CONFIG_FILE is the name of your worker pool config file, and REGION is the region where you want to create your worker pool:

    gcloud builds worker-pools create WORKERPOOL_ID --config-from-file WORKERPOOL_CONFIG_FILE --region REGION
    

Optional: Enabling public internet calls on the VPC network

Make sure your VPC network is configured to allow network connectivity to where your repository is hosted (e.g. github.com) with the following settings:

  1. In your worker pool config file, make sure that the egressOption field is set to NO_PUBLIC_EGRESS.

  2. The VPC network that your private pool runs on is defined as a PeeredNetwork. To allow calls to your repository host, ensure that this VPC network allows public egress to your repository host. For information on doing this, see routes and firewall rules.

Running builds in a private pool within the service perimeter

Builds run within the service perimeter don't have access to the public internet, because of which you'll need to perform a few actions before running a build.

Pushing built images and artifacts

If your builds push images and artifacts to Container Registry, Artifact Registry, or Cloud Storage that are in a different Cloud project, make sure to add that project to the same service perimeter as the project from which your builds originate.

Creating a logs bucket

Build run within the service perimeter will not have permissions to store build logs in the default Cloud Storage logs bucket. Choose one of the following options:

Running builds

Run your build using the instructions at Running builds in a private pool.

What's next