ポリシーの検証

このトピックでは、Cloud Identity and Access Management(Cloud IAM)を lint で検証する方法を説明します。

始める前に

Cloud IAM ポリシーの lint チェックについて

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

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

ポリシーの lint チェックは、失敗した setIamPolicy() 操作の詳細な説明が得るためのデバッグツールとして使用できます。また、Cloud 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. [条件の編集] パネルを閉じたら、[権限の編集] パネルでもう一度 [保存] をクリックし、Cloud 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

lintPolicy() を呼び出し、次の条件式を lint チェックします。

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

リクエストの本文には条件式が含まれます。

{
        "condition": {
          "title": "1_less_than_2",
          "description": "",
          "expression": "1 &lt;"
        }
    }
    

レスポンスの本文には、以下のような 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 \'&lt;EOF&gt;\' expecting {\'[\', \'{\', \'(\', \'.\', \'-\', \'!\', \'true\', \'false\', \'null\', NUM_FLOAT, NUM_INT, NUM_UINT, STRING, BYTES, IDENTIFIER}\n  | 1&lt;\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