拒否ポリシー

Identity and Access Management(IAM)拒否ポリシーを使用すると、Google Cloud リソースへのアクセスにガードレールを設定できます。拒否ポリシーを使用すると、付与されるロールに関係なく、特定のプリンシパルが特定の権限を使用できないようにする拒否ルールを定義できます。

このページでは、拒否ポリシーと拒否ルールの概要について説明します。拒否ポリシーを作成および更新する方法については、リソースへのアクセスを拒否するをご覧ください。

拒否ポリシーの仕組み

拒否ポリシーは拒否ルールで構成されます。拒否ルールでは、次のものを指定します。

  • 権限を拒否するプリンシパルのセット
  • プリンシパルで拒否される権限、または使用できない権限
  • (省略可)権限を拒否する条件

権限が拒否された場合、プリンシパルは付与されている IAM ロールに関係なく、その権限を必要とする操作を行うことができません。これは、IAM では、関連する許可ポリシーの前に、関連する拒否ポリシーがチェックされるためです。詳しくは、ポリシーの評価をご覧ください。

拒否ポリシーをプロジェクト、フォルダまたは組織に接続して、ポリシーの適用先を限定します。これらのリソースのいずれかに拒否ポリシーが接続されている場合、そのポリシーのプリンシパルは、指定された権限でリソースとその子孫にアクセスすることはできません。拒否ポリシーを接続できる場所の詳細については、このページの接続ポイントをご覧ください。

1 つのリソースに複数の拒否ポリシーを接続できます。これにより、拒否ルールの種類ごとに別々の拒否ポリシーを作成できます。たとえば、1 つのポリシーにコンプライアンス関連の拒否ルールを設定し、別のポリシーに他の拒否ルールを作成できます。拒否ポリシーは他の拒否ポリシーとは別に評価されます。

各リソースには、最大 500 個の拒否ポリシーを設定できます。これらの拒否ポリシーには、合計で 500 個の拒否ルールを含めることができます。

接続ポイント

拒否ポリシーは組織、フォルダ、プロジェクトに関連付けられます。これらのリソースのいずれかに接続すると、そのプロジェクト、フォルダ、または組織内の下位レベルのすべてのリソースに拒否ポリシーが継承されます。拒否ポリシーを使用するには、拒否ポリシーが接続されているリソースの ID が必要です。これは接続ポイントと呼ばれます。この ID は、次の表のいずれかの形式を使用します。

接続ポイントの形式
組織

cloudresourcemanager.googleapis.com/organizations/ORG_ID
ORG_ID は、数値の組織 ID に置き換えます。REST API の場合は、値全体を URL エンコードします。

gcloud CLI の例:
cloudresourcemanager.googleapis.com/organizations/123456789012

REST API の例:
cloudresourcemanager.googleapis.com%2Forganizations%2F123456789012

フォルダ

cloudresourcemanager.googleapis.com/folders/FOLDER_ID
FOLDER_ID は、数値のフォルダ ID に置き換えます。REST API の場合は、値全体を URL エンコードします。

gcloud CLI の例:
cloudresourcemanager.googleapis.com/folders/987654321098

REST API の例:
cloudresourcemanager.googleapis.com%2Ffolders%2F987654321098

プロジェクト

cloudresourcemanager.googleapis.com/projects/PROJECT_ID
PROJECT_ID は、英数字または数字のプロジェクト ID に置き換えます。REST API の場合は、値全体を URL エンコードします。

gcloud CLI の例:
cloudresourcemanager.googleapis.com/projects/my-project

REST API の例:
cloudresourcemanager.googleapis.com%2Fprojects%2Fmy-project

拒否ポリシーの継承

許可ポリシーと同様に、拒否ポリシーもリソース階層に従って継承されます。プロジェクト、フォルダまたは組織に拒否ポリシーを接続すると、そのプロジェクト、フォルダまたは組織の下位にあるすべてのリソースにも同じ拒否ポリシーが適用されます。

たとえば、組織の拒否ポリシーで、プリンシパルが特定の権限を使用できない場合、プリンシパルは組織内のいかなるリソースに対しても、その権限を使用できません。このルールは、その組織内のフォルダとプロジェクトのほうが制限の緩い拒否ポリシーを使用している場合でも適用されます。

同様に、プリンシパルが特定の権限を使用できないことがプロジェクトの拒否ポリシーで設定されている場合、プリンシパルはプロジェクト内のどのリソースに対しても、その権限を使用できません。このルールは、親組織とフォルダでより制限の厳しい拒否ポリシーを使用している場合でも適用されます。

