Linting policies Stay organized with collections Save and categorize content based on your preferences.
Alpha This feature is subject to the "Pre-GA Offerings Terms" in the General Service Terms section of theService Specific Terms. Pre-GA features are available "as is" and might have limited support. For more information, see thelaunch stage descriptions.
This topic describes how tolint, or validate, your Identity and Access Management (IAM)allow policies.
Before you begin
Enable the IAM API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission.Learn how to grant roles.Read theIAM Conditions overview tounderstand the basics of IAM Conditions.
lintPolicy only supportslinting operations on thegoogle.iam.v1.Binding.condition field.Required roles
To lint a resource's allow policy, you need permissions to get the resource, andto get and set the allow policy for the resource. These permissions have thefollowing form, whereSERVICE is the name of the servicethat owns the resource andRESOURCE_TYPE is the name ofthe resource type that you want to manage access to:
SERVICE.RESOURCE_TYPE.getSERVICE.RESOURCE_TYPE.getIamPolicySERVICE.RESOURCE_TYPE.setIamPolicy
For example, to lint a project's allow policy, you need the followingpermissions:
resourcemanager.projects.getresourcemanager.projects.getIamPolicyresourcemanager.projects.setIamPolicy
To gain the required permissions, ask your administrator to grant you apredefined or custom role that includes the permissions. For example, youradministrator could grant you the Security Admin role(roles/iam.securityAdmin), which includes permissions to get almost allGoogle Cloud resources and manage their allow policies.
Understanding linting for allow policies
In the context of allow policies, linting is a method of examining a new orexisting allow policy and checking it for specific issues. These issues includethe following range of possibilities:
- Suggestions
- Warnings
- Information that can help improve the intent of the allow policy, such asbetter syntax and semantics
- Syntax or semantic errors that cause
setIamPolicyoperations to fail
If you try to update an allow policy, and you get an error, linting the allowpolicy can help you find the cause of the error. You can also use the linter tohelp ensure that a conditional role binding has the intended effect.
Linting a condition
Condition expressions can be complex, especially in scenarios that requiremultiple clauses and logic operators to appropriately manage access. If acondition expression contains invalid logic, or if the syntax violates therestrictions of a condition expression, you cannot add the condition to an allowpolicy.
Also, even if a condition expression uses the correct syntax, it might containsemantic errors, which can prevent your allow policies and role bindings fromworking as expected. Common semantic errors include the following:
- Use of unrecommended functions
- Use of legacy resource types or legacy service names
- Ineffective conditions, such as an inapplicable date or time range
When you lint a condition, the linter inspects the condition expression andreports any syntax errors. It also reports possible semantic errors that couldcause unexpected results.
Before attempting to set a new conditional role binding, you are encouraged tolint the expression first. This section shows you how to lint a conditionexpression using the Google Cloud console, Google Cloud CLI, or theREST API.
To lint a condition expression:
Console
In the Google Cloud console, go to theIAM page.
ClickSelect a project, choose a project, and clickOpen.
From the list of principals, locate the desired principal and click theEdit button.
From theEdit permissions panel, locate the desired role that you wantto lint. Then underIAM condition (optional), click the name of thecondition.
In theCondition editor, manually add or edit a condition expression.
To validate the CEL syntax, clickRun Linter.
If the syntax contains errors, anError icon appears next to theincorrect line. To see details about each error, hold the pointer over theicon.
If the condition uses the correct syntax, but the linter finds a possibleissue, aWarning iconappears next to the line with the issue. To see details about each warning,hold the pointer over the icon.
Make any necessary changes to the condition expression. After you clickRunLinter, the linter runs automatically in the background while you edit theexpression.
You must correct all errors before you save the condition expression. Westrongly encourage you to fix all warnings as well.
When there are no errors or warnings, clickSave to apply the condition.
Once theEdit condition panel is closed, clickSave again fromtheEdit permissions panel to update your allow policy.
gcloud
Execute thegcloud alpha iam policies lint-conditioncommand to lint a given condition expression. To execute this command, youcan either create a text file that contains the condition, or specifyflags for the condition's title, description, and expression.
The following example uses a text file that contains the following condition:
condition.json
{"title":"1_less_than_2","description":"","expression":"1 <"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"The output from the command contains the following:
lintResults:-debugMessage:|-ERROR: Parse expression:1:3: mismatched input '<EOF>' expecting {'[', '{', '(', '.', '-', '!', 'true', 'false', 'null', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}| 1>| ...^fieldName:condition.expressionlevel:CONDITIONlocationOffset:3severity:ERRORvalidationUnitName:LintValidationUnits/ConditionCompileCheck...Each of the lint results contain adebugMessage that can be used to helplocate the problem with the condition expression. If the condition failed tocompile, you may see many differentvalidationUnitName types with thefollowingdebugMessage text:
The validation unit is skipped due to absence of a required object: CheckedExprMake changes so that the expression compiles, then lint the condition again.
REST
TheiamPolicies.lintPolicy method lints, or validates, a condition expression in an allow policy.
Before using any of the request data, make the following replacements:
condition: AnExprobject representing the condition to lint. For example:"title":"1_less_than_2","description":"","expression":"1 <"
To learn about the format of an
Exprobject, see theExprschema reference.
HTTP method and URL:
POST https://iam.googleapis.com/v1/iamPolicies:lintPolicy
Request JSON body:
{ "condition": {condition }}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://iam.googleapis.com/v1/iamPolicies:lintPolicy"
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://iam.googleapis.com/v1/iamPolicies:lintPolicy" | 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 body contains one or moreLintResult objects, such as the following:
{ "lint_results": { "level": "CONDITION", "validation_unit_name": "LintValidationUnits/ConditionCompileCheck", "severity": "ERROR", "field_name": "condition.expression", "location_offset": "2", "debug_message": "ERROR: Parse expression:1:2: mismatched input \'<EOF>\' expecting {\'[\', \'{\', \'(\', \'.\', \'-\', \'!\', \'true\', \'false\', \'null\', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n | 1<\n | ..^" }, "lint_results": { "level": "CONDITION", "validation_unit_name": "LintValidationUnits/ConditionComplexityCheck", "severity": "NOTICE", "field_name": "condition.expression", "debug_message": "The validation unit is skipped due to absence of a required object: CheckedExpr" }}Each of the lint results contain adebug_message that can be used to helplocate the problem with the condition expression. If the condition failed tocompile, you may see many differentvalidation_unit_name types withthe followingdebugMessage text:
The validation unit is skipped due to absence of a required object: CheckedExprMake changes so that the expression compiles, then lint the condition again.
Supported validation units
As described previously, a validation unit is an individual lint type thatevaluates the expression for syntactic issues. The table below summarizessupported validation units, each with intended linting level, linting resultseverity, and a brief description.
| Validation unit | Lint level | Severity | Description |
|---|---|---|---|
ConditionCompileCheck | CONDITION | ERROR | The condition expression contains a compilation error as a result of invalid CEL syntax. |
ConditionComplexityCheck | CONDITION | ERROR | The condition expression contains more than the maximum of 12 logic operators. |
DateTimeCheck | CONDITION | WARNING | The condition expression specifies a timestamp comparison that always evaluates to either true or false, due to one of these issues:
|
DateTimeRangeCheck | CONDITION | WARNING | Value out of range for the intended advanced timestamp function and the comparison expression. See thevalid values for advanced timestamp functions. |
DrgGetAttributeDefaultValueCheck | CONDITION | ERROR | The condition expression callsapi.getAttribute('iam.googleapis.com/modifiedGrantsByRole',V), whereV is any value other than an empty list,[]. For this API attribute,V must always be an empty list. |
EffectiveTimeRangeCheck | CONDITION | WARNING | In a more complex usage of timestamp functions and comparison, the expression results in an empty effective time range, and is therefore effectively false. Alternatively, the time range covers a full range, and is therefore effectively true. |
HasOnlyListConstCheck | CONDITION | ERROR | The condition expression callshasOnly(List<T>), where the typeT is not a constant type, such as a string or integer. ThehasOnly() function accepts only a list of constants. |
HasOnlyListLengthCheck | CONDITION | ERROR | The condition expression callshasOnly(List<T>), andList<T> contains more than the maximum of 10 elements. |
ResourceServiceLiteralCheck | CONDITION | WARNING | The specifiedresource.service value is not supported. The expression using such string literal for equality comparison is effectively false. Use asupported value. |
ResourceTypeLiteralCheck | CONDITION | WARNING | The specifiedresource.type value is not supported. The expression using such string literal for equality comparison is effectively false. Use asupported value. |
RestrictedAttributesCheck | CONDITION | WARNING | The expression uses an attribute that is restricted or not supported. Setting the condition expression might not succeed. See thelist of attributes. |
Linting examples
This section shows examples of conditions that cause each validation unit toreport issues. Each example demonstrates linting by using the Google Cloud CLI.
No validation issues
Example condition:
{"title":"1_less_than_2","description":"","expression":"1 < 2"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
{}ConditionCompileCheck
Example condition:
{"title":"Condition not compiling","description":"","expression":"true=false"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:|-ERROR: Parse expression:1:4: token recognition error at: '=f'| true=false| ....^fieldName:condition.expressionlevel:CONDITIONlocationOffset:4severity:ERRORvalidationUnitName:LintValidationUnits/ConditionCompileCheckConditionComplexityCheck
Example condition:
{"title":"Condition not compiling","description":"","expression":"1<2 || 2<3 || 3<4 || 4<5 || 5<6 || 6<7 || 7<8 || 8<9 || 9<10 || 10<11 || 11<12 || 12<13 || 13<14 || 14<15"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:Logical operators count must not be more than 12fieldName:condition.expressionlevel:CONDITIONseverity:ERRORvalidationUnitName:LintValidationUnits/ConditionComplexityCheckDateTimeCheck
Example condition:
{"title":"Condition not compiling","description":"","expression":"request.time < timestamp('2000-01-01T00:00:00Z')"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:Ineffective date time value 2000-01-01T00:00:00+00:00 parsedfrom "2000-01-01T00:00:00Z"; condition is effectively False. Time expiredalready.fieldName:condition.expressionlevel:CONDITIONlocationOffset:25severity:WARNINGvalidationUnitName:LintValidationUnits/DateTimeCheckDateTimeRangeCheck
Example condition:
{"title":"Time function out of range","description":"","expression":"request.time.getMonth() > 13"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:The value being compared to the specified timestamp function(getMonth) must be in range [0, 11].fieldName:condition.expressionlevel:CONDITIONlocationOffset:26severity:WARNINGvalidationUnitName:LintValidationUnits/DateTimeRangeCheckDrgGetAttributeDefaultValueCheck
Example condition:
{"title":"DRG condition takes non empty list as default value","description":"","expression":"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', ['roles/viewer']).hasOnly(['roles/editor'])"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:api.getAttribute call on'iam.googleapis.com/modifiedGrantsByRole' can onlyaccept empty list ('[]') as default value.fieldName:condition.expressionlevel:CONDITIONlocationOffset:60severity:ERRORvalidationUnitName:LintValidationUnits/DrgGetAttributeDefaultValueCheckEffectiveTimeRangeCheck
Example condition:
{"title":"Empty time range","description":"","expression":"request.time.getMonth() > 5 && request.time.getMonth() < 4"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:The aggregate of time functions [getMonth] results in empty ranges.fieldName:condition.expressionlevel:CONDITIONseverity:WARNINGvalidationUnitName:LintValidationUnits/EffectiveTimeRangeCheckHasOnlyListConstCheck
Example condition:
{"title":"hasOnly contains more than constant value","description":"","expression":"api.getAttribute('somekey', []).hasOnly(['somevalue', resource.name])"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:hasOnly() expects an argument of type list containing only constvalues, but a non-const expression was found in the list.fieldName:condition.expressionlevel:CONDITIONlocationOffset:59severity:ERRORvalidationUnitName:LintValidationUnits/HasOnlyListConstCheckHasOnlyListLengthCheck
Example condition:
{"title":"hasOnly contains more than 10 elements","description":"","expression":"api.getAttribute('somekey', []).hasOnly([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:The list argument to hasOnly() cannot have more than 10 elementsfieldName:condition.expressionlevel:CONDITIONlocationOffset:39severity:ERRORvalidationUnitName:LintValidationUnits/HasOnlyListLengthCheckResourceServiceLiteralCheck
Example condition:
{"title":"Condition with unsupported resource service string","description":"","expression":"resource.service == 'resourcemanager'"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:'resource.service:resourcemanagerisnotsupported.Usingthisvalueinconditionmayleadtounintendedconsequences.Checkuserguideathttps://cloud.google.com/iam/docs/conditions-resource-attributes#resource_service_valuesforsupportedvaluesforresource.service.'fieldName:condition.expressionlevel:CONDITIONlocationOffset:20severity:WARNINGvalidationUnitName:LintValidationUnits/ResourceServiceLiteralCheckResourceTypeLiteralCheck
Example condition:
{"title":"Condition with legacy resource type","description":"","expression":"resource.type == 'resourcemanager.projects'"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:'resource.type:resourcemanager.projectsisnotsupported.Usingthisvalueinconditionmayleadtounintendedconsequences.Checkuserguideathttps://cloud.google.com/iam/docs/conditions-resource-attributes#resource_type_valuesforsupportedvaluesforresource.type.'fieldName:condition.expressionlevel:CONDITIONlocationOffset:17severity:WARNINGvalidationUnitName:LintValidationUnits/ResourceTypeLiteralCheckRestrictedAttributesCheck
Example condition:
{"title":"Condition with restricted attribute","description":"","expression":"'accessPolicies/123/accesslevels/TRUSTED' in request.auth.access_levels"}Run command:
gcloudalphaiampolicieslint-condition--condition-from-file="condition.json"Lint result:
lintResults:-debugMessage:Condition attribute `request.auth.access_levels` is restrictedor unsupported. Please check https://cloud.google.com/iam/docs/conditions-overviewfor the full list of supported attributesfieldName:condition.expressionlevel:CONDITIONlocationOffset:57severity:WARNINGvalidationUnitName:LintValidationUnits/RestrictedAttributesCheckExcept 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.