IAM Conditions の概要

このページでは、Identity and Access Management(IAM)の Conditions の機能について説明します。この機能を使用すると、Google Cloud リソースに対する条件付き、属性ベースのアクセス制御を定義して適用できます。

IAM Conditions では、構成された条件が満たされる場合にのみ、ID(メンバー)にリソース アクセス権を付与できます。たとえば、本番環境で問題が発生した場合にユーザーに対して一時的なアクセス権を構成したり、会社のオフィスからリクエストする従業員にのみリソース アクセスを制限したりできます。

条件は、IAM リソースのポリシーのロール バインディングで指定されます。条件が存在する場合、条件式が true に評価されたときに限りアクセス リクエストが許可されます。各条件式は一連の論理ステートメントであり、そこで 1 つまたは複数の属性を指定して検査できます。

条件付き IAM ポリシー

IAM ポリシーは、次の構造を持つ 1 つ以上のロール バインディングで構成されます。

"bindings": [
  {
    "role": ...
    "members": ...
    "condition": ...
  },
  ...
]

condition オブジェクトはオプションです。各ロール バインディングには 0 個または 1 個の条件を含めることができます。ロール バインディングに condition オブジェクトがない場合、そのロール バインディングのメンバーは常にリソースに対する指定されたロールを持ちます。

condition オブジェクトの構造は次のとおりです。

"condition": {
    "title": ...
    "description": ...
    "expression": ...
}

条件の title は必須ですが、description はオプションです。title と description はいずれも純粋な情報フィールドであり、条件の識別と説明に役立ちます。

expression フィールドは必須です。このフィールドは、Common Expression Language(CEL)のサブセットを使用する属性ベースの論理式を定義します。CEL については、後のセクションで詳しく説明します。条件 expression には複数のステートメントを含めることができ、それぞれが 1 つの属性を使用します。複数のステートメントは CEL 言語仕様に従い、論理演算子を使用して結合されます。

条件付きロール バインディングを追加、変更、削除する方法については、条件付きロール バインディングの管理をご覧ください。

条件の CEL

Common Expression Language(CEL)は、IAM Conditions で式を指定するために使われる式言語です。これは属性ベースの論理式を表現することに特化して調整されています。詳細については、CEL の仕様言語の定義をご覧ください。

IAM Conditions では、属性データに基づいてブール型の認証を行う目的で CEL のサブセットが使用されます。一般に、条件式は、論理演算子(&&||、または !)を使用して結合された 1 つ以上のステートメントで構成されます。各ステートメントは、ロール バインディングに適用される属性ベースの制御ルールを表し、最終的に認証が許可されるかどうかを決定します。

条件に関連する CEL の最も重要な機能は次のとおりです。

  • 変数: 条件で使用される変数は、(Timestamp 型の)request.time や(String 型の)resource.name などの特定の属性を表します。これらの変数には、実行時のコンテキストに基づいて値が設定されます。
  • 演算子: Timestamp や String などの各データ型では、論理式の作成に使用できる一連の演算子がサポートされます。通常、演算子を使用して変数に含まれる値とリテラル値とを比較します(例: resource.service == "compute.googleapis.com")。この例では、resource.service の入力値が compute.googleapis.com である場合、式は true と評価されます。
  • 関数: 関数は、より複雑な演算をサポートするデータ型向けの「複合」演算子です。条件式には、特定のデータ型と組み合わせて使用できる事前定義された関数があります。たとえば、request.path.startsWith("/finance") は String 接頭辞マッチ関数を使用し、request.path の値に「/finance」などの一致する接頭辞が含まれる場合に true と評価されます。
  • 論理演算子: Conditions では、単純な式のステートメントから複雑な論理式を作成するために使用できる 3 つの論理演算子(&&||!)がサポートされています。これらの論理演算子を使用すると、1 つの条件式で複数の入力変数を使用できます。たとえば、request.time.getFullYear() < 2020 && resource.service == "compute.googleapis.com" は 2 つの単純なステートメントを結合し、全体的な評価結果として true を生成するには両方のステートメントが満たされる必要があります。

サポートされている変数、演算子、関数の詳細については、属性のリファレンスをご覧ください。

条件の属性

