ロール付与の制限を設定する

大規模な組織では、リソースの許可ポリシーをチームごとに独立して管理できるようにしておくと便利です。ただし、すべての IAM ロールをプリンシパルが付与または取り消しできるようにすると、セキュリティ リスクが大幅に高まります。

Identity and Access Management(IAM)Conditions と iam.googleapis.com/modifiedGrantsByRole API 属性を使用すると、プリンシパルが付与および取り消しできるロールに制限を設定できます。この制限により、設定した制限の境界内で自身のチームの許可ポリシーを管理できる制限付きの IAM 管理者を作成できます。

始める前に

必要な権限

プロジェクト、フォルダまたは組織に対して制限付き IAM 管理者を作成するために必要な権限を取得するため、制限付き IAM 管理者を作成するリソース(プロジェクト、フォルダ、または組織)に対し、次の IAM ロールを付与するよう管理者に依頼してください。

  • プロジェクトに対して制限付き IAM 管理者を作成する: プロジェクト IAM 管理者roles/resourcemanager.projectIamAdmin
  • フォルダに対して制限付き IAM 管理者を作成する: フォルダ管理者roles/resourcemanager.folderAdmin
  • プロジェクト、フォルダまたは組織に対して制限付き IAM 管理者を作成する: 組織管理者roles/resourcemanager.organizationAdmin

ロールの付与については、プロジェクト、フォルダ、組織へのアクセス権の管理をご覧ください。

これらの事前定義ロールには、プロジェクト、フォルダ、または組織に対して制限付き IAM 管理者を作成するために必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。

必要な権限

プロジェクト、フォルダまたは組織に対して制限付き IAM 管理者を作成するには、次の権限が必要です。

  • プロジェクトに対して制限付き IAM 管理者を作成する:
    • resourcemanager.projects.getIamPolicy
    • resourcemanager.projects.setIamPolicy
  • フォルダに対して制限付き IAM 管理者を作成する:
    • resourcemanager.folders.getIamPolicy
    • resourcemanager.folders.setIamPolicy
  • 組織に対して制限付き IAM 管理者を作成する:
    • resourcemanager.organizations.getIamPolicy
    • resourcemanager.organizations.setIamPolicy

カスタムロールや他の事前定義ロールを使用して、これらの権限を取得することもできます。

一般的なユースケース

以下のセクションでは、制限付きのロールを付与して、許可ポリシーのセルフサービス管理を有効にする方法について説明します。

制限付き IAM 管理者を作成する

フィンというユーザー(finn@example.com)が、プロジェクトの制限付き IAM 管理者を担当するシナリオについて考えましょう。フィンが付与および取り消しできるロールは、自分のプロジェクトの App Engine 管理者(roles/appengine.appAdmin)と App Engine 閲覧者(roles/appengine.appViewer)のロールのみにする必要があります。

この制限付き権限を付与するには、プロジェクト IAM 管理者ロール(roles/resourcemanager.projectIamAdmin)を条件付きで付与します。プロジェクト IAM 管理者ロールを付与すると、フィンは IAM ロールを付与および取り消しできるようになります。また、条件によって、フィンが付与および取り消すロールが制限されます。

{
  "version": 3,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "members": [
        "user:owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "finn@example.com"
      ],
      "role": "roles/resourcemanager.projectIamAdmin",
      "condition": {
        "title": "only_appengine_admin_viewer_roles",
        "description": "Only allows changes to role bindings with the App Engine Admin or Viewer roles",
        "expression":
          "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/appengine.appAdmin', 'roles/appengine.appViewer'])"
      }
    }
  ]
}

この条件付きロール バインディングでは、フィンは次のことができるようになります。

  • プロジェクトの App Engine 管理者および App Engine 閲覧者のロールを付与する。
  • プロジェクトの App Engine 管理者および App Engine 閲覧者のロールを取り消す。
  • App Engine 管理者および App Engine 閲覧者のロールを付与するプロジェクト レベルのロール バインディングの条件を追加、削除、または変更する。
  • プロジェクト IAM 管理者のロールによって許可され、プロジェクトの許可ポリシーを変更しないその他のアクションを実行する。たとえば、フィンは projects.getIamPolicy メソッドを使用してプロジェクトの許可ポリシーを取得できます。

