Set limits on granting roles

In large organizations, it can be helpful to let teams independently manage theallow policies for their resources. However, letting a principal grant or revokeall IAM roles can greatly increase your security risk.

You can set limits on the roles that a principal can grant and revoke withIdentity and Access Management (IAM) Conditions and theiam.googleapis.com/modifiedGrantsByRole API attribute. These limits let youcreate limited IAM admins who can manage their own team's allowpolicies, but only within the boundaries that you have set.

Before you begin

Required permissions

To get the permissions that you need to create limited IAM admins for a project,folder, or organization, ask your administrator to grant you the following IAM roles on the resource that you want to create a limitedIAM admin for (project, folder, or organization):

  • To create a limited IAM admin for a project:Project IAM Admin (roles/resourcemanager.projectIamAdmin)
  • To create a limited IAM admin for a folder:Folder Admin (roles/resourcemanager.folderAdmin)
  • To create a limited IAM admin for a project, folder, or organization:Organization Admin (roles/resourcemanager.organizationAdmin)

For more information about granting roles, seeManage access to projects, folders, and organizations.

These predefined roles contain the permissions required to create limited IAM admins for a project,folder, or organization. To see the exact permissions that are required, expand theRequired permissions section:

Required permissions

The following permissions are required to create limited IAM admins for a project,folder, or organization:

  • To create a limited IAM admin for a project:
    • resourcemanager.projects.getIamPolicy
    • resourcemanager.projects.setIamPolicy
  • To create a limited IAM admin for a folder:
    • resourcemanager.folders.getIamPolicy
    • resourcemanager.folders.setIamPolicy
  • To create a limited IAM admin for an organization:
    • resourcemanager.organizations.getIamPolicy
    • resourcemanager.organizations.setIamPolicy

You might also be able to get these permissions withcustom roles or otherpredefined roles.

Common use cases

The following sections describe how you can use limited role granting toenable self-service management of allow policies.

Create limited IAM admins

Consider a scenario where you want to let a user, Noam, actas a limited IAM admin for your project. You want Noam to be ableto grant and revoke only the App Engine Admin (roles/appengine.appAdmin) andApp Engine Viewer (roles/appengine.appViewer) roles for your project.

To grant this limited ability, you conditionally grant Noam the Project IAMAdmin role (roles/resourcemanager.projectIamAdmin). The Project IAM Admin roleallows Noam to grant and revoke IAM roles, and the conditionlimits which roles Noam can grant and revoke:

{"version":3,"etag":"BwWKmjvelug=","bindings":[{"members":["user:owner@example.com"],"role":"roles/owner"},{"members":["user:noam@example.com"],"role":"roles/resourcemanager.projectIamAdmin","condition":{"title":"only_appengine_admin_viewer_roles","description":"Only allows changes to role bindings with the App Engine Admin or Viewer roles","expression":"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/appengine.appAdmin', 'roles/appengine.appViewer'])"}}]}

This conditional role binding lets Noam do the following:

  • Grant the App Engine Admin and App Engine Viewer roles for the project.
  • Revoke the App Engine Admin and App Engine Viewer roles for the project.
  • Add, remove, or modify conditions for project-level role bindings that grantthe App Engine Admin and App Engine Viewer roles.
  • Perform other actions allowed by the Project IAM Admin role that don'tmodify the project's allow policy. For example, Noam could use theprojects.getIamPolicy method to get the project's allowpolicy.

This conditional role binding does not let Noam do any of the following:

  • Modify allow policies for resources other than the project.
  • Grant roles other than the App Engine Admin or App Engine Viewer roles.
  • Revoke roles other than the App Engine Admin or App Engine Viewer roles.
  • Add, remove, or modify conditions for role bindings that don't grantthe App Engine Admin or App Engine Viewer roles.

Allow users to manage limited IAM admins

Consider a scenario where you want to make a user, Lila, a limitedIAM admin for her team. You want Lila to be able to grant andrevoke only the Compute Admin role (roles/compute.admin) for her project.However, you also want to let Lila select other users to act as limitedIAM admins. In other words, you want to let Lila allow otherusers to grant and revoke only the Compute Admin role.