条件の属性は、リクエストされたリソース(タイプや名前など)に基づくことも、リクエストの詳細(ターゲット Compute Engine 仮想マシン(VM)インスタンスのタイムスタンプ、発信元 IP アドレス、宛先 IP アドレスなど)に基づくこともあります。これらの属性を使用した式の例を以下に示します。

リソースの属性

リソースの属性では、リソースタイプ、リソース名、使用されている Google Cloud サービスなど、アクセス リクエスト内のリソースを評価する条件を作成できます。

リソースの属性の完全なリストについては、リソース属性のリファレンスをご覧ください。

リソース属性を使用してリソースベースのアクセスを構成する方法については、リソースベースのアクセスの構成を参照してください。

式の例

Compute Engine VM インスタンスへのアクセスは許可するが、他のタイプのリソースは許可しない:

resource.type == "compute.googleapis.com/Instance"

Cloud Storage リソースへのアクセスは許可するが、他のサービスのリソースへのアクセスは許可しない:

resource.service == "storage.googleapis.com"

指定した接頭辞で始まる名前の Cloud Storage バケットにのみアクセスを許可する:

resource.type == "storage.googleapis.com/Bucket" &&
resource.name.startsWith("projects/_/buckets/exampleco-site-assets-")

リクエストの属性

リクエストの属性では、アクセスレベル、日時、宛先 IP アドレスとポート(IAP TCP トンネリングの場合)、想定 URL ホスト / パス(IAP の場合)など、リクエストの詳細情報を評価する条件を作成できます。

アクセスレベル式の例(IAP の場合のみ)

組織で定義されたアクセスレベルにリクエストが適合する場合にのみ、アクセスを許可します。次の例では、企業ネットワークにトラフィックが出入りする IP アドレス範囲にアクセスを限定するアクセスレベル CorpNet を組織で定義しています。

"accessPolicies/199923665455/accessLevels/CorpNet" in
request.auth.access_levels

アクセスレベルは組織によって定義されます。これは、送信元 IP アドレス、デバイス属性、時刻など、リクエストの属性に基づいて割り当てられます。アクセスレベルの詳細については、Access Context Manager のドキュメントをご覧ください。

日時式の例

指定された期限切れ日時まで一時的にアクセスを許可する:

request.time < timestamp("2021-01-01T00:00:00Z")

ドイツのベルリンのタイムゾーンに基づいて指定された営業時間内にのみアクセスを許可する:

request.time.getHours("Europe/Berlin") >= 9 &&
request.time.getHours("Europe/Berlin") <= 17 &&
// Days of the week range from 0 to 6, where 0 == Sunday and 6 == Saturday.
request.time.getDayOfWeek("Europe/Berlin") >= 1 &&
request.time.getDayOfWeek("Europe/Berlin") <= 5

ドイツのベルリンのタイムゾーンに基づいて、指定された月と年にのみアクセスを許可する:

request.time.getFullYear("Europe/Berlin") == 2020
request.time.getMonth("Europe/Berlin") < 6

タイムスタンプを指定するには、RFC 3339 形式を使用します。タイムゾーンを指定するには、IANA タイムゾーン データベースの識別子を使用します。

日時式の詳細については、CEL 仕様を参照してください。

日時式を使用して一時的なアクセス権を構成する方法については、一時アクセスの構成をご覧ください。

宛先 IP / ポート式の例(IAP TCP トンネリングの場合)

リクエスト内の特定の宛先 IP またはポートでのアクセスを許可する:

destination.ip == "14.0.0.1"
destination.ip != "127.0.0.1"
destination.port == 22
destination.port > 21 && destination.port <= 23

転送ルールの式の例

リクエストで転送ルールが作成されない場合、または内部的な Google Cloud ロードバランサの転送ルールがリクエストで作成されている場合に、メンバーに対してアクセスを許可します。

!compute.isForwardingRuleCreationOperation() || (
  compute.isForwardingRuleCreationOperation() &&
  compute.matchLoadBalancingSchemes([
    'INTERNAL', 'INTERNAL_MANAGED', 'INTERNAL_SELF_MANAGED'
  ]))
)

URL ホスト / パス式の例(IAP の場合)

