Implementing IAM Deny policies to improve your organizational security posture

aka “Adding Another Layer to your Organization’s Defense in Depth Strategy” is a lightning talk I gave at Google Next ’24 in Las Vegas. This post explores IAM Deny policies, expanding on my talk and including code samples for security practitioners.

Glen Yu
Google Developer Experts

--

Introduction

What comes to mind when you hear Principle of Least Privilege? If you are unfamiliar with PoLP, it is the practice of assigning only the permissions necessary to perform a job or a task. This very intuitive best practice works wonderfully, but has one flaw: denial is implicit. Users are denied access based on the permissions they do not have. But what if they obtained those permissions (whether accidentally or by nefarious means)?

IAM Deny policies aims to cover this flaw in IAM Allow policies by introducing explicit denial.

Requirements

IAM Deny policies are an organizational feature, meaning this is not available for personal accounts — you need an Google Cloud organization! Additionally, in order to view, create, update, or delete IAM Deny policies, you need to be assigned the Deny Admin (roles/iam.denyAdmin) at the organizational level.

How it works

The evaluation process is very straight forward:

  1. Evaluate IAM Deny policies (if any exist) — deny any explicitly denied principal(s)
  2. Evaluate IAM Allow policies if no IAM Deny policies resulted in permission denial
Source: Google Cloud blog

The beauty of IAM Deny policies is that it takes precedence over IAM Allow policies. A single matching deny rule will throw up an access roadblock. This means that you will get denied access regardless of the role(s) you have.

IAM Deny policies extend across organization, folder, and project hierarchies, solidifying your security posture at scale!

Anatomy of an IAM Deny policy

I used the image of a deconstructed burger to help illustrate the components of an IAM Deny policy, because much like a burger there are required and optional components.

Image of burger generated via Gemini
  • deniedPrincipals (required): specifies the user(s) and/or group(s) the IAM Deny policy applies to
  • deniedPermissions (required): the permissions while deniedPrincipals are not allowed to have
  • exceptionPrincipals (optional): user(s) and/or group(s) that are excluded from the IAM Deny policy
  • denialCondition (optional): specific conditions under which the IAM Deny policy takes affect. Can only use organization tags for conditional matching (unlike IAM Allow policy conditionals)

NOTE: You may also have noticed the way users, service accounts, groups, etc. are referenced seem a little different from what you are probably more accustomed to seeing — and you would be right! This is because IAM Deny policy rules use the IAM v2 API when referring to users. Single users/accounts are known as a principal, while groups of users are a principalSet.

Use cases

Ready to see IAM Deny policies in action? I will explore common use cases and provide concrete examples.

Centralizing administrate privileges

The following policy example is typically applied at the organization level and denies all users except for members of the project admins group from creating or deleting projects:

Prevent data exfiltration

By preventing access to databases or storage, you can limit access to sensitive data. The following policy restricts access to Google Cloud Storage buckets and objects to everyone but me:

Restricting contractor access to lower environments

If your organization uses contractors or consultants (like myself), you may want to restrict their access to only non-production environments. You can also safeguard sensitive data (like PII or PHI) and prevent accidental modifications in production.

The following policy contains two rules and utilizes two different organizational tags. One which denies access on resources that are not (notice the ! in !resource.matchTag) tagged for contractor staff. The second denies access to resources where the environment is prod:

Tips

  • Consider implementing organizational tags if you not yet already. Not only is it a effective way of filtering out resources (especially for billing/cost analysis purposes), but is used by IAM Deny policies for policy conditions
  • Use infrastructure as code tools such as HashiCorp’s Terraform to manage policies. Allows for easier updating of existing policies (updating IAM policies using gcloud is a multi-step process involving obtaining the etag first — an intermediate step which Terraform abstracts away from the user). Below is an example of an IAM Deny policy written in Terraform:
  • Only some resources and permissions are supported (e.g. at time of writing AlloyDB is not supported), so please consult the permissions supported by deny policies page to get the updated list
  • Be organized; logically group your policies (I recommend by environment and/or resource type)

Conclusion

Strengthen your security baseline by implementing IAM Deny policies at the organization, folder, and project levels. IAM Deny policies can help simplify and centralize administrative privileges. It can provide guardrails against excessive permissions and backdoors. If you have a Google Cloud organization, you should absolutely consider implementing IAM Deny policies. Your security team will sleep more soundly at night.

--

--

Glen Yu
Google Developer Experts

Cloud Engineering @ PwC Canada. I'm a Google Cloud GDE, HashiCorp Ambassador and HashiCorp Core Contributor (Nomad). Also an ML/AI enthusiast!