Franklin Hu

Google Cloud IAM for AWS Users

I spent some time trying to set up a project on Google Cloud Platform a couple weeks ago, and spent the majority of the time trying to make sense of its IAM model, mistakenly assuming that it was the same as AWS’s. In short:

I’m going to walk through some of the major differences between the offerings, and how you can avoid making the same mistakes I did.

Organizations and Projects

Projects are the units of isolation with an Organization. An Organization can have many Projects underneath it.

AWS Organizations seem to be trying to backport a similar hierarchy onto existing accounts, though I haven’t worked with them yet.


Google Cloud ties its types of identity closely with its other Gsuite products.

Google accounts, Google groups, Gsuite domains

GCP allows you to assign roles to each of these granularities. If you use Gsuite for groups, it seems nice to be able to use the same construct for service authorizations. There are also a couple of broader permissions (anyone with a Google account, anyone on the internet) that are available, but unclear how one would use them.

Service accounts

These are for applications (or “services” hence the name). For example, you might have a CI service account that has a different set of access permissions than an AppServer service account. Depending on how you use AWS IAM, these are likely similar to your AWS roles.


These are the individual cloud resources that GCP provides (e.g. storage, pubsub, compute). There isn’t an analogous concept to AWS’s resources names or namespaces (ARNs), which means that you mostly can’t give fine-grain access to a specific resource. There are a some services that have support (e.g. PubSub allows you specify access to a topic name for subscribers, Storage buckets can have specialized policies), but otherwise you’ll have to make due to with Project-level access.


Roles are bundles of permissions that an identity can be associated with, so in some ways you can think of them as AWS’s built in Managed Policies. Currently there’s support for:

  • primitive roles (viewer, editor, owner) that are assigned at the project level and give blanket access, and
  • pre-defined roles that have finer-grain resource type access (roles/storage.objectCreator can create but not delete or override objects)

Notably, you can’t define custom roles, and there are a few places where the permissions a workflow requires don’t match a specific role over time (e.g. Container Registry requires roles/storage.admin the first time pushing a container, but only roles/storage.objectCreator after that), which made the automation I was building a bit more cumbersome than it needed to be.

If you’re clicking around through the web console, you might notice that pre-defined roles are nowhere to be found. In fact, they can only be bound to an identity through the API or CLI client, though they’ll show up in the console afterward. Binding a role to an identity is done through policies, which we’ll get into next.

Policies and Inheritance

Policies specify how roles are bound to identities. Since GCP accounts are organized hierarchically, policies attached to the top level Organization are inherited by each of their Projects, which can layer on more.

In the CLI, these are accessed via:

gcloud projects …
gcloud organizations …

and you can use commands such as add-iam-policy-binding to make these bindings1.

Putting it all together

Overall when comparing with AWS, I was surprised by the lack of individual resource permissioning and the inability to define custom roles. Both of these would increase my confidence that services only have the minimum number of privileges they need (e.g. I want my CI service account to be able to update container deployments, but not reconfigure the cluster or access secrets; both things that roles/container.developer can do). It feel like the limiting blast radius by Project is the recommended path, but I haven’t had a chance to use it yet and it’s unclear whether managing those permissions at the Organization level would be untenable. I’m super curious if any security-conscious enterprises have had success with it.

That said, I can understand why sticking to pre-defined roles might be desirable (how good is the average AWS account’s IAM managed policy hygiene, and how often do resources have an overly permissive set of permissions?). I’m bullish on the outlook; none of these issues are really things that are irreparable, but I’m curious how GCP will approach this as time goes on.

  1. add-iam-policy-binding has really terrible error output, so be sure that you’ve properly structured your member and role names correctly (e.g.