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 guide shows how to use VPC Service Controls with Cloud Functions to add additional security to your functions.

For known limitations with this integration, see the VPC Service Controls documentation.

Organization-level setup

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

Set up a VPC Service Controls perimeter

To set up a service perimeter, you need the Organization Viewer (roles/resourcemanager.organizationViewer) and Access Context Manager Editor (roles/accesscontextmanager.policyEditor) roles.

Follow the VPC Service Controls Quickstart to:

  1. Create a service perimeter.
  2. Add one or more projects to the perimeter.
  3. Restrict the Cloud Functions API.

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

Optional: Whitelist development machines

Because VPC Service Controls checks are enforced for the Cloud Functions API, calls to the Cloud Functions API fail unless they originate from within the service perimeter. Thus, to manage functions with the Cloud Functions API, the Cloud Functions 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 function developers access to the perimeter. For example, you can create access levels that enable perimeter access based on IP address or user identity. See Allowing access to protected resources from outside a perimeter for more information.

Set up organization policies

To manage organization policies, you need the Organization Policy Administrator (roles/orgpolicy.policyAdmin) role.

To comply with VPC Service Controls and protect against data exfiltration, set up the following organization policies that control the allowable network settings for Cloud Functions in the service perimeter.

Restrict allowed ingress settings

The cloudfunctions.allowedIngressSettings organization policy controls the ingress settings that developers are allowed to use for Cloud Functions. Set this organization policy to mandate that developers use the value ALLOW_INTERNAL_ONLY:

Console

  1. Go to the Allowed ingress settings policy page in the Cloud Console:

    Go to organization policy

  2. Click Edit.

  3. On the Edit page, select Customize.

  4. Under Policy enforcement, select Replace.

  5. Under Policy values, select Custom.

  6. Under Policy type, select Allow.

  7. Under Custom values, enter ALLOW_INTERNAL_ONLY.

  8. Click Save.

gcloud

Use the gcloud beta resource-manager org-policies allow command:

gcloud beta resource-manager org-policies allow \
  cloudfunctions.allowedIngressSettings ALLOW_INTERNAL_ONLY \
  --organization ORGANIZATION_ID

where ORGANIZATION_ID is your organization ID.

After this organization policy is in place, all functions must use the value ALLOW_INTERNAL_ONLY for their ingress settings. This means that HTTP functions can only accept traffic originating from a VPC network within the service perimeter. Function deployments specifying a different value will fail.

Require VPC connector

The cloudfunctions.requireVPCConnector organization policy controls whether a Serverless VPC Access connector is required for functions. Set this organization policy to enforce this constraint:

Console

  1. Go to the Require VPC Connector policy page in the Cloud Console:

    Go to organization policy

  2. Click Edit.

  3. On the Edit page, select Customize.

  4. Under Enforcement, select On.

  5. Click Save.

gcloud

Use the gcloud beta resource-manager org-policies enable-enforce command:

gcloud beta resource-manager org-policies enable-enforce \
  cloudfunctions.requireVPCConnector \
  --organization ORGANIZATION_ID

where ORGANIZATION_ID is your organization ID.

After this organization policy is in place, all functions must use a Serverless VPC Access connector. Function deployments that do not specify a connector will fail.

Restrict allowed VPC Connector egress settings

The cloudfunctions.allowedVpcConnectorEgressSettings organization policy controls the egress settings that developers are allowed to use for Cloud Functions. Set this organization policy to allow only the value ALL_TRAFFIC:

Console

  1. Go to the Allowed VPC Connector egress settings policy page in the Cloud Console:

    Go to organization policy

  2. Click Edit.

  3. On the Edit page, select Customize.

  4. Under Policy enforcement, select Replace.

  5. Under Policy values, select Custom.

  6. Under Policy type, select Allow.

  7. Under Custom values, enter ALL_TRAFFIC.

  8. Click Save.

gcloud

Use the gcloud beta resource-manager org-policies allow command:

gcloud beta resource-manager org-policies allow \
  cloudfunctions.allowedVpcConnectorEgressSettings ALL_TRAFFIC \
  --organization ORGANIZATION_ID

where ORGANIZATION_ID is your organization ID.

After this organization policy is in place, all functions must use the value ALL_TRAFFIC for their egress settings. This means that functions must route all egress traffic through your VPC network. Function deployments specifying a different value will fail.

Project-level setup

For individual projects within the service perimeter, you must perform additional configuration to use VPC Service Controls.

Configure VPC networks