You might think that the solution is to grant Lila the Project IAM Admin role(roles/resourcemanager.projectIamAdmin), and then give her the ability togrant or revoke that role for others. However, if you grant Lila the Project IAMAdmin role, she could remove the condition from her own role and give herselfthe ability to grant or revoke any IAM role.

To help prevent this privilege escalation, you insteadcreate a Google group,iam-compute-admins, forthe project's limited IAM admins. Then, youadd Lila to the group andmake her a group manager.

After you create the group, you conditionally grant the group the Project IAMAdmin role (roles/resourcemanager.projectIamAdmin). The Project IAM Admin roleallows group members to grant and revoke IAM roles, and thecondition limits which roles they can grant and revoke:

{"version":3,"etag":"BwWKmjvelug=","bindings":[{"members":["user:owner@example.com"],"role":"roles/owner"},{"members":["group:iam-compute-admins@example.com"],"role":"roles/resourcemanager.projectIamAdmin","condition":{"title":"only_compute_admin_role","description":"Only allows changes to role bindings for the Compute Admin role","expression":"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/compute.admin'])"}}]}

As amember of theiam-compute-admins group, Lila can do thefollowing:

  • Grant the Compute Admin role for the project by adding a newbinding for the role, or by adding a principal to an existing binding for therole.
  • Revoke the Compute Admin role by removing an existing bindingfor the role, or by removing a principal from an existing binding for therole.
  • Modify grants for the Compute Admin role by adding, removing,or modifying conditions attached to bindings for the role.
  • Perform other actions allowed by the Project IAM Admin role that don't modifythe project's allow policy. For example, she could use theprojects.getIamPolicy method to get the project's allowpolicy.

As amanager of theiam-compute-admins group, Lila can allowother users to grant or revoke the Compute Admin role by adding them to theiam-compute-admins group.

Lila cannot do the following:

  • Give herself the ability to grant or revoke other roles.
  • Modify allow policies for resources other than the project.
  • Grant roles other than the Compute Admin role.
  • Revoke roles other than the Compute Admin role.
  • Add, remove, or modify conditions for role bindings that don't grantthe Compute Admin role.

Limit role granting

The following sections explain how to let principals grant or revoke onlycertain roles.

Caution: Some Google Cloud services don't recognize limits on role granting. If a limited IAM admin tries to grant a role on a resource, and the resource's service does not recognize limits on role granting, then the request fails. For a list of services that recognize limits on role granting, see IAM API attributes.

The exception to this behavior is BigQuery datasets. Datasets don't recognize themodifiedGrantsByRole attribute, but limited IAM admins can still grant or revoke roles on datasets. Specifically, if a limited IAM admin's role includes permissions to grant roles on datasets,they can do so, regardless of any limits placed on their role granting.

Write a condition expression to limit role granting

To limit a principal's ability to grant roles, write a condition expression thatspecifies the roles a principal can grant or revoke.

Use the following format for your condition expression:

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(roles)

This expression does the following:

To customize this expression, replaceroles with a listof the roles that the principal is allowed to grant or revoke. For example, tolet the principal grant or revoke only the Pub/Sub Editor(roles/pubsub.editor) and Pub/Sub Publisher (roles/pubsub.publisher) roles,use the value['roles/pubsub.editor', 'roles/pubsub.publisher'].

You can include up to 10 values in the list of allowedroles. All of these values must be string constants.

Note: You cannot customize the default value forapi.getAttribute functionsinvolvingiam.googleapis.com/modifiedGrantsByRole. It must be an empty list.

Warning: Don't include the following types of roles in the list of allowed roles:

Both of these types of roles contain, or could contain, permission to modify allow policies. As a result, limited IAM admins who can grant and revoke these types of roles can give themselves permission to grant and revoke all IAM roles.

For example, if a user is a limited IAM admin for a project, and you let them grant or revoke a custom role that they can modify, they could add theresourcemanager.projects.setIamPolicy permission to the custom role, then grant themselves that role unconditionally. They would then be able to grant and revoke all IAM roles for the project.

Logical operators forhasOnly() statements

Don't use the&& or|| operators to join multiplehasOnly() statements ina single condition. If you do, then requests that grant or revoke multiple rolesmight fail, even if the principal can grant or revoke those roles individually.

