I have a GCP organisation of a handful of projects laid out in folders. I also have a handful of humans that need access of various types to the estate.

My first class of humans are those which need full read-only access to just about all of GCP.

My second class of users need read-only access to one or more folders of projects. However, I'd like to deny them access to anything in Secrets Manager or Billing.

My first thought was to create the first class of users at the top level, and the second class at the folder level, with a deny rule at the project level. However, since they all use roles/viewer, that doesn't work.

I could also solve this by denying each user in the second class, but not the first. Since I'm permissioning everyone with Terraform, I could just deny the second class of users. This could work, but it means something special for each user - not a terrible problem, but seems wrong.

The last method I've looked at is to create a custom role. The first class of users just use roles/viewer as they do now, but the second class use roles/restricted-viewers or whatever. My problem with that is that I'd need to somehow keep up with permissions in the viewer role and apply them to my custom role.

Are there any other (better?) ways to do this? Can we guess at how Google intended us to handle situations such as this?

1 Answer 1


After some battling, I've found that ultimately this isn't possible to achieve (at least, not with a Deny policy).

The good news is you can attach a deny policy to a project, folder or organisation (See: https://cloud.google.com/iam/docs/deny-access#attachment-point).

The bad news is you cannot deny access to billing - it's not a supported permission (see: https://cloud.google.com/iam/docs/deny-permissions-support). If your use case is covered by supported permissions then it actually all works quite well though.

For anyone stumbling across this, the Terraform to try this out looks something like this:

terraform {
  required_providers {
    google = {
      version = "~> 4.53.1"

provider "google" {
  project = "myProject"
  region  = "europe-west1"

resource "google_iam_deny_policy" "deny" {
  provider     = google-beta
  parent       = urlencode("cloudresourcemanager.googleapis.com/folders/1234567890")
  name         = "my-deny-rule"
  display_name = "Deny Rule for trying it out"
  rules {
    description = "Deny Access to confidential resources"
    deny_rule {
      denied_principals  = ["principal://goog/subject/[email protected]"]
      denied_permissions = ["dns.googleapis.com/managedZones.list"]

Something that tripped me up were the permissions required to apply this. I thought I was an admin of everything, but still had to add the required permissions (see: https://cloud.google.com/iam/docs/troubleshooting-deny#before-you-begin).

In terms of solving the original problem (ie. broad viewer access, except some specific areas), I'm none the wiser. I think my best bet is just permission the restricted users with a series of role/<something>.viewer roles that allow them to view the things they need and nothing more. Figuring out what they need is going to take some time, and it's bound to be wrong at some point in the future, but at least they won't be able to see things they shouldn't.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.