Home

Published

- 8 min read

GCP Defense-in-Depth: IAM Deny & Org Policies

img of GCP Defense-in-Depth: IAM Deny & Org Policies

Why allowing permissions is only half the battle, and how learning to say “no” will revolutionize your cloud security posture.

As CISOs and security leaders, we’ve long focused on granting access in the cloud through IAM policies and the principle of least privilege. But in complex environments, this “allow-only” model has limits. Permissions pile up, roles get messy, and it becomes hard to answer: Who can actually do what?

The risk of over-permissioning is real, and true least privilege often feels out of reach. But what if we shifted our approach? Instead of just allowing access, what if we clearly defined what’s not allowed?

That’s the power of “no” in Google Cloud. By combining Organization Policies with IAM Deny Policies, you can build stronger, simpler, and more resilient security—creating a secure-by-default cloud environment.

The Challenge of an “Allow-Only” World

Relying solely on traditional IAM allow policies presents several challenges:

  • Complexity Creep: Over time, the combination of predefined roles, custom roles, and group memberships can become incredibly complex, obscuring the true “effective permissions” of a user or service.
  • Risk of Over-permission: To get things working quickly, teams may be granted overly broad roles like Project Owner or Editor. These roles contain thousands of individual permissions, many of which are high-risk and unnecessary for the task at hand.
  • Silent Failures: An allow-only model fails silently. If you forget to apply a restrictive policy, the default is often “allow,” leaving security gaps you may not be aware of.

Two Pillars of Preventative Control: Org Policies and IAM Deny

To build a truly robust defense, Google Cloud provides two distinct but complementary mechanisms for establishing preventative guardrails.

Pillar 1: Organization Policies – The Broad Guardrails

Think of the Organization Policy Service as the “constitution” for your cloud environment. It doesn’t deal with who (identities) can do what, but rather what is allowed to happen within your resource hierarchy (Organization, Folders, Projects). It sets broad, preventative constraints on the types of configurations allowed.

Key Use Cases for Organization Policies:

  • Enforcing Data Sovereignty: Restrict the physical location of newly created resources to specific geographic regions (e.g., constraints/gcp.resourceLocations).
  • Disabling Risky Defaults: Turn off the creation of default networks or prevent VMs from being assigned public IP addresses.
  • Blocking High-Risk Actions: The most powerful example is disabling service account key creation (constraints/iam.disableServiceAccountKeyCreation). Since service account keys are long-lived static credentials, blocking their creation across an entire organization is a massive security win, forcing the use of more secure authentication methods.

Organization Policies are your first line of defense, setting the “safe playground” rules for your entire cloud estate.

Pillar 2: IAM Deny Policies – The Surgical Strike

If Organization Policies are the constitution, IAM Deny Policies are the unbreakable laws. This is where the security model fundamentally shifts.

An IAM Deny Policy allows you to set guardrails on which permissions specific principals (users, groups, service accounts) are forbidden from using, regardless of what IAM roles they have been granted.

The most important concept to understand is this: a deny rule always overrides any allow rule.

This is a game-changer. It doesn’t matter if a user is a Project Owner with thousands of permissions; if a Deny Policy explicitly blocks their ability to use compute.firewalls.create, they simply cannot create that firewall rule. Period.

How IAM Deny Works: The Unbreakable Rule

Deny policies are evaluated before allow policies. When a principal tries to access a resource, GCP checks for any relevant deny rules first.

  • Check for Deny: GCP checks if there is a deny policy that prevents the principal from using the required permission on the resource.
  • Enforce Deny: If a deny rule exists, the access request is denied, and the evaluation process stops.
  • Check for Allow (only if no deny rule applies): If and only if no deny rules block the request, GCP then checks the traditional IAM allow policies to see if the principal has the necessary permission.

Deny policies, like allow policies, are inherited down the resource hierarchy. A policy set at the Organization level applies to all folders and projects within it.

Practical Blueprints: Real-World Use Cases for a Layered Defense

Let’s move from theory to practice. Here’s how you can combine Organization Policies and IAM Deny to create powerful, layered defenses.

Use Case 1: Enforcing Strict Separation of Duties (The “IAM Isolation” Model)

