VPC Service Controls: the only real defence against data exfiltration in GCP, and why it is hard
IAM stops the wrong people reading your data. It does not stop the right people copying it somewhere else. Service perimeters do, and they will break things on the way in. Here is how to roll one out without an outage.
Consider the scenario that IAM cannot address. An engineer with legitimate roles/bigquery.dataViewer on your customer dataset runs a query and writes the result to a Cloud Storage bucket in their own personal GCP project. Every API call is authorised. Every log line looks normal. The data is gone.
VPC Service Controls is the control that addresses this, and it is the reason a regulated workload on Google Cloud can make a stronger data-residency claim than the equivalent elsewhere. It is also the control that causes the most self-inflicted outages, so the rollout order matters more than the design.
What a perimeter actually does
A service perimeter is a boundary around a set of projects and a set of Google APIs. Inside it, calls work normally. Crossing it — in either direction — is denied unless an explicit rule allows it.
Three properties matter:
- It applies at the API layer, not the network layer. It stops
bigquery.googleapis.comcalls from outside the perimeter regardless of whether the caller has IAM permission. - It is identity-independent. A stolen service account key used from outside the perimeter is useless, which is a meaningful mitigation for the credential that leaks most.
- It controls egress as well as ingress. Copying data from a protected project to an unprotected one is a perimeter crossing, which is the exfiltration case above.
The rollout that does not cause an outage
1. Draw the perimeter around data, not around everything. The projects holding customer data, the BigQuery datasets, the buckets. Not your CI project, not your monitoring project. A perimeter that contains your whole estate protects nothing from anything and breaks everything.
2. Run in dry-run mode for at least a month. Dry-run perimeters log what would have been denied without denying it. This is not optional. Every estate has an integration nobody documented, and dry run is how you find it before it finds you at 4pm on a Friday.
3. Read the dry-run violations weekly and classify each one. Three buckets: legitimate and needs an ingress or egress rule, legitimate but should be moved inside the perimeter, or exactly the thing you built the perimeter to stop. The third category is rare and it is the justification for the whole project.
4. Write the rules as narrowly as the violations require. Ingress and egress rules can be scoped by identity, by source project, by service and by method. A rule allowing one service account to call one method from one project is a rule you can defend at audit. A rule allowing * from * is a perimeter with a hole in it.
5. Add access levels for humans. Access Context Manager lets you require a corporate IP range, a managed device or a specific identity group for access from outside. This is how your analysts keep working from the office VPN while a leaked credential from anywhere else does not.
6. Enforce, and keep the dry-run perimeter running alongside for the next change.
The things that will break
Learn these before, not during:
- Cloud Build and CI pulling from Artifact Registry inside the perimeter. Needs an egress or ingress rule, or the build project inside.
- Terraform from a laptop or a CI runner outside. You will need an access level, and this is usually the first thing to break.
- Logging sinks writing to a bucket in another project.
- Cloud Console access to BigQuery from a browser outside the access level, which produces a confusing permission error rather than a clear one.
- Any SaaS integration reading from your buckets. Each one needs a documented ingress rule, which is a useful inventory exercise in itself.
Error messages from perimeter denials are famously unhelpful. Set up a saved log query for VPC_SERVICE_CONTROLS violations on day one and share it with the whole team, or you will spend the rollout debugging IAM problems that are not IAM problems.
Is it worth it
For an estate holding regulated personal data, health data or payment data: yes, and it is often the control that makes the compliance conversation short. For a startup with public product data: no, and the operational cost is not justified.
The middle case — an estate with one sensitive dataset among many — is where perimeters do best, precisely because you can draw a small boundary around the thing that matters. That scoping decision is what we spend the first week on in a security engagement.
What to do this week
Create a dry-run perimeter around your single most sensitive project. It denies nothing, it costs nothing, and in a month it will have shown you every system that touches that data — which is a list almost nobody has.