Understanding allow policies

You can grant access to Google Cloud resources by usingallow policies, also known asIdentity and Access Management (IAM) policies, which areattached to resources. You can attach only one allow policy to each resource.The allow policy controls access to the resource itself, as well as anydescendants of that resource thatinherit the allow policy.

This page shows allow policies in JSON format. You can also use theGoogle Cloud CLI to retrieve allow policies in YAML format.

Policy structure

An allow policy is a collection ofrole bindings and metadata. A role bindingspecifies what access should be granted to a resource. It associates, orbinds, one or moreprincipals with a single IAMrole andany context-specificconditions that change how and when the role is granted.The metadata includes additional information about the allow policy, such as anetag andversion to facilitate policy management.

Each role binding can include the following fields:

  • One or moreprincipals, also known asmembers oridentities. There are multiple types of principals, includingsingle users, groups of users, and service accounts. For a full list ofsupported principal types, seePrincipal types.
  • Arole, which is a named collection ofpermissions that provide the ability to perform actions on Google Cloudresources.
  • Acondition, which is an optional logicexpression that further constrains the role binding based on attributes aboutthe request, such as its origin or the target resource. Conditionsare typically used to control whether access is granted based on the contextfor a request.

    If a role binding contains a condition, it is referred to as aconditionalrole binding.

    Some Google Cloud services don't accept conditions in allow policies.For a list of services and resource types that accept conditions, seeResource types that accept conditional role bindings.

Changes to a principal's access areeventually consistent. This means that it takes time for access changes topropagate through the system. To learn how long it takes, on average, for access changes topropagate, seeAccess change propagation.

Limits on all principals

Each allow policy can contain up to 1,500 principals. For the purposes of this limit, IAM countsall appearances of each principal in the allow policy's role bindings, as well as the principals that the allow policyexempts from Data Access audit logging. It doesnot deduplicate principals that appear in more than one role binding. For example, if an allow policy contains only role bindings for the principaluser:my-user@example.com, and this principal appears in 50 role bindings, then you can add another 1,450 principals to the role bindings in the allow policy.

Also, for the purposes of this limit, each appearance of a domain or Google group is counted as a single principal, regardless of the number of individual members in the domain or group.

If you use IAM Conditions, or if you grant roles to many principals with unusually long identifiers, then IAM might allow fewer principals in the allow policy.

Limits on groups and domains

Up to 250 of the principals in an allow policy canbe Google groups, Cloud Identity domains, or Google Workspace accounts.

For the purposes of this limit, Cloud Identity domains, Google Workspace accounts, and Google groups are counted as follows:

  • For Google groups, each unique group is counted only once, regardless of how many times the group appears in the allow policy. This is different from how groups are counted for the limit on the total number of principals in an allow policy—for that limit, each appearance of a group counts towards the limit.
  • For Cloud Identity domains or Google Workspace accounts, IAM countsall appearances of each domain or account in the allow policy's role bindings. It doesnot deduplicate domains or accounts that appear in more than one role binding.

For example, if your allow policy contains only one group,group:my-group@example.com, and the group appears in the allow policy 10 times, then you can add another 249 Cloud Identity domains, Google Workspace accounts, or unique groups before you reach the limit.

Alternatively, if your allow policy contains only one domain,domain:example.com, and the domain appears in the allow policy 10 times, then you can add another 240 Cloud Identity domains, Google Workspace accounts, or unique groups before you reach the limit.

Policy metadata

The metadata for an allow policy includes the following fields:

  • Anetag field, which is used for concurrency control, and ensures that allowpolicies are updated consistently. For details, seeUsing etags in a policy on this page.
  • Aversion field, which specifies the schema version for a given allowpolicy. For details, seePolicy versions on this page.

For organizations, folders, projects, and billing accounts, the allow policy canalso contain anauditConfig field, which specifies the types of activity thatgenerateaudit logs for each service. To learn how to configurethis part of an allow policy, seeConfiguring Data Access audit logs.

Using etags in a policy

When multiple systems try to write to the same allow policy at the same time,there is a risk that those systems might overwrite each other's changes. Thisrisk exists because allow policies are updated using theread-modify-writepattern, which involves multiple operations:

  1. Reading the existing allow policy
  2. Modifying the allow policy
  3. Writing the entire allow policy

