本主題說明如何檢查或驗證身分與存取權管理 (IAM) 允許政策。
事前準備
Enable the IAM API.
請參閱 IAM 條件總覽,瞭解 IAM 條件的基本概念。
必要的角色
如要對資源的允許政策執行 Lint 作業,您需要取得資源的權限,以及取得和設定資源允許政策的權限。這些權限的格式如下,其中 SERVICE
是擁有資源的服務名稱,RESOURCE_TYPE
則是您要管理存取權的資源類型名稱:
SERVICE.RESOURCE_TYPE.get
SERVICE.RESOURCE_TYPE.getIamPolicy
SERVICE.RESOURCE_TYPE.setIamPolicy
舉例來說,如要對專案的允許政策執行 Lint 檢查,您需要下列權限:
resourcemanager.projects.get
resourcemanager.projects.getIamPolicy
resourcemanager.projects.setIamPolicy
如要取得必要權限,請要求管理員授予包含這些權限的預先定義或自訂角色。舉例來說,管理員可以授予您安全管理員角色 (roles/iam.securityAdmin
),讓您有權取得幾乎所有Google Cloud 資源,並管理這些資源的允許政策。
瞭解允許政策的 Linting
就允許政策而言,Linting 是檢查新政策或現有政策,並找出特定問題的方法。這類問題包括下列可能性:
- 建議
- 警告
- 有助於改善允許政策意圖的資訊,例如更完善的語法和語意
- 導致
setIamPolicy
作業失敗的語法或語意錯誤
如果嘗試更新允許政策時發生錯誤,可以對允許政策執行 Lint 作業,找出錯誤原因。您也可以使用 Lint,確保條件式角色繫結能達到預期效果。
檢查條件
條件運算式可能很複雜,尤其是在需要多個子句和邏輯運算子才能適當管理存取權的情況下。如果條件運算式含有無效邏輯,或語法違反條件運算式的限制,您就無法將條件新增至允許政策。
此外,即使條件運算式使用正確的語法,也可能包含語意錯誤,導致允許政策和角色繫結無法正常運作。常見的語意錯誤包括:
- 使用不建議的函式
- 使用舊版資源類型或舊版服務名稱
- 條件無效,例如日期或時間範圍不適用
對條件執行 Lint 時,Lint 工具會檢查條件運算式,並回報任何語法錯誤。此外,也會回報可能導致非預期結果的語意錯誤。
嘗試設定新的條件式角色繫結前,建議您先檢查運算式。本節說明如何使用 Google Cloud 控制台、Google Cloud CLI 或 REST API,對條件運算式執行 Lint 檢查。
如要對條件運算式執行 Lint 檢查,請按照下列步驟操作:
控制台
前往 Google Cloud 控制台的「IAM」(身分與存取權管理) 頁面。
按一下 [選取專案],選擇專案,然後按一下 [開啟]。
在主體清單中找出所需主體,然後按一下「編輯」
按鈕。在「編輯權限」面板中,找出要進行 Lint 檢查的角色。然後在「IAM 條件 (選用)」下方,按一下條件名稱。
在條件編輯器中,手動新增或編輯條件運算式。
如要驗證 CEL 語法,請按一下「執行 Linter」。
如果語法有誤,錯誤行旁邊會顯示
「錯誤」圖示。如要查看各項錯誤的詳細資料,請將指標懸停在圖示上。如果條件使用正確語法,但 Lint 發現可能的問題,有問題的行旁會顯示
「警告」圖示。如要查看每項警告的詳細資料,請將指標懸停在圖示上。視需要變更條件運算式。按一下「執行 Linter」後,系統就會在背景自動執行 Linter,方便您編輯運算式。
你必須先修正所有錯誤,才能儲存條件運算式。我們強烈建議您修正所有警告。
如果沒有錯誤或警告,請按一下「儲存」套用條件。
關閉「編輯條件」面板後,再次按一下「編輯權限」面板中的「儲存」,即可更新允許政策。
gcloud
執行 gcloud alpha iam policies lint-condition
指令,對指定條件運算式執行 Lint 檢查。如要執行這項指令,您可以建立包含條件的文字檔,或是指定條件標題、說明和運算式的旗標。
以下範例使用包含下列條件的文字檔:
condition.json
{
"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
請進行變更,讓運算式能夠編譯,然後再次檢查條件。
REST
iamPolicies.lintPolicy
方法會檢查或驗證允許政策中的條件運算式。
使用任何要求資料之前,請先替換以下項目:
-
condition
:代表要檢查的條件的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 層級 | 嚴重性 | 說明 |
---|---|---|---|
ConditionCompileCheck |
CONDITION |
ERROR |
條件運算式含有編譯錯誤,原因是 CEL 語法無效。 |
ConditionComplexityCheck |
CONDITION |
ERROR |
條件運算式包含超過 12 個邏輯運算子。 |
DateTimeCheck |
CONDITION |
WARNING |
條件運算式指定的時間戳記比較一律會評估為 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 |
運算式使用的屬性受到限制或不支援。 設定條件運算式可能無法成功。請參閱屬性清單。 |
Linting 範例
本節會舉例說明導致各驗證單元回報問題的條件。每個範例都會示範如何使用 Google Cloud CLI 執行 Lint 檢查。
沒有驗證問題
條件範例:
{
"title": "1_less_than_2",
"description": "",
"expression": "1 < 2"
}
執行下列指令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 結果:
{}
ConditionCompileCheck
條件範例:
{
"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
條件範例:
{
"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
條件範例:
{
"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
條件範例:
{
"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
條件範例:
{
"title": "DRG condition takes non empty list as default value",
"description": "",
"expression":
"api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', ['roles/viewer']).hasOnly(['roles/editor'])"
}
執行下列指令:
gcloud alpha iam policies lint-condition --condition-from-file="condition.json"
Lint 結果:
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
條件範例:
{
"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
條件範例:
{
"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 結果:
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
條件範例:
{
"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 結果:
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
條件範例:
{
"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
條件範例:
{
"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
條件範例:
{
"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