Securing serverless infrastructure requires a paradigm shift. Because serverless environments like Cloud Run, Cloud Functions, and App Engine inherently run outside of your traditional virtual network perimeters, controlling exfiltration and unauthorised ingress to the data they process is highly challenging. Google Cloud VPC Service Controls (VPC SC) solves this by placing a logical, identity-based security perimeter around Google Cloud platform APIs, independent of the underlying network architecture.
This article details how to architect and enforce a VPC Service Controls perimeter that successfully encapsulates Google Cloud Serverless environments, ensuring that your serverless compute cannot access or exfiltrate data to resources outside your trusted boundary.
The Architecture of VPC Service Controls
VPC Service Controls do not manage IP routing or firewall rules. Instead, they act at the IAM (Identity and Access Management) API layer. When a VPC SC perimeter is defined, Google Cloud intercepts every API call made to the protected services (such as Cloud Storage, BigQuery, or Cloud Run Admin APIs).
If a Cloud Run service inside the perimeter attempts to read a BigQuery dataset outside the perimeter, the request is blocked, even if the service account has the correct IAM permissions. Conversely, external identities attempting to invoke your serverless functions will be blocked unless explicitly allowed by an Ingress Rule.
Step 1: Planning the Security Perimeter
Before implementing VPC SC, you must define the scope of your perimeter. VPC SC is configured at the Google Cloud Organization level, not the Project level.
Ensure you have the Access Context Manager Admin role at the Organization level.
Determine which projects will be inside the perimeter. For this guide, we will place a project containing a Cloud Run service and a Cloud Storage bucket inside a single perimeter. The goal is to ensure the Cloud Run service can access the bucket, but neither can be accessed from the public internet without explicit context-aware conditions.
Step 2: Creating an Access Level (Optional but Recommended)
If you want administrators to deploy code or manage the serverless environment from outside the perimeter (e.g., from a corporate office network), you must define an Access Level in Access Context Manager.
- In the Google Cloud Console, navigate to Security > Access Context Manager.
- Click Create Access Level.
- Name it Corporate_Network.
- Under Conditions, specify the public IP CIDR ranges of your corporate VPN or office.
- Save the Access Level.
This Access Level will later be used in the Ingress Rules of your perimeter to allow administrative API calls.
Step 3: Creating the VPC Service Controls Perimeter
Now, we define the actual perimeter that will encapsulate your serverless project.
- Navigate to Security > VPC Service Controls.
- Ensure you are viewing the Organization scope in the top resource selector.
- Click New Perimeter.
- Name the perimeter Serverless_Secure_Perimeter.
- Perimeter Type: Select Regular perimeter.
- Projects: Add the Google Cloud Project containing your Cloud Run service and Storage buckets.
- Restricted Services: This is the most critical step. Select the APIs you wish to protect. For a serverless environment, you must protect Cloud Run API, Cloud Functions API, and data services like Cloud Storage API and BigQuery API.
Step 4: Configuring Serverless VPC Access
If your Cloud Run or Cloud Functions need to communicate with resources inside a traditional VPC (like a private Cloud SQL instance) while both are inside the VPC SC perimeter, you must configure a Serverless VPC Access Connector. Furthermore, you must ensure that the VPC network itself is included in the perimeter.
When the serverless service routes traffic through the connector, the traffic originates from the internal IP space of the VPC. Because the VPC is inside the perimeter, API calls to Cloud Storage or BigQuery made via Private Google Access will be recognized as internal to the perimeter and allowed.
Step 5: Configuring Ingress Rules for Serverless Invocations
By default, once you add the Cloud Run API to the restricted services list, all external invocations (HTTP requests from the internet) to your Cloud Run service will be blocked with a 403 Forbidden (VPC Service Controls) error. To allow end-users to access the serverless application while protecting the administrative APIs, you must define Ingress Rules.
- In your perimeter configuration, go to the Ingress Policy section.
- Click Add Rule.
- From:
- Identities: Select All Users (if the app is public) or specific Service Accounts.
- Source: Any (or restrict to your Access Level for internal apps).
- To:
- Projects: Select your serverless project.
- Services: Select Cloud Run API.
- Methods: Specify
run.routes.invoketo allow HTTP invocations, while leaving administrative methods (likerun.services.create) blocked.
Step 6: Dry Run and Enforcement Mode
Never deploy a VPC SC perimeter in Enforcement Mode initially. Always use Dry Run mode. Dry Run logs violations without actually blocking the traffic, allowing you to identify missing Ingress Rules or legitimate cross-project traffic.
- Save the perimeter in Dry Run mode.
- Allow your applications to run normally for several days.
- Navigate to Logs Explorer and query for VPC SC violations using:
logName="projects/YOUR_PROJECT_ID/logs/cloudaudit.googleapis.com%2Fpolicy_violation" - Analyze the logs. If you find legitimate traffic being flagged, create the necessary Ingress or Egress rules.
- Once the logs are clean, edit the perimeter and switch it from Dry Run to Enforced mode.
Conclusion
VPC Service Controls provide a formidable defence-in-depth layer for Google Cloud serverless environments. By strategically defining perimeters, restricting APIs, and carefully crafting Ingress policies for invocations, you can entirely mitigate the risk of data exfiltration and unauthorized administrative access, regardless of the underlying network topology.