If System A reads an allow policy, and System B immediately writes an updatedversion of that allow policy, then System A will not be aware of the changesfrom System B. When System A writes its own changes to the allow policy, SystemB's changes could be lost.

To help prevent this issue, Identity and Access Management (IAM) supports concurrencycontrol through the use of anetag field in the allow policy. Every allowpolicy contains anetag field, and the value of this field changes each timean allow policy is updated. If an allow policy contains anetag field, but norole bindings, then the allow policy does not grant any IAMroles.

Theetag field contains a value such asBwUjMhCsNvY=. When you update theallow policy, be sure to include theetag field in the updated allow policy.If the allow policy has been modified since you retrieved it, theetag valuewill not match, and the update will fail. For the REST API, you receive the HTTPstatus code409 Conflict, and the response body is similar to the following:

{"error":{"code":409,"message":"There were concurrent policy changes. Please retry the whole read-modify-write with exponential backoff.","status":"ABORTED"}}

If you receive this error, retry the entire series of operations: read the allowpolicy again, modify it as needed, and write the updated allow policy. Youshouldperform retries automatically, with exponentialbackoff, in any tools that you use to manage allow policies.

Example: Simple policy

Consider the following allow policy that binds a principal to a role:

{"bindings":[{"members":["user:jie@example.com"],"role":"roles/owner"}],"etag":"BwUjMhCsNvY=","version":1}

In the preceding example, Jie is granted theOwner basicrole without any conditions.This role gives Jie almost unlimited access.

Caution: Basic roles include thousands of permissions across all Google Cloud services. In productionenvironments, do not grant basic roles unless there is no alternative. Instead, grant the mostlimitedpredefined roles orcustom roles that meet your needs.

Example: Policy with multiple role bindings

Consider the following allow policy that contains more than one role binding.Each role binding grants a different role:

{"bindings":[{"members":["user:jie@example.com"],"role":"roles/resourcemanager.organizationAdmin"},{"members":["user:raha@example.com","user:jie@example.com"],"role":"roles/resourcemanager.projectCreator"}],"etag":"BwUjMhCsNvY=","version":1}

In the preceding example, Jie is granted theOrganizationAdmin predefined role(roles/resourcemanager.organizationAdmin) in the first role binding. This rolecontains permissions for organizations, folders, and limited projectsoperations. In the second role binding, both Jie and Raha are granted theability to create projects by the Project Creator role(roles/resourcemanager.projectCreator). Together, these role bindings grantfine-grained access to both Jie and Raha, and Jie is granted more access thanRaha.

Example: Policy with conditional role binding

Consider the following allow policy, which binds principals to a predefined roleand uses a condition expression to constrain the role binding:

{"bindings":[{"members":["group:prod-dev@example.com","serviceAccount:prod-dev-example@appspot.gserviceaccount.com"],"role":"roles/appengine.deployer","condition":{"title":"Expires_July_1_2022","description":"Expires on July 1, 2022","expression":"request.time < timestamp('2022-07-01T00:00:00.000Z')"}}],"etag":"BwWKmjvelug=","version":3}

In this example, theversion field is set to3,because the allow policy contains a condition expression. The role binding inthe allow policy is conditional; it grants the role to theprod-dev group andthe service accountprod-dev-example@appspot.gserviceaccount.com, but only until July 1, 2022.

For details about the features that each allow policy version supports, seePolicy versions on this page.

Example: Policy with conditional and unconditional role bindings

Consider the following allow policy, which contains both conditional andunconditional role bindings for the same role:

{"bindings":[{"members":["serviceAccount:prod-dev-example@appspot.gserviceaccount.com"],"role":"roles/appengine.deployer"},{"members":["group:prod-dev@example.com","serviceAccount:prod-dev-example@appspot.gserviceaccount.com"],"role":"roles/appengine.deployer","condition":{"title":"Expires_July_1_2022","description":"Expires on July 1, 2022","expression":"request.time < timestamp('2022-07-01T00:00:00.000Z')"}}],"etag":"BwWKmjvelug=","version":3}

In this example, the service accountserviceAccount:prod-dev-example@appspot.gserviceaccount.comis included in two role bindings for the same role. The first role binding doesnot have a condition. The second role binding has a condition that only grantsthe role until July 1, 2022.

