Business Challenge
Organization Policy is usually adopted after an incident, in a hurry, and the four surprises below all arrive in the first fortnight.
Because enforcement of most organization policies is not retroactive. Google states it plainly: if a new policy restricts an action or state a service is already in, the policy is considered to be in violation, but the service will not stop its original behaviour. The constraint blocks the next one. It does not undo the last hundred.
Correct approachTreat switching a constraint on as closing the door, and treat the existing violations as a separate remediation project with its own inventory. A green policy page is not a compliant estate, and nothing in the console reconciles the two for you.
For list constraints, DENY values always take precedence. If a folder denies a value and a project underneath allows the same value, the policies merge and the denial wins. A team with full policy rights over their own project still cannot buy back something the parent took away.
Read a denial at any ancestor as final for everything beneath it. If an exception is genuinely needed, it has to be made where the denial was set — or the resource has to move to a branch that never denied it.
Not necessarily. Where an organization policy is not enforced, it inherits from its lowest ancestor where one is enforced — and if no policy is enforced anywhere in the ancestor hierarchy, the Google-managed default behaviour of the constraint applies. Some of those defaults are restrictive, so an unset policy is not the same as an open one.
Correct approachNever reason from what is set. Read the effective policy on the resource you actually care about, which is the only value that decides anything.
Changes to organization policies can take up to 15 minutes to be fully enforced. That is long enough for an engineer to conclude the change did not work, make a second change, and end up debugging two.
Correct approachBuild the fifteen minutes into any pipeline that sets a policy and then tests against it. A retry loop is the fix; a second policy edit is how a simple change becomes an afternoon.
Architecture
Two nouns do most of the work here and they are routinely used interchangeably, which is the source of a good deal of confusion.
Constraint and policy are not the same noun
A constraint is a particular type of restriction against a Google Cloud service — a definition, published by Google, that does nothing on its own. An organization policy configures a single constraint, and it is the act of configuring that makes anything happen. The constraint is the blueprint; the policy is the building.
This matters practically because the two are named the same way in conversation. "We have a policy on public IPs" and "there is a constraint for public IPs" describe entirely different states of the world: the second is true for everybody on Google Cloud and implies nothing about your estate.
Google draws the line in one sentence: Identity and Access Management focuses on who, and Organization Policy focuses on what. IAM decides whether a principal may create a VM. Organization Policy decides whether a VM with an external IP may exist in this folder at all — regardless of who is asking, including the person who wrote the policy. That is the point of it: a control that does not depend on the permissions of the caller cannot be escaped by escalating them.
Where a policy can be set, and what inherits
A policy is set on an organization, folder, or project resource, and it enforces the constraint on that resource and any child resources. When set, all descendants inherit it by default.
Three levels, one direction. There is no policy on an individual VM or bucket — the granularity of Organization Policy is the granularity of the hierarchy, which is why the hierarchy design covered earlier in this series is load-bearing for governance and not merely tidy.
What actually applies: the effective policy
The value that decides anything is the effective policy on the resource, and it is computed rather than stored. The rules, in the order they matter:
| Situation | Result |
|---|---|
| A policy is set on the resource | A resource that has an organization policy set by default supersedes any policy set by its parent resources in the hierarchy. |
inheritFromParent = true |
The effective policy of the parent is inherited, merged and reconciled to evaluate the resulting effective policy. |
inheritFromParent = false |
The resource does not inherit the organization policy from its parent. |
| List constraint, parent denies and child allows | DENY values always take precedence. The denial stands. |
| Nothing enforced on the resource | It inherits from its lowest ancestor where a policy is enforced. |
| Nothing enforced anywhere above it | The Google-managed default behaviour of the constraint is enforced. |
RestoreDefault invoked |
The policy uses the default behaviour of the constraint for this resource, and child resources also inherit that behaviour. |
Two rules in that table point in opposite directions and both are true. A policy set on a resource supersedes its parent — that is real delegation, and a project team can genuinely override what a folder decided. But for list constraints a DENY always takes precedence when the policies merge, so the override only works upward into permissiveness that nobody has explicitly forbidden. A parent can hand down freedom and have it refused; it cannot hand down a prohibition and have it ignored. Design the hierarchy on that basis: put denials high, because they are the only thing that cannot be undone from below.
Who can change one
Setting or modifying a policy needs the Organization policy administrator role, roles/orgpolicy.policyAdmin, granted on the organization. That placement is deliberate and worth resisting pressure on: the role that can edit the constraint set is the role that can dismantle every guardrail beneath it, and granting it at a folder to give one team self-service is a much larger delegation than it appears.
Why This Architecture Holds Up
The rollout problem, which is not a policy problem
Because enforcement is usually not retroactive, turning a constraint on splits your estate into two populations that look identical in the console: resources that comply, and resources that are in violation and running perfectly well. Google notes that where a constraint is retroactively enforced it will be labelled as such — so the default assumption is that yours is not.
The practical consequence is that a policy rollout has two halves with different owners and different timescales. Setting the policy is a five-minute change by a platform engineer. Finding and fixing the existing violations is an inventory exercise across every team, and it is the half that gets skipped because the policy page already looks correct.
Tags provide a way to conditionally enforce constraints based on whether a resource has a specific tag. This is the mechanism that makes a broad denial survivable: deny at the organization, then exempt precisely the resources carrying an agreed tag, rather than carving holes in the hierarchy by creating a folder for every exception. It is also the clearest illustration of why the previous post insisted the distinction matters — a label here would do nothing at all, because policy engines do not read labels.
Reading a policy you did not write
The single most useful habit is to stop reading policy documents and start reading effective policies. A document tells you what one person decided at one level; the effective policy tells you what will happen. They differ whenever anything above has an opinion, which in a mature organization is most of the time.
The same applies when writing. A policy that looks permissive at the project can be entirely inert because a folder above denies the values it allows, and nothing reports that as an error — the merge is silent and successful. Google's own advice on the related trap is worth taking literally: do not include a value in both the allowed and denied lists, because it makes policies harder to understand.
Fifteen minutes, and what to do with them
Policy changes take up to 15 minutes to be fully enforced. Three consequences follow, none of them obvious:
- Automated tests must wait. A pipeline that sets a policy and immediately asserts on it will fail intermittently, and the failure looks like a flaky test rather than a documented propagation delay.
- Incident response is not instant. If a policy is the mitigation for an active problem, fifteen minutes is the floor on the mitigation, and something else has to cover the gap.
- Do not stack edits. A second change made while the first is propagating produces a state nobody predicted and a debugging session with two variables.
Key Architecture Decisions
| Decision | Choose this | Because |
|---|---|---|
| Where to put a denial | As high as it is true | A DENY always takes precedence and cannot be undone from below; permissiveness can. |
| Turning a constraint on | Plan the remediation separately | Enforcement is usually not retroactive; existing violations keep running. |
| Judging compliance | Inventory the resources, not the policies | A policy page shows intent; it does not show the estate. |
| Reading what applies | The effective policy on the resource | It is computed from every ancestor, and it is the only value that decides anything. |
| Exceptions to a broad rule | Conditional enforcement on a tag | Tags can conditionally enforce constraints; a new folder per exception deforms the hierarchy. |
| Granting policy rights | roles/orgpolicy.policyAdmin, at the organization, sparingly |
It is the role that can remove every guardrail beneath it. |
| Pipelines that set policy | Wait and retry for up to 15 minutes | That is the documented time for a change to be fully enforced. |
Using inheritFromParent = false |
Rarely, and never at a boundary you rely on | It detaches a subtree from everything an ancestor decided. |
| Returning to the default | RestoreDefault, deliberately |
It restores the constraint's default behaviour and children inherit that, which may not be permissive. |
| Writing list rules | Never list a value as both allowed and denied | Google's own recommendation; it makes the policy harder to understand and the deny wins anyway. |
| Assuming an unset policy is permissive | Do not | With nothing enforced anywhere, the Google-managed default applies, and some defaults restrict. |
Closing Thought
Most access control on a cloud platform is a conversation about people: who is on call, who approves, who has the role. Organization Policy is the part that refuses to have that conversation. It does not care who is asking, which is exactly why it is the only control that still holds when an account is compromised or an automation is given too much.
The cost of that strength is that its behaviour is never local. No single policy document tells you what will happen, because what happens is assembled from every level above the resource and reconciled by rules that deliberately favour denial. That is the right bias for a guardrail. But it means the honest question is never "what policy did we set" — it is "what is the effective policy here, and what is already running that would fail it today".
#20 opens up the constraints themselves: boolean, list and custom — what each can express, why a list constraint needs a value format you cannot guess, and what becomes possible once you can write your own.
Comments