IAM Conditions の概要

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

IAM Conditions では、指定された条件を満たす場合にのみプリンシパルにアクセス権を付与するように設定できます。たとえば、本番環境に関する問題を解決するために、ユーザーに一時的なアクセス権を付与できます。また、会社のオフィスからリクエストを行う従業員にのみアクセス権を付与することもできます。

条件は、リソースの許可ポリシーのロール バインディングで指定します。条件が存在する場合は、条件式が true に評価された場合にのみ、アクセス リクエストが許可されます。条件式は、チェックする 1 つ以上の属性が指定された一連の論理ステートメントです。

条件付きポリシーを許可する

許可ポリシーには、次の構造を持つ 1 つ以上のロール バインディングが含まれます。

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

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

ロール バインディングの条件を受け入れるのは、一部のリソースタイプのみです。ただし、組織レベルまたはプロジェクト レベルでロールを付与することで、他のリソースタイプに条件付きアクセス権を付与できます。

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

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

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

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

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

条件の CEL

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

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

IAM Conditions では、次の CEL 機能を使用します。

  • 変数: 条件で使用される変数は、request.time(Timestamp 型)や resource.name(String 型)などの特定の属性を表します。これらの変数には、実行時のコンテキストに基づいて値が設定されます。
  • 演算子: 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 を生成するには両方のステートメントが満たされる必要があります。

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

条件の属性

条件の属性は、リクエストされたリソース(タイプや名前など)またはリクエストの詳細(タイムスタンプや宛先 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/Object" &&
resource.name.startsWith("projects/_/buckets/exampleco-site-assets/")

タグ env: prod を持つ Google Cloud リソースへのアクセスを許可する:

resource.matchTag('123456789012/env', 'prod')

リクエストの属性

リクエストの属性を使用すると、次のようなリクエストに関する詳細を評価する条件を記述できます。

  • アクセスレベル
  • 日付と時刻
  • 宛先 IP アドレスとポート(IAP TCP トンネリングの場合)
  • 想定 URL ホスト / パス(IAP の場合)

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

次の例では、企業ネットワークの境界で使用される IP アドレスの範囲でアクセスを制限するアクセスレベル CorpNet を定義しています。リクエストが CorpNet アクセスレベルを満たしている場合にのみ、アクセスが許可されます。

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

組織では、リクエストの属性(送信元 IP アドレス、デバイス属性、時刻など)に基づいてアクセスレベルを定義します。詳しくは、Access Context Manager のドキュメントをご覧ください。

API 属性の式の例

ユーザーに請求先アカウント管理者(roles/billing.admin)ロールに限り付与および取り消しを許可します。

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

API 属性を使用してロールの付与を制限する方法については、ロールの付与に関する制限の設定をご覧ください。

日時式の例

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

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")

次のステップ