Table of Contents
This post shows you how to fix the dreaded NO_MATCHING_ACCESS_LEVEL error when dealing with VPC Service Control in GCP.
Let’s assume you want to protect a project and its resources by putting it within a VPC SC perimeter. You must also ensure your trusted device(s) can access the protected project resources.
In this case, an access level is created to capture the IP address (or CIDR ranges) that requires access to the protected resources.
Once an access level is created, a VPC SC perimeter is also created with the ingress policy configured to allow any identities from the whitelisted IPs access to the protected project resources.
One easy way to test the VPC SC perimeter is to interact with a GCS bucket from the command line. If the perimeter is configured properly, you should see a list of files. Otherwise, you will get a VPC SC error like below.
> gsutil ls gs://my-shitty-bucket AccessDeniedException: 403 Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier: qQgF9j6AzA413Mfinr2fC5c67-TQoJRuNFKfCzAfXXXXXXXX
When looking up the VPC SC UID for more details, it states there is no matching access level, even though the VPC SC perimeter is configured with an access level containing a matching IP address.
The most likely reason for this error is you have accidentally created a scoped access policy (see the red warning below) without an unscoped access policy at the org level.
To verify this, go to Security > VPC Service Controls > MANAGE POLICIES.
In this example, the “main” access policy is scoped to a project (covered by blue color).
There are 2 ways to fix this.
Option A: Keep Existing Scoped Access Policy, Create Dummy Unscoped Access Policy
If you share this GCP org with other team members and you want to get it working without impacting other GCP resources, the easiest way is to create another access policy that is unscoped (i.e., no project or folder specified) at the org level. This unscoped access policy does not have any VPC SC perimeters configured.
In this example, an unscoped access policy named “default” is created.
Once the changes are propagated, you can execute the same gsutil command successfully.
> gsutil ls gs://my-shitty-bucket gs://my-shitty-bucket/my-shitty-file.jpg
Option B (Preferred): Delete Existing Scoped Access Policy, Create Unscoped Access Policy with VPC SC Perimeter
Unfortunately, an existing scoped access policy cannot be unscoped. So, if you accidentally create a scoped access policy, you can delete it and create an unscoped access policy instead, which requires you to reconfigure the VPC SC perimeter. The upside is you won’t confuse yourself with multiple access policies if you truly don’t need the scoped access policy.
In this example, an unscoped access policy named “default” is created, and it also has the VPC SC perimeter configured with the same settings.
Once the changes are propagated, the same gsutil command will also execute successfully.