Darkbit has joined Aqua Security!


GCP Predefined IAM Role Permission Tracker

06 August 2020

During one of our Google Cloud Platform (GCP) security assessments, we noticed that one of the Predefined IAM Roles had more permissions than before. After a bit, we noticed the GCP IAM Permissions Change Log explained which permissions were added. So, we decided to automatically track those changes, and the results have been enlightening.

Primitive and Predefined Roles

The primitive roles in GCP are viewer, editor, and owner, and they represent the most coarse way to assign permissions to identities inside GCP. In nearly all use cases, their use immediately violates the principle of least privilege as they include permissions across all GCP services to “read all the things”, “edit all the things”, and “full control”, respectively. If you wanted to grant the ability to view logs in a GCP project, you could assign viewer and it would work. But, it would grant thousands more permissions than needed to view logs. For example, it would grant read access to GCS buckets, GCR images, and much more. Instead, consider assigning the predefined role named roles/logging.viewer.

Predefined roles are another form of built-in IAM Roles that are more granular in nature, and they should be the starting point for access control in most use cases. There are some predefined roles like roles/browser that don’t seem to change much as their permissions for reading the organization, folder, and project hierarchy are foundational. But what about predefined roles that correspond to a job function like roles/iam.securityReviewer that touches many services? As it turns, out, these can and do change – sometimes multiple times in a single day.

The Release Notes Lie?

If you review the GCP IAM Permissions Change Log closely, you can see that changes are posted for a given week. But what happens during the week is actually quite a bit more than that. In order to capture this, we set out to write some simple automation. Like many things, it started with quick shell script in a local repo. A few days later, it captured the first change that wasn’t yet public on the change log, and that’s when we knew this could be useful to run autonomously.

GCP IAM Role Permissions Github Project

What started as a simple script is now a Github Project leveraging Github Actions to automatically enumerate the currently available primitive and predefined roles and permissions into the repository on a twice-daily basis. If any changes are detected, it tags and creates a date/time named release.

We Caught One!

One of the early “catches” was the removal of container.secrets.list from the roles/iam.securityReviewer predefined role.


Why is this particular permission removal so interesting? A few reasons:

Being able to list secrets inside all GKE clusters via IAM means that role allows that identity to read all of the Kubernetes Service Account Tokens that are stored as native Kubernetes secrets. In nearly all clusters in practical use, one or more Kubernetes Service Accounts are bound to privileges that can afford the attacker-desired capabilties of cluster-admin. With access to the Bearer token associated with those Kubernetes Service Accounts, the roles/iam.securityReviewer is actually cluster-admin inside all GKE clusters in scope. Thankfully, this specific privilege escalation path is no longer possible.

Get Notified

GCP administrators should understand that the primitive and predefined IAM roles in GCP can actually change at any time, and these changes may not appear on the GCP IAM Permissions Change Log right away, if at all. To be notified of each GCP IAM Role and permission change automatically, consider subscribing to the GCP IAM Role Permissions Release Page. The changes may surprise you!