Effectively, this allow policy always grants the role to the service account. InIAM, conditional role bindings don't override role bindings withno conditions. If a principal is bound to a role, and the role binding does nothave a condition, then the principal always has that role. Adding the principalto a conditional role binding for the same role has no effect.

In contrast, theprod-dev group is included only in the conditional rolebinding. Therefore, it has the role only before July 1, 2022.

Example: Policy that binds a role to a deleted principal

Consider the following allow policy. This allow policy binds a role to a serviceaccount,serviceAccount:my-service-account@my-project.iam.gserviceaccount.com, which was deleted. As a result, the serviceaccount's identifier now has adeleted: prefix:

{"bindings":[{"members":["deleted:serviceAccount:my-service-account@my-project.iam.gserviceaccount.com?uid=123456789012345678901"],"role":"roles/owner"}],"etag":"BwUjMhCsNvY=","version":1}

If you create a new service account with the same name, the allow policy's rolebindings for the deleted service account don't apply to the new service account.This behavior applies for all types of deleted principals.

This behavior prevents new principals from inheriting roles that were granted todeleted principals. If you want to grant roles to the new principal, add the newprincipal to the allow policy's role bindings, as shown inPolicies withdeleted principals on this page.

All deleted principals have the prefixdeleted:. Some types of deletedprincipals, like service accounts, also have the suffix?uid=numeric-id, wherenumeric-id is the deleted principal's unique numeric ID.In this example, instead ofserviceAccount:serviceAccount:my-service-account@my-project.iam.gserviceaccount.com, the allow policy shows the identifierdeleted:serviceAccount:my-service-account@my-project.iam.gserviceaccount.com?uid=123456789012345678901.

Default policies

Allresources that accept allow policies are createdwith default allow policies. Most resources' default allow policies are empty.However, some resources' default allow policies automatically contain certainrole bindings. For example, when you create a new project, the allow policy forthe project automatically has a role binding that grants you the Owner role(roles/owner) on the project.

These role bindings are created by the system, so the user doesn't needgetIamPolicy orsetIamPolicy permissions on the resource for the rolebindings to be created.

To learn if a resource is created with an allow policy, refer to the resource'sdocumentation.

Policy inheritance and the resource hierarchy

Google Cloud resources are organized hierarchically, where theorganization node is the root node in the hierarchy, then optionally folders,then projects. Most of other resources are created and managed under a project.Each resource has exactly one parent, except the organization. The organization,as the root node in the hierarchy, has no parent. See theResourceHierarchy topic formore information.

The resource hierarchy is important to consider when setting an allow policy.When setting an allow policy at a higher level in the hierarchy, such as at theorganization level, folder level, or project level, the granted access scopeincludes the resource level where this allow policy is attached to and allresources under that level. For example, an allow policy set at the organizationlevel applies to the organization and all resources under the organization.Similarly, an allow policy set at the project level applies to the project andall resources in the project.

Policy inheritance is the term that describes how allow policies apply toresources beneath their level in the resource hierarchy.Effective policy isthe term that describes how all parent allow policies in the resource hierarchyare inherited for a resource. It is the union of the following:

  • The allow policy set on the resource
  • The allow policies set on all of resource's ancestry resource levels in thehierarchy

Each new role binding (inherited from parent resources) that affect theresource's effective allow policy are evaluated independently. A specific accessrequest to the resource is granted if any of the higher-level role bindingsgrant access to the request.

If a new role binding is introduced to any level of a resource's inherited allowpolicy, the access grant scope increases.

Example: Policy inheritance

To understand allow policy inheritance, consider a scenario where you grant auser, Raha, two different IAM roles at two different levels inthe resource hierarchy.

To grant Raha a role at theorganization level, youset the following allowpolicy on your organization:

{"bindings":[{"members":["user:raha@example.com"],"role":"roles/storage.objectViewer"}],"etag":"BwUjMhCsNvY=","version":1}

This allow policy grants Raha the Storage Object Viewer role(roles/storage.objectViewer), which containsget andlist permissions forprojects and Cloud Storage objects. Because you set the allow policy onyour organization, Raha can use these permissions for all projects and allCloud Storage objects in your organization.

To grant Raha a role at theproject level, youset the following allowpolicy on the projectmyproject-123:

{"bindings":[{"members":["user:raha@example.com"],"role":"roles/storage.objectCreator"}],"etag":"BwUjMhCsNvY=","version":1}

