VPC SC Perimeters
Just recently, we've been working with a couple of clients on implementing and reworking Google Cloud VPC Service Controls (VPC-SC). If you aren't aware of this service from Google, it is a technology that allows you to surround your resources accessible through Google APIs with a protective perimeter. This is not VMs or apps which are accessible over the Internet but Dataflow pipelines or BigQuery datasets. You can think of it a little bit like an advanced firewall for your Google Cloud resources.
VPC-SC is a great product to add another layer to your security-in-depth strategy but it can be quite complex so I wanted to offer a short article, with the aid of a silly analogy and some terrible drawings, to hopefully give an easy to remember way of thinking about a complicated topic.
Let's start off with briefly describing some components
- Perimeters. There are actually 2 types of perimeters. Regular and bridges. However, for the purpose of this article we'll keep them separate. Perimeters are walls which you can put around your cloud resources to stop things getting to them or them getting out. A bit like a firewall. By default, when created, they don't stop anything.
- Bridges. A project can only be in one perimeter at a time, so if you need projects in different perimeters to communicate, you'll need to create a bridge between them.
- Ingress/egress (directional) policies. Bridges are very simple things and have no fine grained control over what goes back and forth. I/E policies can be applied to individual perimeters and define granular rules of what goes in and what comes out.
- Access Levels. An access level is a lot like a profile of some source location which can be added to a perimeter or an I/E rule. They can contain combinations of types of sources, like service account identities and IP addresses. They can also define device types as a source or even include other access levels to we can group them together.
Our descriptions out of the way, let's get into our silly analogy.
Build a wall
First of all, let's start off by imagining our Google Cloud projects as small villages that offer services to people inside and outside of the village. Let's say we have 2 villages. Village 1 has a compute workshop, which only they can use within the village, and a storage depot which they want to allow external access to. Then, village 2 has a BigQuery workshop and they want to allow select access to it externally.
So, the first thing we're going to do is put up two walls. One around each village...
There we go. Two walls around two villages. We could add a single wall around both villages, whereby all access to services would be available between villages, but two works well for the example.
Now, by default adding a perimeter doesn't restrict any access unless you add any services to its restricted services list. So our wall has lots of open doorways and paths to the village workshops. If you add a service to the list, it effectively closes the door to and from the workshop it represents so that the path in and out of the perimeter wall is blocked.
Above, only the Compute workshop has been restricted by closing the Compute doorway on our wall. For our example, we're going to close all of the doors to prevent malicious outsiders accessing anything inside the village, and bad actors inside sending things out (data loss prevention). In reality you may not want to restrict all services but this is a good place to start.
"But what about Identity and Access Management? Doesn't that provide access control like this?" I don't hear you ask. Well, our standard IAM is like a set of keys to those workshops, each key opening up more access to the shop (user roles through to admin roles). Whereas adding a perimeter is like adding a wall around our village. If someone gets hold of your keys, they can get into your workshop without any issues but if there is also a big wall around the workshop, it's more difficult.
To summarise where we are now. We have:
- 2 villages (Projects)
- 1 wall (Perimeter) around each village, with all doors (Cloud Services) closed and preventing access in or out
Bridge a gap
At this stage, even our two villages can't work with each other any longer; but just like the UK and EU they're great friends (ahem!), so we're going to drop a bridge over the top of the perimeter walls with one end in one village and one end in the other. As pointed out at the start, bridges are simple, so when we do this everyone in each village can cross over it to get to all the shops on the other side.
At this stage we haven't made any other external access changes. We've kind of just extended our internal access. There's still no external access for those objects in our village's storage depot or useful information via the BigQuery data workshop. For this we're going to make use of our fancy new(ish) ingress/egress policies.
Border control
We can think of I/E policies like a VIP list that a nightclub doorman might use to know who's allowed in (and out). By default we don't need our doorman because when we restrict a service, we close and lock the door, so no one comes in or goes out. As we previously stated, our villages do want some wider availability to some services that they offer, so we're going to need to create some rules to give to the doorman on specific doors to help them to know who they can let in and out.