Problem: You have a central networking team responsible for managing all firewall rules. However, project owners, by default, have the compute.firewalls.* permissions and could potentially alter or delete critical security rules, either by accident or with malicious intent.

The Blueprint:

  • Attach a Deny Policy at the folder or organization level.
  • Create a deny rule that denies the compute.firewalls.create, compute.firewalls.delete, and compute.firewalls.update permissions to all principals.
  • Crucially, add an exception to this rule for your central networking admin group (g:[email protected]).

Outcome: Now, no one—not even a Project Owner—can modify firewall rules, except for the members of the designated networking team. You have created an unbreakable guardrail that enforces separation of duties.

Use Case 2: Preventing Privilege Escalation via IAM Tampering

Problem: An attacker who compromises a user with the ability to modify IAM policies (resourcemanager.projects.setIamPolicy) can easily grant themselves the Project Owner role and achieve full control.

The Blueprint:

  • Attach a Deny Policy at the organization level.
  • Create a rule that denies the resourcemanager.projects.setIamPolicy permission to all principals.
  • Add an exception only for a highly secured “break-glass” administrator group, which should be monitored with high-priority alerts.

Outcome: You have severely restricted the most common privilege escalation path in GCP. Day-to-day administrators can no longer grant project-level ownership, drastically reducing your attack surface.

Use Case 3: A Holistic Approach to Service Account Security

Problem: Service accounts are a primary target for attackers. Leaked keys or overly permissive roles can lead to a major breach.

The Blueprint:

  • Broad Guardrail (Org Policy): Enforce the iam.disableServiceAccountKeyCreation constraint across the entire organization. This forces teams to use more secure, short-lived credentials.
  • Surgical Strike (Deny Policy): Create a deny policy that prevents service accounts from being attached to resources in non-production projects (iam.serviceAccounts.actAs) unless they are on an approved list. This stops developers from attaching highly privileged service accounts to test VMs.

Outcome: You have established a multi-layered defense for service accounts, blocking the creation of risky static credentials at the highest level and preventing their misuse with surgical deny rules.

Conclusion: Build Your Unbreakable Guardrails Today

Moving beyond a purely additive security model is a critical step in maturing your cloud security posture. The traditional castle-and-moat approach is no longer sufficient for the complex, distributed nature of the cloud. By embracing the power of “no,” you can establish a simpler, more powerful, and inherently more secure environment.

Start by setting broad, preventative guardrails with Organization Policies to define a safe operational space. Then, layer on IAM Deny Policies to create unbreakable, surgical rules that protect against your highest-risk scenarios. Together, they allow you to grant necessary permissions with confidence, knowing that your foundational guardrails will always be enforced. This is the future of defense-in-depth on Google Cloud.

To further enhance your cloud security and implement Zero Trust, contact me on LinkedIn Profile or [email protected].

GCP IAM Deny & Org Policies FAQ:

  • What is the main difference between an IAM Deny Policy and an Organization Policy? An Organization Policy constrains what actions or configurations are allowed on resources (e.g., “block service account key creation”), regardless of who is making the request. An IAM Deny Policy forbids specific principals from using specific permissions, regardless of what roles they have been granted.
  • If a user is a Project Owner and there’s a Deny Policy blocking a permission in that role, what happens? The Deny Policy wins. Access is denied. Deny policies are always evaluated first and override any “allow” permissions granted by IAM roles.
  • When should I use a Deny Policy versus just creating a restrictive custom IAM role? Use a Deny Policy when you need to create an absolute, unbreakable guardrail that applies across your resource hierarchy, especially to prevent misuse of powerful permissions found in broad roles like Project Owner. It’s for defining what should never happen, while custom roles define what should happen.
  • Can IAM Deny Policies be applied to individual resources, like a single VM? No, Deny Policies can only be attached at the organization, folder, or project level. They are designed for setting broad, inherited guardrails, not for fine-grained resource-level control.
  • Is there a cost associated with using IAM Deny or Organization Policies? No, both the Organization Policy Service and IAM Deny Policies are offered as part of Google Cloud at no additional charge.

Relevant Resource List: