GCP: Managing IAM Access Control Across Projects -- The Simpler Version

Posted on Mon 25 February 2019 in gcp

GCP resources are organized into projects -- all resource IDs and IAM principles are grouped under a project ID. This means that by default roles assigned to a principle (e.g. a user or service account) are scoped only to project resources. This can be tricky if say your images are in one project's storage bucket and your app is running in another

If you want to provide a service principle in one project access to resources in another , the approach is not obvious, nor is it well documented.

Below we'll talk about the most direct way, which works for projects that are not part of an organization. This is good for projects managed by different teams or GCP projects that are part of a personal account (without gsuite)

Use Case -- Allow an Outside App Engine App Access Build Status

For this example, the app engine app running in ${SOURCE_PROJECT_ID} needs to access build status in ${GOOGLE_CLOUD_PROJECT}.

This can easily be done using the cloud shell activated for the project id = ${GOOGLE_CLOUD_PROJECT}

Grant a Role to An Outside Service Principle

gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member=serviceAccount:${SOURCE_PROJECT_ID}@appspot.gserviceaccount.com \
--role=roles/cloudbuild.builds.viewer \

How Does This Work?

GCP Access control for projects is an ACL mapping members -> roles. The above command refers directly to the app engine service account (PROJECT_ID@appspot.gserviceaccount.com) in the outside account, and attaches the cloudbuild.builds.viewer role

e.g. You can view the entire project-level ACL this way

gcloud projects get-iam-policy `${GOOGLE_CLOUD_PROJECT}`
- members:
  - serviceAccount:XXXXX@cloudbuild.gserviceaccount.com
  - serviceAccount:local-dev@XXXXXX.iam.gserviceaccount.com
  role: roles/appengine.appAdmin
- members:
  - serviceAccount:XXXXXX@cloudbuild.gserviceaccount.com

Won't this Get Messy?

Any sane person can see that this doesn't scale well. It can work if the deps are often one way, but once you get two-way dependences it would be a disaster. At that point look into creating an organization and manaing the ACL at the organization level

How is this Better or Worse Than AWS IAM?

There are pros and cons to project-based resourcing. On the plus side, a project works like a c++ namespace so all resources are implicitly granted to principles in the same project. AWS policies contain an explicit resource pattern match, which makes every grant more complex.

Security is also improved by default since deny is the default among projects.

How About Larger Projects?

tl;dr, don't put all of your resources in one project, and when your projects start having two-way deps, think about moving those into a star pattern and using a GCP organization for the ACL