This allow policy grants Raha the Storage Object Creator role(roles/storage.objectCreator), which lets them create Cloud Storageobjects. Because you set the allow policy onmyproject-123, Raha can createCloud Storage objects only inmyproject-123.

Now that there are two role bindings that grant Raha access to the targetCloud Storage objects undermyproject-123, the following allow policiesapply:

  • An allow policy at the organization level grants the ability to list and getall Cloud Storage objects under this organization.
  • An allow policy at the project level, for the projectmyproject-123, grantsthe ability to create objects within that project.

The following table summarizes Raha's effective policy:

Permissions from the Storage Object Viewer role on the organizationPermissions from the Storage Object Creator role on `myproject-123`Effective permissions for Raha on `myproject-123`
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.create
resourcemanager.projects.get
resourcemanager.projects.list
storage.objects.get
storage.objects.list
storage.objects.create

Policy versions

Over time, IAM might add new features that significantly add orchange fields in the allow policy schema. To avoid breaking your existingintegrations that rely on consistency in the allow policy structure, suchchanges are introduced in new allow policy schema versions.

If you are integrating with IAM for the first time, werecommend using the most recent allow policy schema version available at thattime. The following section discusses the different versions available and howto use each. It also describes how to specify a policy version and discussessome troubleshooting scenarios.

Every existing allow policy specifies aversion field as part of the allowpolicy's metadata. Consider the highlighted portion of the following sample:

{"bindings":[{"members":["user:jie@example.com"],"role":"roles/owner"}],"etag":"BwUjMhCsNvY=","version":1}

This field specifies thesyntax schema version of the allow policy. Eachversion of the allow policy contains a specific syntax schema that can be usedby role bindings. The newer version can contain role bindings with the newersyntax schema that is unsupported by earlier versions. This field is notintended to be used for any purposes other than controlling the syntax schemafor the allow policy.

Valid policy versions

Allow policies can use the following allow policy versions:

VersionDescription
1The first version of the IAM syntax schema for policies. Supports binding one role to one or more principals. Does not support conditional role bindings.
2Reserved for internal use.
3 Introduces thecondition field in the role binding, which constrains the role binding using context-based and attribute-based rules. For more information, see theoverview of IAM Conditions.

Specifying a policy version when getting a policy

For the REST API and client libraries, when youget an allow policy, we recommend that you specify an allow policyversion in the request. When a request specifies an allow policy version,IAM assumes that the caller is aware of the features in thatallow policy version and can handle them correctly.

Note: When you use the Google Cloud console or the gcloud CLI, youdon't need to specify an allow policy version. These tools specify the versionautomatically.

If the request does not specify an allow policy version, IAMassumes that the caller wants a version1 allowpolicy.

When you get an allow policy, IAM checks the allow policyversion in the request, or the default version if the request did not specify aversion. IAM also checks the allow policy for fields that arenot supported in a version1 allow policy. It usesthis information to decide what type of response to send:

Scenario 1: Policy version that fully supports IAM Conditions

Suppose you call the following REST API method to get the allow policy for aproject:

POSThttps://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

The request body contains the following text:

{"options":{"requestedPolicyVersion":3}}

The response contains the project's allow policy. If the allow policy containsat least one conditional role binding, itsversion field is set to3:

{"bindings":[{"members":["user:tal@example.com"],"role":"roles/iam.securityReviewer","condition":{"title":"Expires_July_1_2022","description":"Expires on July 1, 2022","expression":"request.time < timestamp('2022-07-01T00:00:00.000Z')"}}],"etag":"BwWKmjvelug=","version":3}

If the allow policy does not contain conditional role bindings, itsversionfield is set to1, even though the request specifiedversion3:

{"bindings":[{"members":["user:tal@example.com"],"role":"roles/iam.securityReviewer",}],"etag":"BwWKmjvelug=","version":1}

Scenario 2: Policy version with limited support for IAM Conditions

Suppose you call the following REST API method to get the allow policy for aproject:

POSThttps://cloudresourcemanager.googleapis.com/v1/projects/project-id:getIamPolicy

The request body is empty; it does not specify a version number. As a result,IAM uses the default allow policy version,1.

The allow policy contains a conditional role binding. Because the allow policyversion is1, the condition does not appear in theresponse. To indicate that the role binding uses a condition,IAM appends the string_withcond_ to the role name,followed by a hash value:

