本主题介绍了如何对您的 Identity and Access Management (IAM) 政策执行 lint 请求(进行验证)。
准备工作
阅读 IAM Conditions 概览,了解 IAM Conditions 的基础知识。
了解适用于 IAM 政策的 lint 请求
在 IAM 政策的上下文中,执行 lint 请求是一种检查新政策或现有政策以及确认其是否存在特定问题的方法。这些问题有以下几种可能的类型:
- 建议
- 警告
- 有助于改善政策意图的信息,比如更好的语法和语义
- 导致
setIamPolicy
操作失败的语法或语义错误
对政策执行 lint 请求的功能可用作调试工具,以便为任何失败的 setIamPolicy()
操作提供详细说明。它还可以用作辅助工具,帮助编写 IAM 政策以实现预期结果。
对条件执行 lint 请求
条件表达式往往会变得很复杂,尤其是在需要多个子句和逻辑运算符来适当限制访问权限的情况下。
如果条件表达式包含无效逻辑,或者语法违反了条件表达式的限制,则 setIamPolicy()
操作将失败。此外,虽然条件可以传递有关政策更新的所有严格语法和语义要求,但它可能仍然包含在政策实施期间会导致意外访问结果的结构。此类情况的一些示例如下:
- 使用不推荐的函数
- 使用旧版资源类型或旧版服务名称
- 无效条件,例如不适用的日期或时间范围
对条件执行 lint 请求将进行全面检查,并报告可能在政策更新中发生的失败以及其他有问题的结构。
在尝试设置新的条件角色绑定之前,建议您先对表达式执行 lint 请求。本部分介绍了如何使用 Cloud Console、gcloud
命令行工具或 REST API 来对条件执行 lint 请求。
要对条件表达式执行 lint 请求,请执行以下操作:
控制台
在 Cloud Console 中,转到 IAM 页面。
点击选择项目,然后选择一个项目并点击打开。
从成员列表中找到所需成员,然后点击
按钮。在修改权限面板中,找到想要对其执行 lint 请求的角色。然后在条件下,点击条件的名称。
在修改条件面板中,条件编辑器提供了对表达式执行 lint 请求的功能。条件构建器目前提供有限的执行 lint 请求的功能。
在条件编辑器中,手动添加或修改条件表达式。
通过点击右上方文本框上面的运行 Linter 来验证 CEL 语法。如果语法包含错误,表达式的每一行旁边都会显示一个
图标。如果将指针悬停在该图标上,将会显示该部分表达式的错误消息,并提供一些实用的调试反馈。我们建议您修复错误后再保存条件。 如果条件没有语法错误,但执行 lint 请求的操作发现了有问题的结构,则会显示警告图标 (
)。如果将指针悬停在该图标上,将会显示该部分表达式的警告消息,并提供一些实用的调试反馈。我们强烈建议修复警告后再保存条件,但这并不是强制要求。对条件表达式进行必要的更改。在运行 Linter 触发之后,它将继续在后台执行 lint 请求,以便于修改表达式。
对表达式成功执行 lint 请求后,点击保存以应用该条件。
关闭修改条件面板后,在修改权限面板中再次点击保存,以更新 IAM 政策。
gcloud
执行 gcloud alpha iam policies lint-condition
命令,对给定条件表达式执行 lint 请求。要执行此命令,可以创建包含该条件的文本文件,也可以为条件的标题、说明和表达式指定标志。
在下面的示例中,我们将使用包含该条件的文本文件:
condition.json
{
"condition": {
"title": "1_less_than_2",
"description": "",
"expression": "1 <"
}
}
命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
命令的输出结果包含以下内容:
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.expression
level: CONDITION
locationOffset: 3
severity: ERROR
validationUnitName: LintValidationUnits/ConditionCompileCheck
...
每个 lint 结果都包含一个 debugMessage
,可帮助您找出条件表达式的问题。如果条件编译失败,您可能会看到许多不同的 validationUnitName
类型,其中包含以下 debugMessage
文本:
The validation unit is skipped due to absence of a required object: CheckedExpr
执行必要的更改,以使表达式能够成功编译,然后再次尝试对条件执行 lint 请求。
REST
iamPolicies.lintPolicy
方法可对 IAM 政策中的条件表达式执行 lint 请求或进行验证。
在使用下面的请求数据之前,请先进行以下替换:
-
condition
:表示要 lint 的条件的 Expr 对象。例如:"title": "1_less_than_2", "description": "", "expression": "1 <"
如需了解 Expr 对象的格式,请参阅 Expr 架构参考文档。
HTTP 方法和网址:
POST https://iam.googleapis.com/v1/iamPolicies:lintPolicy
请求 JSON 正文:
{ "condition": { condition } }
如需发送您的请求,请展开以下选项之一:
响应正文包含一个或多个 LintResult 对象,例如:
{ "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" } }
每个 lint 结果都包含一个 debug_message
,可帮助您找出条件表达式的问题。如果条件编译失败,您可能会看到许多不同的 validation_unit_name
类型,其中包含以下 debugMessage
文本:
The validation unit is skipped due to absence of a required object: CheckedExpr
执行必要的更改,以使表达式能够成功编译,然后再次尝试对条件表达式执行 lint 请求。
支持的验证单元
如前所述,验证单元是用于评估表达式有无语法问题的的单个 lint 类型。下表总结了受支持的验证单元,每个验证单元均有预期的执行 lint 请求的级别,lint 请求结果严重级别和简要说明。
验证单元 | Lint 级别 | 严重级别 | 说明 |
---|---|---|---|
ConditionCompileCheck |
CONDITION |
ERROR |
由于 CEL 语法无效,条件表达式包含一个编译错误。 |
ConditionComplexityCheck |
CONDITION |
ERROR |
条件表达式包含的逻辑运算符超过最大值(12 个)。 |
DateTimeCheck |
CONDITION |
WARNING |
由于时间戳格式无效(非 ISO 8601 格式),过期时间戳是过去时间或者开始时间戳是过去时间,条件表达式指定的时间戳比较结果总是 true 或 false。 |
DateTimeRangeCheck |
CONDITION |
WARNING |
值超出预期的高级时间戳函数和比较表达式的范围。请参阅高级时间戳函数的有效值。 |
DrgGetAttributeDefaultValueCheck |
CONDITION |
ERROR |
条件表达式调用 api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', V) ,其中 V 是空列表 [] 以外的任何值。对于此 API 属性,V 必须始终为空列表。 |
EffectiveTimeRangeCheck |
CONDITION |
WARNING |
在更为复杂的时间戳函数和比较用法中,表达式得出空的有效时间范围,因此结果总是 false。或者,时间范围涵盖整个范围,因此结果总是 true。 |
HasOnlyListConstCheck |
CONDITION |
ERROR |
条件表达式调用 hasOnly(List<T>) ,其中 T 类型不是常量类型,例如字符串或整数。hasOnly() 函数仅接受常量列表。 |
HasOnlyListLengthCheck |
CONDITION |
ERROR |
条件表达式调用 hasOnly(List<T>) ,List<T> 包含的元素数量超过 10 个。 |
ResourceServiceLiteralCheck |
CONDITION |
WARNING |
指定的 resource.service 值不受支持。使用此类字符串字面量进行相等性比较的表达式的结果总是 false。 请使用支持的值。 |
ResourceTypeLiteralCheck |
CONDITION |
WARNING |
指定的 resource.type 值不受支持。
使用此类字符串字面量进行相等性比较的表达式结果总是 false。 请使用支持的值。 |
RestrictedAttributesCheck |
CONDITION |
WARNING |
表达式使用的特性目前受限或不受支持。设置条件表达式可能会失败。 请参阅特性列表。 |
执行 lint 请求的示例
本部分提供每个验证单元的执行 lint 请求政策使用示例。
对于每个验证单元,都会提供有问题的输入示例。每个示例均使用 gcloud
命令行工具演示了执行 lint 请求的操作
ConditionCompileCheck
条件表达式示例:
{
"condition": {
"title": "Condition not compiling",
"description": "",
"expression": "true=false"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: |-
ERROR: Parse expression:1:4: token recognition error at: '=f'
| true=false
| ....^
fieldName: condition.expression
level: CONDITION
locationOffset: 4
severity: ERROR
validationUnitName: LintValidationUnits/ConditionCompileCheck
ConditionComplexityCheck
条件表达式示例:
{
"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"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: Logical operators count must not be more than 12
fieldName: condition.expression
level: CONDITION
severity: ERROR
validationUnitName: LintValidationUnits/ConditionComplexityCheck
DateTimeCheck
条件表达式示例:
{
"condition": {
"title": "Condition not compiling",
"description": "",
"expression": "request.time < timestamp('2000-01-01T00:00:00Z')"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: Ineffective date time value 2000-01-01T00:00:00+00:00 parsed
from "2000-01-01T00:00:00Z"; condition is effectively False. Time expired
already.
fieldName: condition.expression
level: CONDITION
locationOffset: 25
severity: WARNING
validationUnitName: LintValidationUnits/DateTimeCheck
DateTimeRangeCheck
条件表达式示例:
{
"condition": {
"title": "Time function out of range",
"description": "",
"expression": "request.time.getMonth() > 13"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: The value being compared to the specified timestamp function
(getMonth) must be in range [0, 11].
fieldName: condition.expression
level: CONDITION
locationOffset: 26
severity: WARNING
validationUnitName: LintValidationUnits/DateTimeRangeCheck
DrgGetAttributeDefaultValueCheck
条件表达式示例:
{
"condition": {
"title": "DRG condition takes non empty list as default value",
"description": "",
"expression":
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', ['roles/viewer']).hasOnly(['roles/editor'])"
}
}
运行命令:
sh
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:yaml
lintResults:
- debugMessage: api.getAttribute call on
'iam.googleapis.com/modifiedGrantsByRole' can only
accept empty list ('[]') as default value.
fieldName: condition.expression
level: CONDITION
locationOffset: 60
severity: ERROR
validationUnitName: LintValidationUnits/DrgGetAttributeDefaultValueCheck
EffectiveTimeRangeCheck
条件表达式示例:
{
"condition": {
"title": "Empty time range",
"description": "",
"expression": "request.time.getMonth() > 5 && request.time.getMonth() < 4"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: The aggregate of time functions [getMonth] results in empty ranges.
fieldName: condition.expression
level: CONDITION
severity: WARNING
validationUnitName: LintValidationUnits/EffectiveTimeRangeCheck
HasOnlyListConstCheck
条件表达式示例:
{
"condition": {
"title": "hasOnly contains more than constant value",
"description": "",
"expression":
"api.getAttribute('somekey', []).hasOnly(['somevalue', resource.name])"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:yaml
lintResults:
- debugMessage: hasOnly() expects an argument of type list containing only const
values, but a non-const expression was found in the list.
fieldName: condition.expression
level: CONDITION
locationOffset: 59
severity: ERROR
validationUnitName: LintValidationUnits/HasOnlyListConstCheck
HasOnlyListLengthCheck
条件表达式示例:
{
"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])"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:yaml
lintResults:
- debugMessage: The list argument to hasOnly() cannot have more than 10 elements
fieldName: condition.expression
level: CONDITION
locationOffset: 39
severity: ERROR
validationUnitName: LintValidationUnits/HasOnlyListLengthCheck
ResourceServiceLiteralCheck
条件表达式示例:
{
"condition": {
"title": "Condition with unsupported resource service string",
"description": "",
"expression": "resource.service == 'resourcemanager'"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: 'resource.service : resourcemanager is not supported. Using this
value in condition may lead to unintended consequences. Check user guide at
https://cloud.google.com/iam/docs/conditions-resource-attributes#resource_service_values
for supported values for resource.service.'
fieldName: condition.expression
level: CONDITION
locationOffset: 20
severity: WARNING
validationUnitName: LintValidationUnits/ResourceServiceLiteralCheck
ResourceTypeLiteralCheck
条件表达式示例:
{
"condition": {
"title": "Condition with legacy resource type",
"description": "",
"expression": "resource.type == 'resourcemanager.projects'"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: 'resource.type : resourcemanager.projects is not supported.
Using this value in condition may lead to unintended consequences. Check
user guide at https://cloud.google.com/iam/docs/conditions-resource-attributes#resource_type_values
for supported values for resource.type.'
fieldName: condition.expression
level: CONDITION
locationOffset: 17
severity: WARNING
validationUnitName: LintValidationUnits/ResourceTypeLiteralCheck
RestrictedAttributesCheck
条件表达式示例:
{
"condition": {
"title": "Condition with restricted attribute",
"description": "",
"expression": "'accessPolicies/123/accesslevels/TRUSTED' in request.auth.access_levels"
}
}
运行命令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 结果:
lintResults:
- debugMessage: Condition attribute `request.auth.access_levels` is restricted
or unsupported. Please check https://cloud.google.com/iam/docs/conditions-overview
for the full list of supported attributes
fieldName: condition.expression
level: CONDITION
locationOffset: 57
severity: WARNING
validationUnitName: LintValidationUnits/RestrictedAttributesCheck