To access Google APIs and services while mitigating data exfiltration risks, requests should be sent to the restricted virtual IP (VIP) range, 199.36.153.4/30 (restricted.googleapis.com).

For each VPC network in a project, follow these steps to block outbound traffic except for traffic to the restricted VIP range:

  1. Configure firewall rules to prevent data from leaving the VPC network:

    • Create a deny egress rule that blocks all outbound traffic.

    • Create an allow egress rule that permits traffic to 199.36.153.4/30 on TCP port 443. Ensure that it has a priority before the deny egress rule you just created—this allows egress only to the restricted VIP range.

  2. Configure DNS to resolve *.googleapis.com to restricted.googleapis.com.

  3. Configure DNS with an A record mapping cloudfunctions.net to the 199.36.153.4/30 IP range. You can do this with Cloud DNS:

    gcloud dns managed-zones create ZONE_NAME \
    --visibility=private \
    --networks=https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default \
    --description=none \
    --dns-name=cloudfunctions.net
    
    gcloud dns record-sets transaction start --zone=ZONE_NAME
    
    gcloud dns record-sets transaction add --name=*.cloudfunctions.net. \
    --type=A 199.36.153.4 199.36.153.5 199.36.153.6 199.36.153.7 \
    --zone=ZONE_NAME \
    --ttl=300
    
    gcloud dns record-sets transaction execute --zone=ZONE_NAME
    

At this point, requests originating from within the VPC network:

  • are not able to leave the VPC network, preventing egress outside the service perimeter.
  • can only reach Google APIs and services that check VPC Service Controls, preventing exfiltration through Google APIs.

Grant the Cloud Build Service Account access to the VPC Service Controls perimeter

Cloud Functions uses Cloud Build to build your source code into a runnable container. In order to use Cloud Functions with VPC Service Controls, you must configure an access level for the Cloud Build Service Account in your service perimeter:

  1. Find the service account's address. Use the following workaround:

    1. Deploy a function in your project. Use the default in the Google Cloud Console:

      Create function

    2. Wait for the deployment to fail, then click the function name in the list to go to its Function details page.

    3. See the "Deployment failure" error message—it starts with Build failed: Unable to build your function due to VPC Service Controls. The error message contains the service account's email address.

    You can also use a script like the following to find the service account's address from the command line:

    #!/bin/bash
    
    REGION="us-central1" # Your region
    CONNECTOR_NAME="test-connector" # Your VPC connector name
    
    # Deploy and delete an HTTP-triggered function
    gcloud functions deploy FUNCTION_NAME --trigger-http --runtime nodejs8 --region $REGION --ingress-settings=internal-only --egress-settings=all --vpc-connector $CONNECTOR_NAME -q
    gcloud functions delete FUNCTION_NAME --region $REGION -q
    
    # Search log entries for Cloud Build failures
    LOG_ENTRIES=$(gcloud logging read "resource.type=\"audited_resource\" AND protoPayload.serviceName=\"containerregistry.googleapis.com\"" --freshness=10m)
    SERVICE_ACCTS=$(echo "$LOG_ENTRIES" | grep -oE "\d+@\w+.gserviceaccount.com" | sort | uniq)
    
    # Print out service account IDs
    echo "$SERVICE_ACCTS"
    

    Using a script like the one above, FUNCTION_NAME can be any HTTP function, such as a simple Hello World function.

  2. Grant the service account access to the service perimeter. Follow the guide at Limit access by user or service account to create an access level and follow Adding an access level to an existing perimeter to add the access level to your service perimeter.

After granting the Cloud Build Service Account access to the VPC Service Controls service perimeter, function deployments will succeed.

Deploy functions compliant with VPC Service Controls

After VPC Service Controls is configured for Cloud Functions, you must ensure that all functions deployed within the service perimeter comply with the specified organization policies. This means that:

  • All functions must use a Serverless VPC Access connector. See Connecting to a VPC network for more information.
  • All functions must allow only traffic from internal sources. See Ingress settings for more information.
  • All functions must route all outgoing traffic through the VPC network. See Egress settings for more information.

Function deployments that do not meet the above criteria will fail.

Audit existing functions to ensure VPC Service Controls compliance

After setting up VPC Service Controls, new functions created in projects within the service perimeter are automatically checked for compliance. However, to avoid disruption of existing workloads, existing functions continue to work and might not comply with organization policies.

We recommend that you audit existing functions and update or redeploy functions as necessary. To facilitate this process, you might create a script that uses the Cloud Functions API to list your functions and highlight those that do not specify the proper network settings.