{"bindings":[{"members":["user:tal@example.com"],"role":"roles/iam.securityReviewer_withcond_58e135cabb940ad9346c"}],"etag":"BwWKmjvelug=","version":1}

Specifying a policy version when setting a policy

When youset an allow policy, we recommend that you specify anallow policy version in the request. When a request specifies an allow policyversion, IAM assumes that the caller is aware of the featuresin that allow policy version and can handle them correctly.

Note: When you use the Google Cloud console or the gcloud CLI, youdon't need to specify an allow policy version. These tools specify the versionautomatically.

If the request does not specify an allow policy version, IAMaccepts only the fields that can appear in a version1 allow policy. As a best practice, don't changeconditional role bindings in a version1 allowpolicy; because the allow policy does not show the condition for each rolebinding, you don't know when or where the role binding is actually granted.Instead, get the version3 representation of the allowpolicy, which shows the condition for each role binding, and use thatrepresentation to update the role bindings.

Important: If you use IAM Conditions, always specify allowpolicy version3, and always include theetag fieldwhen you use a client library or the REST API to set an allow policy. If youomit theetag field, then IAM lets you overwrite aversion3 allow policy with a version1 allow policy, which deletes all of the conditionsfrom the allow policy.

Scenario: Policy versions in requests and responses

Suppose you use the REST API to get an allow policy, and you specify version3 in the request. The response contains the followingallow policy, which uses version3:

{"bindings":[{"members":["user:raha@example.com"],"role":"roles/storage.admin","condition":{"title":"Weekday_access","description":"Monday thru Friday access only in America/Chicago","expression":"request.time.getDayOfWeek('America/Chicago') >= 1 && request.time.getDayOfWeek('America/Chicago') <= 5"}}],"etag":"BwUjMhCsNvY=","version":3}

You decide that Raha should have the Storage Admin role (roles/storage.admin)throughout the week, not just on weekdays. You remove the condition from therole binding and send a REST API request to set the allow policy; once again,you specify version3 in the request:

{"bindings":[{"members":["user:raha@example.com"],"role":"roles/storage.admin"}],"etag":"BwUjMhCsNvY=","version":3}

The response contains the updated allow policy:

{"bindings":[{"members":["user:raha@example.com"],"role":"roles/storage.admin"}],"etag":"BwWd8I+ZUAQ=","version":1}

The allow policy in the response uses version1, eventhough the request specified version3, because theallow policy uses only fields that are supported in a version1 allow policy.

Policies with deleted principals

If a role binding in an allow policy includes a deleted principal, and you add arole binding for a new principal with the same name, the role binding is alwaysapplied to the new principal.

For example, consider this allow policy that includes a role binding for adeleted service account,my-service-account@project-id.iam.gserviceaccount.com. As a result, the identifier for eachthe service account has adeleted: prefix:

{"bindings":[{"members":["deleted:serviceAccount:my-service-account@project-id.iam.gserviceaccount.com?uid=123456789012345678901"],"role":"roles/owner"}],"etag":"BwUjMhCsNvY=","version":1}

Suppose you create a new service account that is also namedmy-service-account@project-id.iam.gserviceaccount.com, and you want to grant it the Project Creator role(roles/resourcemanager.projectCreator). To grant the role to the new serviceaccount, update the allow policy as shown in this example:

{"bindings":[{"members":["deleted:serviceAccount:my-service-account@project-id.iam.gserviceaccount.com?uid=123456789012345678901"],"role":"roles/owner"},{"members":["serviceAccount:my-service-account@project-id.iam.gserviceaccount.com"],"role":"roles/resourcemanager.projectCreator"}],"etag":"BwUjMhCsNvY=","version":1}

To make it easier to audit your IAM allow policies, you canalso remove the deleted user from the role binding to the Owner role:

{"bindings":[{"members":["deleted:serviceAccount:my-service-account@project-id.iam.gserviceaccount.com?uid=123456789012345678901"],"role":"roles/owner"},{"members":["user:donald@example.com"],"role":"roles/resourcemanager.projectCreator"}],"etag":"BwUjMhCsNvY=","version":1}
Note: If you remove a deleted principal from a role binding, then undelete theprincipal, the principal is not added back to the role binding.

Policy best practices

The following best practices apply to organizations with many Google Cloudusers:

What's next

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2025-12-09 UTC.