ポリシーの lint チェック

このトピックでは、Identity and Access Management(IAM)ポリシーの検証(lint チェック)を行う方法について説明します。

始める前に

IAM ポリシーの lint について

IAM ポリシーのコンテキストでは、lint チェックは新規または既存のポリシーを調べて特定の問題をチェックする方法です。次のような問題があります。

  • 候補
  • 警告
  • 構文やセマンティクスの改善など、ポリシーのインテントの改善に役立つ情報
  • setIamPolicy 操作の失敗を招く構文エラーまたはセマンティック エラー

ポリシーの lint チェックは、失敗した setIamPolicy() 操作の詳細な説明が得るためのデバッグツールとして使用できます。また、IAM ポリシーを意図した目的で作成するためのヘルパーツールとしても使用できます。

条件の lint チェック

条件式は、特にアクセスを適切に制限するために複数の句と論理演算子を必要とする場合は複雑になることがあります。条件式に無効なロジックが含まれている場合や、構文が条件式の制限に違反している場合、setIamPolicy() 操作は失敗します。さらに、条件はポリシー更新のためのすべての厳密な構文とセマンティクスの要件を満たすことができますが、ポリシーの適用中に予期しないアクセス結果につながる構造が含まれる可能性があります。たとえば、次のようなケースが考えられます。

  • 推奨されない関数の使用
  • レガシー リソースタイプまたはレガシー サービス名の使用
  • 適用できない条件(無効な期間など)

条件の lint チェックでは、全体的なチェックが行われ、ポリシー更新中に発生した可能性のあるエラーと、その他の問題がある可能性がある構造の両方がレポートされます。

新しい条件付きロール バインディングを設定する前に、最初に式を lint チェックすることをおすすめします。このセクションでは、Cloud Console、gcloud コマンドライン ツールや REST API を使用して条件式を lint チェックする方法を説明します。

条件式を lint チェックするには:

Console

  1. Cloud Console で [IAM] ページに移動します。

    [IAM] ページに移動

  2. [プロジェクトを選択] をクリックし、プロジェクトを選択して [開く] をクリックします。

  3. リストから目的のメンバーを探し、 ボタンをクリックします。

  4. [権限の編集] パネルで、lint チェックするロールを探します。次に、[条件] の下で、条件の名前をクリックします。

  5. [条件の編集] パネルで、[条件エディタ] は、式を lint チェックする機能を提供します。[条件ビルダー] は現在、制限付きの lint チェック機能を備えています。

  6. [条件エディタ] で、条件式を手動で追加または編集します。

  7. 右上のテキスト ボックスの上の [リンターを実行] をクリックして、CEL 構文を検証します。構文にエラーがある場合、 アイコンが式の各ラインの横に表示されます。アイコンの上にポインタを置くと、式のその部分のエラー メッセージが表示され、デバッグのための実用的なフィードバックが提供されます。

    エラーを修正してから、条件を保存することをおすすめします。条件が構文的に正しいが、lint チェックの操作により疑わしい構文が検出された場合、警告アイコン()が表示されます。アイコンの上にポインタを置くと、式のその部分の警告メッセージが表示され、デバッグのための実用的なフィードバックが提供されます。強くおすすめはしますが、条件を保存する前に警告を修正することは厳格な要件ではありません。

  8. 条件式に必要な変更を加えます。[リンターを実行] がトリガーされた後は、式の編集を容易にするためにバックグラウンドで lint チェックが続行されます。

  9. 式が正常に lint チェックされた後、[保存] をクリックして、条件を適用します。

  10. [条件の編集] パネルを閉じたら、[権限の編集] パネルでもう一度 [保存] をクリックし、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 が含まれ、これは、条件式の問題の特定に役立ちます。条件でコンパイルが失敗した場合は、次の debugMessage テキストでさまざまな validationUnitName の種類を確認できます。

The validation unit is skipped due to absence of a required object: CheckedExpr

式が正常にコンパイルされ、その後で条件が再度 lint チェックされるように、必要な変更を行います。

REST API

iamPolicies.lintPolicy メソッドは、IAM ポリシーの条件式に lint チェックまたは検証を行います。

後述のリクエストのデータを使用する前に、次のように置き換えます。

HTTP メソッドと URL:

POST https://iam.googleapis.com/v1/iamPolicies:lintPolicy

JSON 本文のリクエスト:

{
  "condition": {
    condition
  }
}

リクエストを送信するには、次のいずれかのオプションを展開します。

レスポンスの本文には、次のように 1 つ以上の 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 が含まれ、これは、条件式の問題の特定に役立ちます。条件でコンパイルが失敗した場合は、次の debugMessage テキストでさまざまな validation_unit_name の種類を確認できます。

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 条件式は、タイムスタンプ比較が実質的に true か false かを指定します。無効なタイムスタンプ形式(ISO 8601 以外)であるか、有効期限タイムスタンプが過去の日付であるか、開始タイムスタンプが過去の日付であるか、によります。
DateTimeRangeCheck CONDITION WARNING 対象の高度なタイムスタンプ関数と比較式の値が範囲外です。高度なタイムスタンプ関数の有効な値の範囲は、こちらをご覧ください
EffectiveTimeRangeCheck CONDITION WARNING タイムスタンプ関数と比較のより複雑な使用では、式の結果は空の有効期間となり、実質的に false になります。また、時間範囲は全範囲を対象としているため、実質的に true です。
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

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

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 in private beta
    release and may be subject to whitelist control. Please check https://cloud.google.com/iam/docs/conditions-overview
    for the full list of restricted attributes
  fieldName: condition.expression
  level: CONDITION
  locationOffset: 57
  severity: WARNING
  validationUnitName: LintValidationUnits/RestrictedAttributesCheck