Using IAM Conditions in Google Cloud

Larry Nguyen
4 min readOct 29, 2022

It has been a while I have not written any article. So many new things happened in the last few months. Google Cloud Platform (GCP) now is called Google Cloud (GC). Today, we will take a look at IAM Conditions to see how we could ultilize that to futher control the access of an IAM Role.

In a nutshell, the IAM Conditions are a set of rules that do the matching on the attributes on the API Request and the Resource. On the Request side, except the Timestamp, all other attributes are meant for IAP. Timestamp is useful to control the access based on time. For example, we want to limit the access to the Bucket only outside batch processing period. Resource is to match with the destination resource (**Note: not all resource types are supported, check the official documentation for the list of supported types)

If the rule fails, ALL the permissions in the role are denied. This behavior is a bit inconvenient. For example, if we just want to control the Cloud Storage permissions, we may accidentally control all other permissions included in the role. GC has come up with a better approach for this requirement called Deny Policy that would control at the Folder and Organization level. We will take a look at that in another article.

Let’s use the predefined role Cloud Dataflow Service Agent as our example. This is a very popular service account role that has lot of permissions to PubSub and Cloud Storage. By default this role will allow access to all the Buckets and Topics.

We will try to create the IAM Condition so that the role can only access the bucket non_private_bucket_01 following the tutorial on Google Documentation as below

First we need to add the Role and add the IAM Condition.

We could either use the Editor or Builder.

Let’s do some tests.

$gsutil ls gs://non_private_bucket_01
gs://non_private_bucket_01/public_data/
$gsutil ls gs://sensitive_bucket_01
AccessDeniedException: 403 dataflow@littlewind-01.iam.gserviceaccount.com does not have storage.objects.list access to the Google Cloud Storage bucket.

It works as expected. However, when I tried to upload a file to non_private_bucket_01, I hit AccessDeniedException error.

$gsutil cp file.txt gs://non_private_bucket_01/public_dataAccessDeniedException: 403 dataflow@littlewind-01.iam.gserviceaccount.com does not have storage.objects.create access to the Google Cloud Storage object.

Why is that? Checking the Policy Troubleshooter does not help either. That tool is not useful at all for IAM Condition (or maybe I don’t know how to use it properly)

If we look at the official example, it is using resource.type. For Cloud Storage, there are 2 different types Bucket and Object. So if we only check for Bucket, all the access to the Object such as storage.objects.get for download or storage.objects.create for upload will be denied.

We can fix this by using resource.service instead. Actually, for this scenario the condition with just the resource.name is more than enough.

Now we have a problem. The condition works well for the Buckets, but it also block access to PubSub Topics.

$gcloud pubsub topics publish projects/medium/topics/TestTopic
--message="Test"
ERROR: (gcloud.pubsub.topics.publish) PERMISSION_DENIED: User not authorized to perform this action.

Can we just add the Topic to the condition? Unfortunately, the IAM Conditions only available for certain resource types. PubSubLite is part of those but PubSub is not. I do not know exactly the reason behind this constraint. For PubSub, we do directly at the Topics that we allow access by going to the Topic itself → show the Info Panel and Add Principle in the Permissions tab.

In summary, I find the IAM Condition is a very good way to fine-tune the access control. I hope Google will add more features into it in the future. Below are some of them:

  • Support more resource types
  • More attributes on both Request and Resource such as allowing to control the size of the object/file to be uploaded
  • Make the condition a resource itself, so it could be re-used easily or automatically added using some policy (e.g. Org Policy)

--

--