この条件付きロール バインディングでは、フィンは次のことはできません。

  • プロジェクト以外のリソースの許可ポリシーを変更する。
  • App Engine 管理者または App Engine 閲覧者以外のロールを付与する。
  • App Engine 管理者または App Engine 閲覧者以外のロールを取り消す。
  • App Engine 管理者または App Engine 閲覧者のロールを付与しないロール バインディングの条件を追加、削除、または変更する。

ユーザーに制限付き IAM 管理者の管理を許可する

リラというユーザーをチームの制限付き IAM 管理者にするシナリオについて考えましょう。リラが付与および取り消しできるロールは、自分のプロジェクトの Compute 管理者のロール(roles/compute.admin)のみにする必要があります。ただし、リラが他のユーザーを制限付き IAM 管理者に指定できるようにしたいとも考えています。つまり、リラが他のユーザーを Compute 管理者のロールに限り付与および取り消しできるようにするということです。

リラにプロジェクト IAM 管理者のロール(roles/resourcemanager.projectIamAdmin)を付与し、他のユーザーにこのロールを付与または取り消す権限を与えることが解決策だと思うかも知れません。しかし、リラにプロジェクトの IAM 管理者のロールを付与すると、自分のロールから条件を削除し、IAM ロールを付与または取り消す権限を自身に付与してしまう可能性があります。

この権限昇格を防止するには、代わりにプロジェクトの制限付き IAM 管理者用の Google グループを作成iam-compute-admins@example.com)します。次に、リラをグループに追加し、グループ マネージャーに指名します。

グループを作成したら、グループにプロジェクトの IAM 管理者のロール(roles/resourcemanager.projectIamAdmin)を条件付きで付与します。プロジェクト IAM 管理者のロールを使用すると、グループ メンバーは IAM ロールを付与および取り消すことができます。また、条件によって、付与および取り消し可能なロールが制限されます。

{
  "version": 3,
  "etag": "BwWKmjvelug=",
  "bindings": [
    {
      "members": [
        "user:owner@example.com"
      ],
      "role": "roles/owner"
    },
    {
      "members": [
        "iam-compute-admins@example.com"
      ],
      "role": "roles/resourcemanager.projectIamAdmin",
      "condition": {
        "title": "only_compute_admin_role",
        "description": "Only allows changes to role bindings for the Compute Admin role",
        "expression":
          "api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/compute.admin'])"
      }
    }
  ]
}

リラは、iam-compute-admins@example.com グループのメンバーとして、次のことができます。

  • ロールに新しいバインディングを追加するか、ロールの既存のバインディングにプリンシパルを追加して、プロジェクトの Compute 管理者ロールを付与する。
  • ロールの既存のバインディングを削除するか、ロールの既存のバインディングからプリンシパルを削除して、Compute 管理者ロールを取り消す。
  • ロールのバインディングに関連付けられている条件を追加、削除、変更して、Compute 管理者ロールの付与を変更する。
  • プロジェクト IAM 管理者のロールによって許可され、プロジェクトの許可ポリシーを変更しないその他のアクションを実行する。たとえば、projects.getIamPolicy メソッドを使用してプロジェクトの許可ポリシーを取得できます。

リラは iam-compute-admins@example.com グループの管理者として、他のユーザーを iam-compute-admins@example.com グループに追加することで、彼等に Compute 管理者ロールを付与または取り消すことができます。

リラは、次のことはできません。

  • 他のロールを付与または取り消す権限を自分に与える。
  • プロジェクト以外のリソースの許可ポリシーを変更する。
  • Compute 管理者ロール以外のロールを付与する。
  • Compute 管理者ロール以外のロールを取り消す。
  • Compute 管理者ロールを付与しないロール バインディングの条件を追加、削除、または変更する。