リクエスト内の特定のサブドメインまたは URL パスにのみアクセスを許可する:

request.host == "hr.example.com"
request.host.endsWith(".example.com")
request.path == "/admin/payroll.js"
request.path.startsWith("/admin")

負荷分散スキームの詳細については、Google Cloud ロードバランサでの IAM Conditions の使用をご覧ください。

異なるタイプの属性を持つ式の例

特定の時間内にリクエストが行われ、リソース名の接頭辞、目的のアクセスレベル、特定のリソースタイプと一致している場合にアクセスを許可する:

request.time > timestamp("2018-08-03T16:00:00-07:00") &&
request.time < timestamp("2018-08-03T16:05:00-07:00") &&
((resource.name.startsWith("projects/project-123/zones/us-east1-b/instances/dev") ||
 (resource.name.startsWith("projects/project-123/zones/us-east1-b/instances/prod") &&
  "accessPolicies/34569256/accessLevels/CorpNet" in request.auth.access_levels)) ||
 resource.type != "compute.googleapis.com/Instance")

条件付きのロール バインディングを許可するリソース

次のタイプの Google Cloud リソースについて、IAM ポリシーに条件を追加できます。

Google Cloud サービス リソースタイプ
Cloud Key Management Service(Cloud KMS)
  • 暗号鍵
  • 暗号鍵バージョン
  • キーリング
Cloud Storage バケット 1、2
Compute Engine
  • グローバル バックエンド サービス
  • リージョン バックエンド サービス
  • ファイアウォール
  • イメージ
  • インスタンス テンプレート
  • インスタンス
  • リージョン永続ディスク
  • ゾーン永続ディスク
  • スナップショット
Identity-Aware Proxy(IAP)
  • トンネル
  • トンネル インスタンス
  • トンネルゾーン
  • すべてのウェブサービス
  • 個々のウェブサービス
  • ウェブサービス タイプ
  • ウェブサービスのバージョン
Resource Manager
  • 組織
  • プロジェクト
Secret Manager
  • Secret
  • Secret のバージョン

1 均一なバケットレベルのアクセスを使用するバケットで使用できます。均一なバケットレベルのアクセスを有効にできない場合は、プロジェクトなど、上位レベルのリソースの IAM ポリシーに条件を追加できます。

2 resource.name 属性を使用して、Cloud Storage バケット内のオブジェクトを参照できます。ただし、バケットやプロジェクトなど、上位レベルのリソースの IAM ポリシーに条件を追加する必要があります。

他のタイプのリソースの IAM ポリシーでは、条件が許可されません。ただし、条件付きロール バインディングを組織レベルまたはプロジェクト レベルで追加でき、他のリソースはリソース階層を介してこれらのロール バインディングを継承します。

どの属性がどのリソースタイプに影響するかの詳細については、属性のリファレンスを参照してください。

既知の制限事項

IAM Conditions には次の制限事項があります。

  • このページのサポート サービスの詳細で説明しているように、特定の Google Cloud サービスでのみ、ロール バインディングに条件を追加できます。また、ほとんどの条件属性では、対応するサービス数に制限があります。
  • 基本ロールroles/ownerroles/editorroles/viewer)はサポートされていません。ロール バインディングで基本ロールを使用する条件を設定しようとすると、setIamPolicy 操作は失敗します。
  • allUsers および allAuthenticatedUsers 値は、条件付きロール バインディングではサポートされないメンバータイプです。これらのメンバータイプのいずれかを指定した場合、setIamPolicy 操作は失敗します。
  • 各ポリシーに含めるロール バインディングの数を 100 以下にすることをおすすめします。ポリシー 1 つあたりの基本となるストレージ サイズには制限があります。ポリシーに多数の条件付きロール バインディングが含まれている場合、サイズ制限を超過し、拒否される可能性があります。
  • 同じロール(異なる条件)の同じメンバーには、少数の異なる条件付きロール バインディングのみを設定することをおすすめします。ただし、同じロール、同じメンバーに含めることができるロール バインディングは最大 20 個です。この数を超えると、setIamPolicy 操作は失敗します。
  • 1 つの条件式で最大 12 個の論理演算子を使用できます。この数を超えると、setIamPolicy 操作は失敗します。

次のステップ