IAM Conditions の概要

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

条件とポリシーの種類

条件は次の場所で使用できます。

  • 許可ポリシー
  • 拒否ポリシー
  • プリンシパル アクセス境界ポリシーのポリシー バインディング

以降のセクションでは、これらの場所で条件を使用して属性ベースのアクセス制御を適用する方法について説明します。

許可ポリシーの条件

許可ポリシーの条件を使用して、指定された条件が満たされた場合にのみプリンシパルにアクセス権を付与するように選択できます。たとえば、本番環境に関する問題を解決するために、ユーザーに一時的なアクセス権を付与できます。また、会社のネットワークからリクエストを行う従業員にのみアクセス権を付与することもできます。

条件は、リソースの許可ポリシーのロール バインディングで指定します。ロール バインディングに条件がある場合、条件式が true と評価された場合にのみ、ロールのプリンシパルにロールが付与されます。

ロール バインディングに条件を追加するには、condition フィールドを定義します。

"bindings": [
  {
    "role": "ROLE",
    "members": [
      "MEMBER_1",
      "MEMBER_2"
    ],
    "condition": {
      "title": "TITLE",
      "description": "DESCRIPTION",
      "expression": "EXPRESSION"
    }
  }
]

条件のフィールドの詳細については、このページの条件の構造をご覧ください。

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

1 つの許可ポリシーに追加できる条件付きロール バインディングは 100 個までにすることをおすすめします。条件付きロール バインディングの数が多くなると、許可ポリシーの全体的なサイズの上限を超える可能性があります。

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

拒否ポリシーの条件

拒否ポリシーの条件を使用して、特定の条件が満たされた場合にのみ拒否ルールを適用できます。たとえば、プリンシパルがアクセスしようとしているリソースが prod 環境の一部としてタグ付けされている場合にのみ、権限を拒否できます。

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

拒否ルールに条件を追加するには、denialCondition フィールドを定義します。

"rules": [
  {
    "denyRule": {
      "deniedPrincipals": [
        "PRINCIPAL_1",
        "PRINCIPAL_2"
      ],
      "exceptionPrincipals": [
        "EXCEPTION_PRINCIPAL_1",
        "EXCEPTION_PRINCIPAL_2"
      ],
      "deniedPermissions": [
        "DENIED_PERMISSION_1",
        "DENIED_PERMISSION_2"
      ],
      "denialCondition": {
        "title": "TITLE",
        "description": "DESCRIPTION",
        "expression": "EXPRESSION"
      }
    }
  }
]

条件のフィールドの詳細については、このページの条件の構造をご覧ください。

拒否ポリシーを作成して管理する方法については、アクセスを拒否するをご覧ください。

プリンシパル アクセス境界ポリシー バインディングの条件

プリンシパル アクセス境界ポリシーのポリシー バインディングの条件を使用して、プリンシパル アクセス境界ポリシーが適用されるプリンシパル セットを絞り込むことができます。たとえば、サービス アカウントにのみポリシーを適用したり、super-admin@example.com をポリシーから除外できます。

条件は、各ポリシー バインディングで指定します。ポリシー バインディングに条件がある場合、条件が true と評価された場合にのみ、ポリシー バインディングのポリシーが適用されます。

ポリシー バインディングに条件を追加するには、ポリシー バインディングで condition フィールドを定義します。

{
  "displayName": "DISPLAY_NAME",
  "target": {
    "principalSet": "PRINCIPAL_SET"
  },
  "policyKind": "PRINCIPAL_ACCESS_BOUNDARY",
  "policy": "PAB_POLICY",
  "condition": {
    "title": "TITLE",
    "description": "DESCRIPTION",
    "expression": "EXPRESSION"
  }
}

条件のフィールドの詳細については、このページの条件の構造をご覧ください。

プリンシパル アクセス境界ポリシーのポリシー バインディングを作成する方法については、プリンシパル アクセス境界ポリシーをプリンシパル セットに適用するをご覧ください。

条件の構造

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 つ以上のステートメントから構成されます。

各ステートメントは属性ベースの制御ルールを表し、最終的にロール バインディング、拒否ルール、またはポリシー バインディングが適用されるかどうかを決定します。

IAM Conditions の条件では、次の 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 を生成するには両方のステートメントが満たされる必要があります。

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

条件の属性

条件の属性は、リクエストされたリソース(タイプや名前など)またはリクエストの詳細(タイムスタンプや宛先 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')

プリンシパルの属性

プリンシパルの属性を使用すると、リクエストを発行したプリンシパルに基づいて条件を記述できます。評価可能な属性は次のとおりです。

  • リクエスト内のプリンシパル タイプ
  • リクエスト内のプリンシパルの ID

詳細については、条件属性のリファレンスをご覧ください。

式の例

プリンシパル アクセス境界ポリシー バインディングで次の条件式を使用すると、バインディング内のポリシーがサービス アカウントに対してのみ適用されます。

principal.type == 'iam.googleapis.com/ServiceAccount'

プリンシパル アクセス境界ポリシー バインディングで次の条件式を使用すると、バインディング内のポリシーが super-admin@example.com に適用されません。

principal.subject != 'super-admin@example.com'

リクエストの属性

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

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

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

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

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

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

API 属性の式の例

iam.projects.setIamPolicy 権限を持つロールのロール バインディングで次の条件式を使用すると、ユーザーはプロジェクトに対する請求先アカウント管理者(roles/billing.admin)ロールのみを付与および取り消すことができます。

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

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

日時式の例

ロール バインディングで次の条件式を使用すると、2021 年 1 月 1 日の午前 0 時までアクセスが許可されます。

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') <= '

ロール バインディングで次の条件式を使用すると、ドイツのベルリンのタイムゾーンに基づいて 2020 年 6 月にのみアクセスが許可されます。

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'
  ])
)

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

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

ロール バインディングで次の条件式を使用すると、リクエスト内の特定のサブドメインまたは URL パスにのみアクセスが許可されます。

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

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

ロール バインディングで次の条件式を使用すると、特定の時間内にリクエストが行われ、リソース名の接頭辞、選択したアクセスレベル、特定のリソースタイプと一致している場合にアクセスが許可されます。

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

次のステップ