ロール付与を制限する

以下のセクションでは、プリンシパルが特定のロールのみを付与または取り消す方法について説明します。

ロール付与を制限する条件式を記述する

ロールを付与するプリンシパルの権限を制限するには、プリンシパルが付与または取り消すことができるロールを指定する条件式を記述します。

条件式には次の形式を使用します。

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(roles)

この式は次のことを行います。

  • api.getAttribute() 関数を使用して、API 属性 iam.googleapis.com/modifiedGrantsByRole を取得します。

    リソースの許可ポリシーを設定するリクエストの場合、この属性には、リクエストによって変更されるバインディングのロール名が含まれます。他のタイプのリクエストでは、属性は定義されません。このような場合、関数はデフォルト値([])を返します。

  • hasOnly() Common Expression Language(CEL)関数を使用して、プリンシパルが付与または取り消すことができるロールを定義して適用します。

    hasOnly() 関数の入力は、プリンシパルが付与または取り消すことができるロールのリストです。iam.googleapis.com/modifiedGrantsByRole 属性のロールがこのリストに含まれている場合、この関数は true を返します。含まれていない場合、関数は false を返します。

    iam.googleapis.com/modifiedGrantsByRole 属性にデフォルト値([])が含まれている場合、[] はリストにないロールを含まないため、true を返します。

この式をカスタマイズするには、roles をプリンシパルが付与または取り消すことができるロールのリストに置き換えます。たとえば、プリンシパルが Pub/Sub 編集者(roles/pubsub.editor)と Pub/Sub パブリッシャー(roles/pubsub.publisher)ロールのみを付与または取り消しできるようにするには、値 ['roles/pubsub.editor', 'roles/pubsub.publisher'] を使用します。

許可されたロールのリストには最大 10 個の値を含めることができます。これらの値はすべて文字列定数である必要があります。

hasOnly() ステートメントの論理演算子

&& 演算子または || 演算子を使用して、1 つの条件内で複数の hasOnly() ステートメントを結合しないでください。この操作を行うと、プリンシパルがこれらのロールの付与または取り消しを個別に実行できる場合でも、複数のロールの付与や取り消しを行うリクエストが失敗する可能性があります。

たとえば、次の条件について考えてみましょう。

api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', [])
    .hasOnly(['roles/pubsub.editor']) ||
api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', [])
    .hasOnly(['roles/pubsub.publisher'])

この条件は、リクエストによって roles/pubsub.editor ロールまたは roles/pubsub.publisher ロールのいずれかが付与されている場合は true と評価されますが、リクエストによって roles/pubsub.editor ロールと roles/pubsub.publisher ロールが両方付与されている場合は false と評価されます。

条件付きロール バインディングによりロール付与を制限する