For example, consider the following condition:

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', [])    .hasOnly(['roles/pubsub.editor']) ||api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', [])    .hasOnly(['roles/pubsub.publisher'])

This condition evaluates totrue if a request grants either theroles/pubsub.editor role or theroles/pubsub.publisher role, but itevaluates tofalse if a request grantsboth theroles/pubsub.editor roleand theroles/pubsub.publisher role.

Limit role granting with conditional role bindings

To allow a principal to grant or revoke only certain roles, use the conditionexpression from the preceding section to create a conditional role binding.Then, add the conditional role binding to a resource's allow policy.

Note: Conditional role bindings do not override role bindings with no conditions. If a principal is bound to a role, and the role binding does not have a condition, then the principal always has that role. Adding the principal to a conditional binding for the same role has no effect.

  1. Select a resource that represents the scope that you want to let a principalgrant and revoke roles for:

    Note: While other resource typesrecognize limits on rolegranting, only projects, folders, and organizationsaccept conditions to limit role granting in their allow policies.
  2. Select a role that allows a principal to set the allow policy for theresource type you selected (project, folder, or organization). To follow theprinciple of least privilege, choose one of the following predefined roles:

    Alternatively, choose a custom role that includes theresourcemanager.resource-type.setIamPolicy andresourcemanager.resource-type.getIamPolicypermissions, whereresource-type isproject,folder, ororganization.

    Note: You can also select a role that allows a principal to set the allowpolicy for specific resources within a project, folder, or organization. Forexample, you could select the Storage Admin role, which includes permissionsto set allow policies for buckets and objects. However, if you do so, theprincipal will also be able to use the other permissions included in the role.
  3. Conditionally grant a principal your chosen role on the project, folder, ororganization you selected.

    The new allow policy is applied, and your principal can modify bindings foronly the roles you have allowed.

    Console

    1. In the Google Cloud console, go to theIAM page.

      Go to the IAM page

    2. Make sure the name of your project, folder, or organization appears inthe resource selector at the top of the page. The resource selector tellsyou what project, folder, or organization you are currently working in.

      If you don't see the name of your resource, click the resource selector,then select your resource.

    3. In the list of principals, locate the principal that will grant andrevoke roles, and click the button.

    4. In theEdit permissions panel, select the role you chosepreviously. Then underIAM condition (optional), clickAdd IAMcondition.

    5. In theEdit condition panel, enter a title and optional descriptionfor the condition.

    6. Click theCondition editor tab and enter the expression you wrote inWriting a condition expression to limit role granting.This expression limits which roles the principal can grant or revoke.

      For example, the following condition expression limits the principal togranting and revoking the Pub/Sub Editor (roles/pubsub.editor) andPub/Sub Publisher (roles/pubsub.publisher) roles:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      Warning: Don't include the following types of roles in the list of allowed roles:

      • Roles with permissions to grant and revoke IAM roles (that is, roles with permission names that end insetIamPolicy).
      • Custom roles that the limited IAM admin can modify. For example, if the limited IAM admin also has the Role Administrator role (roles/iam.roleAdmin) on a project, don't allow them to grant or revoke project-level custom roles.

      Limited IAM admins who can grant and revoke these types of roles can give themselves permission to grant and revoke all IAM roles. SeeWriting a condition expression to limit role granting for more information.

    7. ClickSave to apply the condition.

    8. After theEdit condition panel is closed, clickSave in theEdit permissions panel to update your allow policy.

    gcloud

    Allow policies are set using theread-modify-writepattern.

    First, read the allow policy for the resource:

    Execute theget-iam-policy command.This command gets the current allow policy for the resource.

    Command:

    gcloudresource-typeget-iam-policyresource-id--format=json>path

    Replace the following values:

    • resource-type: The resource type that you want tolet a principal grant or revoke roles for. Use one of the following:projects,resource-manager folders, ororganizations.
    • resource-id: Your Google Cloud project,folder, or organization ID.
    • path: The path of the file to download the allowpolicy to.

    The allow policy is saved in JSON format, for example:

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

    Next, modify the allow policy.

    To let a principal only modify bindings for certain roles, add thehighlighted conditional role binding:

    {"bindings":[{"members":["user:owner@example.com"],"role":"roles/owner"},{"members":["principal"],"role":"role","condition":{"title":"title","description":"description","expression":"expression"}}],"etag":"BwWKmjvelug=","version":3}

    Replace the following values:

    • principal: The principal that will grant or revokecertain roles. For example,user:my-user@example.com. To see the formats of eachprincipal type, seePrincipal identifiers.
    • role: The role you chose in the preceding steps.This role must include thesetIamPolicy permission for the resource typeyou chose.
    • title: A string briefly describing the condition.For example,only_pubsub_roles.
    • description: Optional. An additional descriptionfor the condition. For example,Only allows granting/revoking the Pub/Subeditor and publisher roles.
    • expression: The expression you wrote inWriting a condition expression to limit role granting.This expression limits which roles that the principal can grant or revoke.

      For example, the following condition expression limits the principal togranting and revoking the Pub/Sub Editor (roles/pubsub.editor) andPub/Sub Publisher (roles/pubsub.publisher) roles:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      Warning: Don't include the following types of roles in the list of allowed roles:

      • Roles with permissions to grant and revoke IAM roles (that is, roles with permission names that end insetIamPolicy).
      • Custom roles that the limited IAM admin can modify. For example, if the limited IAM admin also has the Role Administrator role (roles/iam.roleAdmin) on a project, don't allow them to grant or revoke project-level custom roles.

      Limited IAM admins who can grant and revoke these types of roles can give themselves permission to grant and revoke all IAM roles. SeeWriting a condition expression to limit role granting for more information.

    Finally, write the updated allow policy:

    Set the new allow policy by executing theset-iam-policy command forthe resource:

    gcloudresource-typeset-iam-policyresource-idpath

    Replace the following values:

    • resource-type: The resource type that you want tolet a principal grant or revoke roles for. Use one of the following:projects,resource-manager folders, ororganizations.
    • resource-id: Your Google Cloud project,folder, or organization ID.
    • path: A path to the file containing the updatedallow policy.

    The new allow policy is applied, and the principal will be able to modifybindings for only the roles you have allowed.

    REST

    Allow policies are set using theread-modify-writepattern.

    First, read the allow policy for the resource:

    The Resource Manager API'sgetIamPolicy method gets a project's, folder's, or organization's allow policy.

    Before using any of the request data, make the following replacements:

    • API_VERSION: The API version to use. Forprojects and organizations, usev1. For folders, usev2.
    • RESOURCE_TYPE: The resource type whosepolicy you want to manage. Use the valueprojects,folders, ororganizations.
    • RESOURCE_ID: Your Google Cloudproject, organization, or folder ID. Project IDs are alphanumeric strings, likemy-project. Folder and organization IDs are numeric, like123456789012.
    • POLICY_VERSION: The policy version to bereturned. Requests should specify the most recent policy version, which is policy version3. SeeSpecifyinga policy version when getting a policy for details.

    HTTP method and URL:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy

    Request JSON body:

    {  "options": {    "requestedPolicyVersion":POLICY_VERSION  }}

    To send your request, expand one of these options:

    curl (Linux, macOS, or Cloud Shell)

    Note: The following command assumes that you have logged in to thegcloud CLI with your user account by runninggcloud init orgcloud auth login , or by usingCloud Shell, which automatically logs you into thegcloud CLI . You can check the currently active account by runninggcloud auth list.

    Save the request body in a file namedrequest.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy"

    PowerShell (Windows)

    Note: The following command assumes that you have logged in to thegcloud CLI with your user account by runninggcloud init orgcloud auth login . You can check the currently active account by runninggcloud auth list.

    Save the request body in a file namedrequest.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy" | Select-Object -Expand Content

    APIs Explorer (browser)

    Copy the request body and open themethod reference page. The APIs Explorer panel opens on the right side of the page. You can interact with this tool to send requests. Paste the request body in this tool, complete any other required fields, and clickExecute.

    The response contains the resource's allow policy. For example:

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

    Next, modify the allow policy.

    Add a conditional role binding that lets a principal grant and revoke onlycertain roles. Make sure to change theversion field to the value3:

    {"version":3,"etag":"BwWKmjvelug=","bindings":[{"members":["user:owner@example.com"],"role":"roles/owner"},{"members":["PRINCIPAL"],"role":"ROLE","condition":{"title":"TITLE","description":"DESCRIPTION","expression":"EXPRESSION"}}]}
    • PRINCIPAL: The principal that will grant or revokecertain roles. For example,user:my-user@example.com. To see the formats of eachprincipal type, seePrincipal identifiers.
    • ROLE: The role you chose in the preceding steps.This role must include thesetIamPolicy permission for the resource typeyou chose.
    • TITLE: A string briefly describing the condition.For example,only_pubsub_roles.
    • DESCRIPTION: Optional. An additional descriptionfor the condition. For example,Only allows granting/revoking the Pub/Subeditor and publisher roles.
    • EXPRESSION: The expression you wrote inWriting a condition expression to limit role granting.This expression limits which roles that the principal can grant or revoke.

      For example, the following condition expression limits the principal togranting and revoking the Pub/Sub Editor (roles/pubsub.editor) andPub/Sub Publisher (roles/pubsub.publisher) roles:

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      Warning: Don't include the following types of roles in the list of allowed roles:

      • Roles with permissions to grant and revoke IAM roles (that is, roles with permission names that end insetIamPolicy).
      • Custom roles that the limited IAM admin can modify. For example, if the limited IAM admin also has the Role Administrator role (roles/iam.roleAdmin) on a project, don't allow them to grant or revoke project-level custom roles.

      Limited IAM admins who can grant and revoke these types of roles can give themselves permission to grant and revoke all IAM roles. SeeWriting a condition expression to limit role granting for more information.

    Finally, write the updated allow policy:

    The Resource Manager API'ssetIamPolicy method sets the allow policy in the request as the new allow policy for the project, folder, or organization.

    Before using any of the request data, make the following replacements:

    • API_VERSION: The API version to use. Forprojects and organizations, usev1. For folders, usev2.
    • RESOURCE_TYPE: The resource type whosepolicy you want to manage. Use the valueprojects,folders, ororganizations.
    • RESOURCE_ID: Your Google Cloudproject, organization, or folder ID. Project IDs are alphanumeric strings, likemy-project. Folder and organization IDs are numeric, like123456789012.
    • POLICY: A JSON representation of the policy that youwant to set. For more information about the format of a policy, see thePolicy reference.

      For example, to set the policy shown in the previous step, replacePOLICY with the following:

      {"version":3,"etag":"BwWKmjvelug=","bindings":[{"members":["user:owner@example.com"],"role":"roles/owner"},{"members":["principal"],"role":"role","condition":{"title":"title","description":"description","expression":"expression"}}]}

    HTTP method and URL:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy

    Request JSON body:

    {  "policy":POLICY}

    To send your request, expand one of these options:

    curl (Linux, macOS, or Cloud Shell)

    Note: The following command assumes that you have logged in to thegcloud CLI with your user account by runninggcloud init orgcloud auth login , or by usingCloud Shell, which automatically logs you into thegcloud CLI . You can check the currently active account by runninggcloud auth list.

    Save the request body in a file namedrequest.json, and execute the following command:

    curl -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy"

    PowerShell (Windows)

    Note: The following command assumes that you have logged in to thegcloud CLI with your user account by runninggcloud init orgcloud auth login . You can check the currently active account by runninggcloud auth list.

    Save the request body in a file namedrequest.json, and execute the following command:

    $cred = gcloud auth print-access-token
    $headers = @{ "Authorization" = "Bearer $cred" }

    Invoke-WebRequest `
    -Method POST `
    -Headers $headers `
    -ContentType: "application/json; charset=utf-8" `
    -InFile request.json `
    -Uri "https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy" | Select-Object -Expand Content

    APIs Explorer (browser)

    Copy the request body and open themethod reference page. The APIs Explorer panel opens on the right side of the page. You can interact with this tool to send requests. Paste the request body in this tool, complete any other required fields, and clickExecute.

    The response contains the updated allow policy.

    Note: If you treat policies as code and store them in a version-control system, you should store the policy that is returned, not the policy that you sent in the request.

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-15 UTC.