拒否条件

拒否条件には、拒否ルールの適用条件を指定します。条件が true と評価された場合、または評価できない場合、拒否ルールが適用され、プリンシパルは指定された権限を使用できません。条件が false と評価された場合、拒否ルールは適用されず、プリンシパルは指定された権限を使用できます。

拒否条件の構造は IAM の条件と同じです。ただし、拒否条件はリソースタグ関数のみを認識します。

条件の記述方法については、IAM Conditions の概要をご覧ください。

権限グループ

一部のサービスでは、権限グループを拒否できます。権限グループは、指定されたパターンに一致する権限のセットです。権限グループを使用すると、関連する一連の権限を拒否できます。たとえば、1 つのサービスまたはリソースに対する権限をすべて拒否できます。

サポートされている権限グループは、拒否ポリシーでサポートされている権限に記載されています。サポートされている権限グループの ID では、権限名の 1 つ以上のセクションをワイルドカード文字(*)に置き換えます。各グループに含まれる権限は、ワイルドカードの位置によって異なります。

  • SERVICE_FQDN/RESOURCE.*: 指定されたリソースに対するすべての権限を拒否します。
  • SERVICE_FQDN/*.*: 指定されたサービスのすべての権限を拒否します。
  • SERVICE_FQDN/*.VERB: 指定された動詞で終わるサービスのすべての権限を拒否します。

権限グループには、指定されたパターンに一致する現在と将来のすべての権限が含まれます。たとえば、権限グループ example.googleapis.com/exampleResource.* を使用して、ユーザーに対して exampleResource リソースタイプのすべての権限を拒否するとします。example.googleapis.comexampleResource リソースタイプの新しい権限(example.googleapis.com/exampleResource.newPermission など)を追加すると、そのユーザーに対して新しい権限が自動的に拒否されます。

ワイルドカードは、サポートされている権限グループでのみ使用できます。それ以外の権限名でワイルドカードを使用することはできません。

拒否ポリシーの構造

拒否ポリシーはメタデータと拒否ルールのコレクションです。拒否ルールは、一連のプリンシパルと、プリンシパルで拒否される権限または使用できない権限を関連付けます。ルールには権限を拒否する条件も指定できます。

たとえば、次の拒否ポリシーでは、プリンシパルが project-admins@example.com のメンバーであるか、削除されるプロジェクトに test というタグが付いている場合を除き、どのプリンシパルもプロジェクトの削除が拒否されます。

{
  "name": "policies/cloudresourcemanager.googleapis.com%2Fprojects%2F253519172624/denypolicies/limit-project-deletion",
  "uid": "06ccd2eb-d2a5-5dd1-a746-eaf4c6g3f816",
  "kind": "DenyPolicy",
  "displayName": "Only project admins can delete projects.",
  "etag": "MTc1MTkzMjY0MjUyMTExODMxMDQ=",
  "createTime": "2021-09-07T23:15:35.258319Z",
  "updateTime": "2021-09-07T23:15:35.258319Z",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete",
          "cloudresourcemanager.googleapis.com/folders.*"
        ],
        "exceptionPermissions": [
          "cloudresourcemanager.googleapis.com/folders.list",
          "cloudresourcemanager.googelapis.com/folders.get"
        ],
        "denialCondition": {
          "title":  "Only for non-test projects",
          "expression": "!resource.matchTag('12345678/env', 'test')"
        }
      }
    }
  ]
}

以降のセクションでは、拒否ポリシーのメタデータと拒否ルールのフィールドについて説明します。

メタデータ

拒否ポリシーには次のメタデータが含まれます。

  • name: 拒否ポリシーの名前。この名前の形式は policies/ATTACHMENT_POINT/denypolicies/POLICY_ID で、ATTACHMENT_POINT は拒否ポリシーが接続されているプロジェクト、フォルダ、または組織、POLICY_ID は拒否ポリシーの英数字の ID です。
  • uid: Google が拒否ポリシーに割り当てる一意の ID。
  • kind: ポリシーのタイプ。拒否ポリシーの kind は常に DenyPolicy です。
  • displayName: 省略可。人が読める形式の拒否ポリシー名。
  • etag: ポリシーのバージョン ID。更新の競合を回避するため、etag 値は IAM に保存されている値と一致させる必要があります。etag 値が一致しない場合、リクエストは失敗します。
  • createTime: 拒否ポリシーが作成された時間。
  • updateTime: 拒否ポリシーが最後に更新された時間。

拒否ルール

拒否ルールには次のフィールドがあります。

  • deniedPrincipals: 権限が拒否されるプリンシパル。個々のプリンシパルを指定することも、プリンシパルのセットを指定することもできます。個々のプリンシパル タイプには、ユーザー アカウント、サービス アカウント、Workforce または Workload Identity プール内の単一の ID が含まれます。プリンシパルのセットには、Google グループ、Cloud Identity ドメイン、Workforce または Workload ID のセット、インターネット上のすべてのユーザーが含まれます。

    有効なプリンシパル タイプと ID のリストについては、IAM v2 API のプリンシパル ID をご覧ください。

  • exceptionPrincipals: 省略可。拒否ルールから除外されるプリンシパル。これらのプリンシパルは、deniedPrincipals に含まれている場合または deniedPrincipals にあるグループのメンバーになっている場合でも、指定された権限が拒否されません。

    個々のプリンシパルを指定することも、プリンシパルのセットを指定することもできます。個々のプリンシパル タイプには、ユーザー アカウント、サービス アカウント、Workforce または Workload Identity プール内の単一の ID が含まれます。プリンシパルのセットには、Google グループ、Cloud Identity ドメイン、Workforce または Workload ID のセット、インターネット上のすべてのユーザーが含まれます。

    有効なプリンシパル タイプと ID のリストについては、IAM v2 API のプリンシパル ID をご覧ください。

  • deniedPermissions: 指定したプリンシパルで使用できない権限または拒否される権限。これらの権限は、IAM v2 の権限形式を使用します。この形式では、完全修飾ドメイン名(FQDN)を使用してサービスを識別します。形式は SERVICE_FQDN/RESOURCE.ACTION です。Google API では、ドメイン *.googleapis.com を使用します。例: iam.googleapis.com/roles.delete

    拒否できるのは一部の権限です。拒否可能な権限の一覧については、拒否ポリシーでサポートされている権限をご覧ください。

    権限グループを使用して権限のセットを拒否できる場合もあります。詳しくは、権限グループをご覧ください。

  • exceptionPermissions: 省略可。指定されたプリンシパルが使用できる権限のリスト。これらの権限が deniedPermissions に含まれている場合でも使用できます。たとえば、このフィールドを使用して、権限グループ内の特定の権限を例外にすることができます。

  • denialConditions: 省略可。拒否ルールが適用条件を示す論理式。条件が true と評価されるか、評価できない場合は、権限が拒否されます。条件が false と評価された場合、権限は拒否されません。詳しくは、このページの拒否条件をご覧ください。

一般的なユースケース

以下では、拒否ポリシーを使用する一般的な状況と、それぞれの状況で作成する拒否ルールの例を示します。 拒否ポリシーを作成および更新する方法については、リソースへのアクセスを拒否するをご覧ください。

管理者権限の一元化

拒否ポリシーを使用すると、特定の管理アクティビティを特定のプリンシパルのセットに制限できます。

たとえば、組織のカスタムロールの管理を中央の特定のチームに限定できます。これを行うには、管理グループ(custom-role-admins@example.com)のユーザーを除くすべてのユーザーにカスタムロールの管理に必要な権限の使用を拒否するルールを作成します。

{
  "deniedPrincipals": [
    "principalSet://goog/public:all"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/custom-role-admins@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/roles.create",
    "iam.googleapis.com/roles.delete",
    "iam.googleapis.com/roles.update",
  ]
}

次に、拒否ポリシーを組織に接続します。

他のユーザーに必要な権限が付与されている場合でも、custom-role-admins@example.com グループのメンバーのみがカスタムロールを管理できようになります。

たとえば、yuri@example.comtal@example.com の両方に組織のロール管理者ロール(roles/iam.organizationRoleAdmin)が付与され、yuri@example.comcustom-role-admins@example.com のメンバーで、tal@example.com はメンバーでないとします。この拒否ポリシーでは、yuri@example.com のみがロールの作成、削除、更新を行うことができます。

アクセス許可の例外の作成

継承された権限を拒否する拒否ポリシーを作成できます。この機能を使用すると、リソース階層の上位レベルにロールを付与し、下位レベルの個々のリソースでのロールの権限を拒否できます。

たとえば、複数のプロジェクトを含むフォルダ Engineering があります。グループ eng@example.com には、フォルダ内のすべてのプロジェクトに対するサービス アカウント キー管理者のロール(roles/iam.serviceAccountKeyAdmin)が付与されています。ただし、フォルダ example-prod 内の 1 つのプロジェクトでは、サービス アカウント キーの作成と削除を許可したくないとします。

この場合は、個々のプロジェクトにサービス アカウント キー管理者のロールを割り当てるのではなく、次のように、eng@example.com を満たすプリンシパルでサービス アカウント キー管理者ロールの作成権限と削除権限を拒否するルールを作成します。

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

次に、この拒否ルールを拒否ポリシーに追加し、ポリシーをプロジェクト example-prod に接続します。

拒否ポリシーをプロジェクトに接続すると、example-prod でのサービス アカウント キーの作成または削除は許可せずに、サービス アカウント キー管理者のロールを Engineering フォルダの eng@example.com に付与できます。

これにより、example-prod 以外の eng@example.com のメンバーは、すべてのプロジェクトでサービス アカウント キーの作成と削除を行えるようになります。たとえば、izumi@example.comeng@example.com のメンバーの場合、example-devexample-test のサービス アカウント キーの作成と削除は可能ですが、example-prod では作成できません。

次に、eng@example.com のサブセットに example-prod でのサービス アカウント キーの作成と削除を許可するとします。このサブセットはグループ eng-prod@example.com です。eng-prod@example.com のメンバーが example-prod でサービス アカウント キーを作成および削除できるようにするには、そのグループを拒否ルールから除外します。

{
  "deniedPrincipals": [
    "principalSet://goog/group/eng@example.com"
  ],
  "exceptionPrincipals": [
    "principalSet://goog/group/eng-prod@example.com"
  ],
  "deniedPermissions": [
    "iam.googleapis.com/serviceAccountKeys.create",
    "iam.googleapis.com/serviceAccountKeys.delete"
  ]
}

修正後の拒否ポリシーにより、eng-prod@example.com のメンバーは example-prod を含むすべてのプロジェクトのサービス アカウント キーを作成、削除できるようになります。たとえば、charlie@example.comeng-prod@example.com のメンバーである場合、eng@example.com のメンバーであっても、そのメンバーは example-devexample-testexample-prod でも鍵の作成と削除を行うことができます。

タグに基づいてアクセスをブロックする

タグとは、組織、フォルダ、プロジェクトに付加できる Key-Value ペアのことです。拒否ポリシーを使用すると、ロールの付与で IAM 条件を追加することなく、タグに基づいて権限を拒否できます。

たとえば、すべてのプロジェクトに devtestprod というタグが付いています。prod タグのあるプロジェクトの削除を project-admins@example.com のメンバーにのみ許可します。

この問題を解決するには、prod タグが付いているリソースについて、project-admins@example.com を除くすべてのユーザーで cloudresourcemanager.googleapis.com/projects.delete 権限を拒否する拒否ルールを作成します。

{
  "displayName": "Only project admins can delete production projects.",
  "rules": [
    {
      "denyRule": {
        "deniedPrincipals": [
          "principalSet://goog/public:all"
        ],
        "exceptionPrincipals": [
          "principalSet://goog/group/project-admins@example.com"
        ],
        "deniedPermissions": [
          "cloudresourcemanager.googleapis.com/projects.delete"
        ],
        "denialCondition": {
          "title":  "Only for prod projects",
          "expression": "resource.matchTag('12345678/env', 'prod')"
        }
      }
    }
  ]
}

次に、この拒否ルールを拒否ポリシーに追加して、ポリシーを組織に接続します。

この拒否ルールにより、ロールの付与で条件を追加せずに、プリンシパルのアクセス権を制限できます。代わりに、cloudresourcemanager.googleapis.com/projects.delete 権限を含むプリンシパルのロールを付与し、project-admins@example.com 以外のプリンシパルに対して、prod タグのあるプロジェクトの削除を拒否する拒否ルールを作成できます。

たとえば、bola@example.comkiran@example.com の 2 人のユーザーについて考えてみましょう。いずれのユーザーにもプロジェクト削除のロール(roles/resourcemanager.projectDeleter)が付与されています。また、kiran@example.comproject-admins@example.com のメンバーです。この拒否ポリシーにより、bola@example.com には dev または test タグ付きプロジェクトのみ削除が許可されます。kiran@example.com は、タグに関係なく、すべてのプロジェクトを削除できます。

次のステップ