Prepare and test your skills
Prepare and test your skills
Identity and Access Management (IAM) (opens in a new tab) policy inheritance is the additive flow of access from the top of the Google Cloud resource hierarchy (opens in a new tab) down to individual resources. An allow policy attached at the organization, folder, or project level automatically applies to every descendant resource, and the effective allow policy for any resource is the union of its own policy plus all ancestor policies. Because inheritance only adds permissions and never removes them, a broad grant at a parent can create unintended excessive access in child resources.
Allow policies in Identity and Access Management (IAM) can be attached at four levels of the resource hierarchy, and each higher level controls all resources below it.
| Hierarchy level | What a grant at that level controls |
|---|---|
| Organization | The company root node and all folders, projects, and service resources under it |
| Folder | That folder and all child folders, projects, and service resources it contains |
| Project | That project, which acts as a trust boundary, and all service resources inside it |
| Service-specific resource | Only that single resource, such as a Pub/Sub topic or Compute Engine instance |
Organization, folder, and project resources are container resources that structure the hierarchy, while service-specific resources are features offered by services. A role granted on a container flows down to every service-specific resource it contains, while a role granted on a service-specific resource provides granular control limited to that resource. Some resources, such as log buckets, do not support their own allow policies, so access to them must be granted on an ancestor such as the containing project with a role like roles/logging.bucketWriter.
The effective allow policy for a resource is the complete set of principals and permissions that can act on that resource after inheritance is applied. Permissions flow first from the organization to folders, then to projects, then to service-specific resources, and the effective result is always the union of every policy along that path. To calculate effective permissions for a resource:
For example, access flows from project_1 to its topic_a when Kalani receives the Editor role on project_1 and Nur receives the Publisher role on topic_a, so the effective allow policy for topic_a gives Kalani the Editor role through inheritance plus Nur the Publisher role through direct grant. To know who can access a resource, the allow policy on the resource alone is not enough; the resource policy and all ancestor policies must be viewed together.
Exam tip: Allow inheritance is additive only, so a child resource cannot remove a parent grant — the grant must be removed where it was created, while a deny policy can still block an allowed permission.
Parent-level grants create least-privilege risk because one role assignment expands to many child resources at once. Granting access at the project, folder, or organization level controls the named container and all resources within it, so a project-wide Editor grant gives that principal Editor permissions on every topic, bucket, instance, and other descendant in that project. Inherited roles cannot be edited or revoked from the child view in the Google Cloud console; the change must be made on the resource where the role was granted. Choosing the lowest hierarchy level and the smallest set of permissions that still allows the work prevents a convenient parent grant from becoming persistent over-privilege.
A redundant grant occurs when an inherited role already supplies all needed permissions and an additional role adds nothing new. The basic roles are concentric, meaning the Owner role includes all Editor permissions and the Editor role includes all Viewer permissions. If Kalani already inherits Editor on topic_a from project_1, granting Viewer directly on topic_a is redundant and has no effect because every Viewer permission is already present through the inherited Editor role.
Final access to a resource is not determined by allow inheritance alone when conditional and blocking controls are present. Allow inheritance expands access downward, while the following controls narrow or block that expanded access:
A conditional allow granted at a folder or project therefore flows to child resources with its condition still enforced, which supports least privilege for resources that do not support conditions directly. Deny and boundary controls apply after the effective allow policy is calculated, so effective allowed permissions that fall inside a deny or outside a boundary do not result in access.
Identity and Access Management (IAM) (opens in a new tab) deny policies and Organization Policy constraints are two separate layers that limit what inherited allow grants can actually do across the resource hierarchy. Allow policies add permissions as they flow down from organization to folder to project to resource, while deny policies (opens in a new tab) block specific permissions for specific principals regardless of those grants. The Organization Policy Service adds centralized constraints over the same hierarchy to control how resources can be configured and used.
Deny evaluation is the rule that IAM checks relevant deny policies before it checks relevant allow policies for a request. An allow policy grants a principal a role that contains permissions, and those grants accumulate down the hierarchy, but a matching deny rule removes the ability to use the denied permission entirely. If a principal is granted a role with a permission and a deny policy denies that same permission, the principal cannot perform any action that requires the permission. This override behavior lets administrators set guardrails that prevent privilege escalation even when broad allow roles are inherited from above.
Exam tip: A deny rule applies when its denial condition is true or cannot be evaluated; it does not apply only when the condition is false.
A deny policy attachment point is the organization, folder, or project resource where a deny policy is attached and from which it is inherited. When a deny policy is attached to an organization such as cloudresourcemanager.googleapis.com/organizations/123456789012, a folder such as cloudresourcemanager.googleapis.com/folders/987654321098, or a project such as cloudresourcemanager.googleapis.com/projects/my-project, the principals in the policy cannot use the specified permissions on that resource or on any of its descendants. Deny policies inherit the same way allow policies do, so a denial at the organization level also denies the permission on folders and projects inside that organization and on service-specific resources inside each project. Each resource can have up to 500 deny policies attached, with a combined total of 500 deny rules, and each deny policy is evaluated independently of all other deny policies.
Policy changes are eventually consistent and generally take effect within 2 minutes, although in some cases propagation across the system can take 7 minutes or more. This delay means a newly created deny rule or revoked allow grant may not block access immediately. Designs that centralize administrative privilege with a high-level deny must account for this window when responding to incidents.
A deny rule is the unit inside a deny policy that names who is blocked, what is blocked, and when the block applies. A deny policy contains metadata including name, unique ID, kind always set to DenyPolicy, optional display name, etag for conflicting-update protection, creation time, and update time. The policy name uses the form policies/ATTACHMENT_POINT/denypolicies/POLICY_ID, where the attachment point identifies the project, folder, or organization.
Each deny rule can contain the following fields:
deniedPrincipals: individual principals and sets of principals that are denied, including user accounts, service accounts, Google groups, Cloud Identity domains, workforce or workload identities, and all users on the internet.exceptionPrincipals: principals exempt from the rule even if they match deniedPrincipals, such as specific admins inside a denied group or service agents needed to keep services functioning.deniedPermissions: permissions the principals cannot use, written in IAM v2 format SERVICE_FQDN/RESOURCE.ACTION such as iam.googleapis.com/roles.delete, limited to permissions supported in deny policies and sometimes expressed as permission groups.exceptionPermissions: permissions that remain usable even if included in deniedPermissions, used to carve out specific permissions from a broad group denial.denialCondition: optional Common Expression Language expression, such as !resource.matchTag('12345678/env', 'test'), that makes the denial apply only when the expression demands it.Denied permissions use fully qualified domain names, with Google APIs using *.googleapis.com. A common pattern is to deny broad sets like principalSet://goog/public:all while adding a group such as project admins to exceptionPrincipals, so only the exception group retains sensitive actions like project deletion or folder management.
The effective allow policy for a resource is the union of the allow policy set directly on that resource and all allow policies inherited from its ancestors. Roles granted at the organization level are inherited by all resources under the organization, roles granted at the highest folder level are inherited by contained folders and projects, roles granted at the project level are inherited by resources within that project, and some service-specific resources support their own lower-level roles. To understand who can access a resource, all affecting allow policies must be viewed together because access flows from the trigger of a request through every applicable ancestor grant.
This model is additive and concentric, not subtractive. If Kalani is granted Editor on project_1 and Nur is granted Publisher on topic_a inside that project, the effective result for topic_a is Editor for Kalani plus Publisher for Nur. Granting an additional role that contains the same or fewer permissions is redundant, such as granting Viewer on the topic to someone who already inherits Editor from the project, because the inherited permissions already include everything the narrower grant would add.
The Organization Policy Service is the service that configures constraints across the resource hierarchy to give centralized and programmatic control over cloud resources. An IAM allow policy answers who has what role for which resource, and an IAM deny policy answers which principals cannot use which permissions even if granted, while an organization policy constraint answers what configurations or behaviors are permitted on resources under its scope. Traffic from an access request therefore depends on both layers: the request must pass IAM evaluation and must also satisfy applicable organization constraints, Access Context Manager rules, and other controls such as VPC Service Controls or Identity-Aware Proxy where they apply.
The three hierarchy mechanisms differ in inheritance effect and purpose:
| Mechanism | What it controls | Inheritance effect |
|---|---|---|
| Allow policy | Which principals receive roles and permissions on a resource | Merges by union; child effective policy includes parent grants |
| Deny policy | Which principals are blocked from using specific permissions | Inherits downward and overrides any allow grant for matching principal and permission |
| Organization policy constraint | Which resource configurations are allowed across the hierarchy | Applies centrally across organization, folder, and project levels to restrict resource use |
Choose allow grants for least-privilege delegation at the lowest level that still works, choose deny rules when broad inherited roles must be carved back for compliance or centralization of admin privilege, and choose organization policy constraints when the goal is to limit resource configuration itself rather than identity permissions. Together they prevent privilege escalation because a lower-level allow grant cannot bypass a higher-level deny or a higher-level constraint that governs the same hierarchy path.
Conditional and tag-based access control is a way to grant Identity and Access Management (IAM) roles dynamically instead of granting the same access to every resource under a policy. A conditional role binding attaches a Common Expression Language condition to an allow policy binding, and IAM grants the permissions in the role only when the condition evaluates to true for that specific request. Resource Manager tags (opens in a new tab) extend this model by letting access flow from annotations attached to organization, folder, or project nodes down to their child resources.
Resource-based IAM Conditions (opens in a new tab) control whether a principal can use a permission based on attributes of the target resource, specifically resource.name, resource.type, and resource.service. When a request arrives, IAM evaluates the allow policy that applies to the resource and then evaluates the condition expression against the resource that owns the permission check; access flows from the binding to the resource only if the expression returns true. The resource.name attribute is supported only for specific services, including Compute Engine, Cloud Storage, BigQuery, Cloud SQL, Spanner, Bigtable, Cloud Key Management Service, Secret Manager, Pub/Sub Lite, and Cloud Logging, among others. A conditional binding never expands access beyond an unconditional binding, so if a principal already has the same role without a condition, the condition does not restrict them.
Exam tip: A conditional role binding does not override an unconditional binding for the same principal and role — the unconditional grant still applies.
Inherited conditions are conditional role bindings set on a container such as an organization, folder, or project that propagate down the resource hierarchy to child resources. The effective allow policy for a child is the union of its own policy and the policies inherited from its parents, so a condition defined once at the top can govern many descendants. This inheritance is especially useful when a child resource does not accept conditions in its own allow policy or has no allow policy at all. Most resource attributes are available only for specific resource types, and if a condition tests an attribute that a resource does not provide, that part of the condition never grants access.
To avoid silently denying access, guard name checks with resource.type or resource.service so non-matching types bypass the name test. For example, the expression resource.type != 'compute.googleapis.com/Disk' || resource.name.endsWith('devResource') evaluates to true for every resource type other than Compute Engine disks, and only checks the resource name for disks. First the request identifies the resource type, then IAM applies the name test only where the attribute exists, which preserves least privilege without breaking unrelated services.
Conditions for custom roles must account for every resource type that an operation touches, because a single user action often checks permissions on more than one type. Creating a Compute Engine virtual machine (VM) instance, for example, requires permissions on both compute.googleapis.com/Instance and compute.googleapis.com/Disk resources, so the condition depends on both the instance object and the disk object. A condition that checks only disks, such as resource.type == 'compute.googleapis.com/Disk' && resource.name.startsWith('projects/PROJECT_ID/zones/ZONE_ID/disks/staging'), blocks the VM permissions because the instance check never matches. The corrected pattern joins a guarded clause for each type with ||, and optionally adds a final clause that passes all other types through unchanged.
Parent-only permissions are *.list permissions that are checked on the parent container rather than on the child resources being listed. To list projects in an organization, the principal needs resourcemanager.projects.list on the organization object, not on each project, and to list Compute Engine disks the check occurs on the Project object with type cloudresourcemanager.googleapis.com/Project. A condition that only matches compute.googleapis.com/Disk therefore prevents compute.disks.list, because the resource under evaluation is the parent project. To grant list access correctly, set resource.service and resource.type in the condition to match the parent type where the check occurs. The service that owns the parent must also recognize the attributes used, so resource.name cannot be used at the project level because Resource Manager does not provide that attribute for projects.
Tag-based access uses Resource Manager tags as annotations that attach to an organization, folder, or project and are inherited by descendant resources. An IAM Condition then calls a tag function on the resource object during authorization, and access flows from the binding to the resource only when the tag test returns true. Tag inheritance lets one policy at a folder grant the same conditional role to every tagged child without creating per-project bindings. Some areas of the Google Cloud console do not recognize tag-conditional bindings and may incorrectly block an action, in which case the same action can be performed with the gcloud CLI.
Tag conditions use different functions depending on the identifier type. Conditions that use permanent IDs call resource.matchTagId(keyId, valueId) to require a specific key-value pair and resource.hasTagKeyId(keyId) to require any value for a key. Conditions that use human-readable names call resource.matchTag(namespacedKey, shortValue), such as resource.matchTag('123456789012/env', 'prod'), and resource.hasTagKey(namespacedKey) to require any value for that key.
Choosing a tag identifier is a tradeoff between operational convenience and safety when keys or values are deleted and recreated. Namespaced names for keys and short names for values are easier to read and work well for experiments and declarative tools like Terraform, because the same names can be reused after recreation. Permanent IDs in the form tagKeys/123456789012 and tagValues/567890123456 can never be reused, so they isolate the condition from a future key or value that happens to share the old name.
| Identifier type | Reuse after delete and recreate | Risk if name is reused with new meaning |
|---|---|---|
Namespaced name and short name, such as 123456789012/env and prod | Condition continues to work without policy updates | Condition continues to apply to the new tag, which can grant unintended access |
Permanent ID, such as tagKeys/123456789012 | Policy must be updated to the new IDs to preserve access | Condition does not apply to the new tag, which reduces unintended access |
Use names when readability and stable declarative management matter most and the tag lifecycle is controlled. Use permanent IDs when minimizing the risk of unintended grants matters most, especially for sensitive environments where tag names might be recycled with different meanings.
The effective allow policy is the union of the resource's own allow policy plus all allow policies inherited from its organization, folder, and project ancestors. Inheritance is additive only, so a child resource cannot remove a parent grant and the grant must be removed where it was created, while a deny policy can still block an allowed permission.
Use deny policies when specific principals must be blocked from using specific permissions even when an inherited or direct allow grant includes those permissions, because deny evaluation overrides matching allow grants. Use Organization Policy constraints when the goal is to limit which resource configurations are permitted under organization, folder, or project scope rather than identity permissions.
A conditional role binding grants permissions only when its condition evaluates to true for the request, and conditions set on a container such as a folder or project are inherited by descendant resources with the condition still enforced. Resource Manager tags attached to an organization, folder, or project are inherited by descendant resources and can be checked with conditions such as resource.matchTag and resource.matchTagId to grant access only when the tag test returns true.
A security engineer is evaluating IAM access across an organization's resource hierarchy structured as follows:
Finance-Deptfin-analytics-prod (child of Finance-Dept)fin-audit-logs (located inside fin-analytics-prod)The following IAM allow policies are currently configured:
Finance-Dept Folder level, the principal auditor@example.com is granted the Storage Admin (roles/storage.admin) role.fin-analytics-prod Project level, auditor@example.com is granted the Storage Object Viewer (roles/storage.objectViewer) role.fin-audit-logs Bucket level, a local administrator attempts to restrict access by granting auditor@example.com only the Storage Object Creator (roles/storage.objectCreator) role.What is the effective permission state of auditor@example.com on the fin-audit-logs bucket, and why?
Last updated