プリンシパルが特定のロールのみを付与または取り消しできるようにするには、前のセクションの条件式を使用して条件付きロール バインディングを作成します。次に、リソースの許可ポリシーに条件付きロール バインディングを追加します。

  1. プリンシパルが付与および取り消しできるロールの範囲を表すリソースを選択します。

    • プリンシパルが組織内のすべてのリソースに対する特定のロールを付与、取り消しできるようにする場合は、組織を選択します。
    • プリンシパルがフォルダ内のすべてのリソースに対する特定のロールを付与、取り消しできるようにする場合は、フォルダを選択します。
    • プリンシパルがプロジェクト内のすべてのリソースに対する特定のロールを付与、取り消しできるようにする場合は、プロジェクトを選択します。
  2. 選択したリソースタイプ(プロジェクト、フォルダ、または組織)の許可ポリシーの設定をプリンシパルに許可するロールを選択します。最小権限の原則に従って、以下のいずれかの事前定義ロールを選択します。

    • プロジェクト: プロジェクト IAM 管理者(roles/resourcemanager.projectIamAdmin
    • フォルダ: フォルダ IAM 管理者(roles/resourcemanager.folderIamAdmin
    • 組織: 組織管理者(roles/resourcemanager.organizationAdmin

    または、resourcemanager.resource-type.setIamPolicy 権限と resourcemanager.resource-type.getIamPolicy 権限を含むカスタムロールを選択します。ここで、resource-typeprojectfolder または organization です。

  3. 選択したプロジェクト、フォルダ、または組織に対して、選択したロールを条件付きでプリンシパルに付与します。

    新しい許可ポリシーが適用され、プリンシパルは許可されたロールに限りバインディングを変更できるようになります。

    コンソール

    1. Google Cloud コンソールの [IAM] ページに移動します。

      [IAM] ページに移動

    2. プロジェクト、フォルダ、または組織の名前が、ページの上部にあるリソース セレクタに表示されていることを確認します。リソース セレクタは、現在作業しているプロジェクト、フォルダ、組織を表示します。

      リソースの名前が表示されない場合は、リソース セレクタをクリックして、リソースを選択します。

    3. プリンシパルのリストで、ロールを付与または取り消すプリンシパルを見つけて、[] ボタンをクリックします。

    4. [権限の編集] パネルで、前に選択したロールを選択します。[IAM の条件(省略可)] で、[IAM の条件を追加] をクリックします。

    5. [条件の編集] パネルで、条件のタイトルとオプションの説明を入力します。

    6. [条件エディタ] タブをクリックし、ロール付与を制限する条件式を記述するで記述した式を入力します。この式により、プリンシパルが付与または取り消すことができるロールが制限されます。

      たとえば、次の条件式では、プリンシパルの権限は Pub/Sub 編集者(roles/pubsub.editor)と Pub/Sub パブリッシャー(roles/pubsub.publisher)のロールを付与または取り消すものに制限されます。

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      警告: 許可されるロールのリストには、次の種類のロールを含めないでください。

      • IAM ロールの付与と取り消しを行う権限を持つロール(つまり、名前が setIamPolicy で終わる権限を持つロール)。
      • 制限付き IAM 管理者が変更できるカスタムロール。たとえば、制限付き IAM 管理者にプロジェクトのロール管理者のロール(roles/iam.roleAdmin)もある場合は、プロジェクト レベルのカスタムロールの付与や取り消しを許可しないようにしてください。

      このようなロールの付与と取り消しができる制限付き IAM 管理者は、すべての IAM ロールを付与および取り消す権限を自分に付与できます。詳細については、ロール付与を制限する条件式を記述するをご覧ください。

    7. [保存] をクリックして条件を適用します。

    8. [条件の編集] パネルを閉じたら、[権限の編集] パネルで [保存] をクリックして、許可ポリシーを更新します。

    gcloud

    許可ポリシーは、読み取り、変更、書き込みのパターンを使用して設定されます。

    まず、リソースの許可ポリシーを読み取ります。

    get-iam-policy コマンドを実行します。このコマンドは、リソースに対する現在の許可ポリシーを取得します。

    コマンド:

    gcloud resource-type get-iam-policy resource-id --format=json > path

    次の値を置き換えます。

    • resource-type: プリンシパルがロールを付与または取り消しできるようにするリソースタイプ。projectsresource-manager foldersorganizations のいずれかを使用します。
    • resource-id: Google Cloud プロジェクト、フォルダ、または組織 ID。
    • path: 許可ポリシーをダウンロードするファイルのパス。

    許可ポリシーは JSON 形式で保存されます。次に例を示します。

    {
      "bindings": [
        {
          "members": [
            "user:project-owner@example.com"
          ],
          "role": "roles/owner"
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 1
    }
    

    次に、許可ポリシーを変更します。

    プリンシパルが特定のロール バインディングのみを変更できるようにするには、ハイライトされた条件付きロール バインディングを追加します。

    {
      "bindings": [
        {
          "members": [
            "user:owner@example.com"
          ],
          "role": "roles/owner"
        },
        {
          "members": [
            "principal"
          ],
          "role": "role",
          "condition": {
            "title": "title",
            "description": "description",
            "expression":
              "expression"
          }
        }
      ],
      "etag": "BwWKmjvelug=",
      "version": 3
    }

    次の値を置き換えます。

    • principal: 特定のロールを付与または取り消すプリンシパル。例: user:my-user@example.com各プリンシパル タイプの形式を確認するには、Binding リファレンスをご覧ください。
    • role: 前の手順で選択したロール。このロールには、選択したリソースタイプに対する setIamPolicy 権限が含まれている必要があります。
    • title: 条件を簡単に記述する文字列。例: only_pubsub_roles
    • description: 省略可。条件の追加の説明。例: Only allows granting/revoking the Pub/Sub editor and publisher roles
    • expression: ロール付与を制限する条件式を記述するで記述した式。この式により、プリンシパルが付与または取り消すことができるロールが制限されます。

      たとえば、次の条件式では、プリンシパルの権限は Pub/Sub 編集者(roles/pubsub.editor)と Pub/Sub パブリッシャー(roles/pubsub.publisher)のロールを付与または取り消すものに制限されます。

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      警告: 許可されるロールのリストには、次の種類のロールを含めないでください。

      • IAM ロールの付与と取り消しを行う権限を持つロール(つまり、名前が setIamPolicy で終わる権限を持つロール)。
      • 制限付き IAM 管理者が変更できるカスタムロール。たとえば、制限付き IAM 管理者にプロジェクトのロール管理者のロール(roles/iam.roleAdmin)もある場合は、プロジェクト レベルのカスタムロールの付与や取り消しを許可しないようにしてください。

      このようなロールの付与と取り消しができる制限付き IAM 管理者は、すべての IAM ロールを付与および取り消す権限を自分に付与できます。詳細については、ロール付与を制限する条件式を記述するをご覧ください。

    最後に、更新された許可ポリシーを作成します。

    リソースに対して set-iam-policy コマンドを実行して、新しい許可ポリシーを設定します。

    gcloud resource-type set-iam-policy resource-id path

    次の値を置き換えます。

    • resource-type: プリンシパルがロールを付与または取り消しできるようにするリソースタイプ。projectsresource-manager foldersorganizations のいずれかを使用します。
    • resource-id: Google Cloud プロジェクト、フォルダ、または組織 ID。
    • path: 更新された許可ポリシーを含むファイルのパス。

    新しい許可ポリシーが適用され、プリンシパルは許可されたロールに限りバインディングを変更できるようになります。

    REST

    許可ポリシーは、読み取り、変更、書き込みのパターンを使用して設定されます。

    まず、リソースの許可ポリシーを読み取ります。

    Resource Manager API の getIamPolicy メソッドは、プロジェクト、フォルダ、または組織の許可ポリシーを取得します。

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

    • API_VERSION: 使用する API のバージョン。プロジェクトと組織の場合は、v1 を使用します。フォルダの場合は、v2 を使用します。
    • RESOURCE_TYPE: ポリシーを管理するリソースタイプ。値 projectsfolders、または organizations を使用します。
    • RESOURCE_ID: Google Cloud プロジェクト、組織、またはフォルダ ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。フォルダ ID と組織 ID は数値です(例: 123456789012)。
    • POLICY_VERSION: 返されるポリシー バージョン。リクエストでは、最新のポリシー バージョン(ポリシー バージョン 3)を指定する必要があります。詳細については、ポリシーの取得時にポリシー バージョンを指定するをご覧ください。

    HTTP メソッドと URL:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:getIamPolicy

    リクエストの本文(JSON):

    {
      "options": {
        "requestedPolicyVersion": POLICY_VERSION
      }
    }
    

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

    レスポンスには、リソースの許可ポリシーが含まれます。次に例を示します。

    {
      "version": 1,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "role": "roles/owner",
          "members": [
            "user:my-user@example.com"
          ]
        }
      ]
    }
    

    次に、許可ポリシーを変更します。

    プリンシパルが特定のロールのみを付与および取り消すことができる条件付きロール バインディングを追加します。version フィールドを値 3 に変更します。

    {
      "version": 3,
      "etag": "BwWKmjvelug=",
      "bindings": [
        {
          "members": [
            "user:owner@example.com"
          ],
          "role": "roles/owner"
        },
        {
          "members": [
            "PRINCIPAL"
          ],
          "role": "ROLE",
          "condition": {
            "title": "TITLE",
            "description": "DESCRIPTION",
            "expression":
              "EXPRESSION"
          }
        }
      ]
    }
    • PRINCIPAL: 特定のロールを付与または取り消すプリンシパル。例: user:my-user@example.com各プリンシパル タイプの形式を確認するには、Binding リファレンスをご覧ください。
    • ROLE: 前の手順で選択したロール。このロールには、選択したリソースタイプに対する setIamPolicy 権限が含まれている必要があります。
    • TITLE: 条件を簡単に記述する文字列。例: only_pubsub_roles
    • DESCRIPTION: 省略可。条件の追加の説明。例: Only allows granting/revoking the Pub/Sub editor and publisher roles
    • EXPRESSION: ロール付与を制限する条件式を記述するで記述した式。この式により、プリンシパルが付与または取り消すことができるロールが制限されます。

      たとえば、次の条件式では、プリンシパルの権限は Pub/Sub 編集者(roles/pubsub.editor)と Pub/Sub パブリッシャー(roles/pubsub.publisher)のロールを付与または取り消すものに制限されます。

      api.getAttribute('iam.googleapis.com/modifiedGrantsByRole', []).hasOnly(['roles/pubsub.editor', 'roles/pubsub.publisher'])

      警告: 許可されるロールのリストには、次の種類のロールを含めないでください。

      • IAM ロールの付与と取り消しを行う権限を持つロール(つまり、名前が setIamPolicy で終わる権限を持つロール)。
      • 制限付き IAM 管理者が変更できるカスタムロール。たとえば、制限付き IAM 管理者にプロジェクトのロール管理者のロール(roles/iam.roleAdmin)もある場合は、プロジェクト レベルのカスタムロールの付与や取り消しを許可しないようにしてください。

      このようなロールの付与と取り消しができる制限付き IAM 管理者は、すべての IAM ロールを付与および取り消す権限を自分に付与できます。詳細については、ロール付与を制限する条件式を記述するをご覧ください。

    最後に、更新された許可ポリシーを作成します。

    Resource Manager API の setIamPolicy メソッドを使用して、プロジェクト、フォルダまたは組織の新しい許可ポリシーとしてリクエストの許可ポリシーを設定します。

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

    • API_VERSION: 使用する API のバージョン。プロジェクトと組織の場合は、v1 を使用します。フォルダの場合は、v2 を使用します。
    • RESOURCE_TYPE: ポリシーを管理するリソースタイプ。値 projectsfolders、または organizations を使用します。
    • RESOURCE_ID: Google Cloud プロジェクト、組織、またはフォルダ ID。プロジェクト ID は英数字からなる文字列です(例: my-project)。フォルダ ID と組織 ID は数値です(例: 123456789012)。
    • POLICY: 設定するポリシーの JSON 表現。ポリシーの形式については、ポリシー リファレンスをご覧ください。

      たとえば、前の手順で示したポリシーを設定するには、POLICY を次のコードに置き換えます。

      {
        "version": 3,
        "etag": "BwWKmjvelug=",
        "bindings": [
          {
            "members": [
              "user:owner@example.com"
            ],
            "role": "roles/owner"
          },
          {
            "members": [
              "principal"
            ],
            "role": "role",
            "condition": {
              "title": "title",
              "description": "description",
              "expression":
                "expression"
            }
          }
        ]
      }

    HTTP メソッドと URL:

    POST https://cloudresourcemanager.googleapis.com/API_VERSION/RESOURCE_TYPE/RESOURCE_ID:setIamPolicy

    リクエストの本文(JSON):

    {
      "policy": POLICY
    }
    

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

    レスポンスには、更新された許可ポリシーが含まれます。

次のステップ