サービス アカウントのコンテキストアウェア アクセスを構成する

このガイドでは、定義したアクセスレベルに基づいて、 Google Cloud API へのサービス アカウント アクセスを保護するために、コンテキストアウェア アクセスを設定する方法について説明します。

制限事項

サービス アカウントのコンテキストアウェア アクセス ポリシーには、次の制限が適用されます。

  • サービス アカウントがワークフローの実行と Cloud Scheduler に使用されている場合、サービス アカウント バインディングにネットワークベースまたは IP アドレスベースの属性を使用することはできません。

  • コンテキストアウェア アクセス ポリシーでは、kubectl を使用した限定公開 Google Kubernetes Engine(GKE)クラスタへの接続や、Auth Proxy を使用した Cloud SQL への接続をブロックできません。

  • サービス アカウントにバインドするアクセスレベルに、Device 属性などのサポートされていない属性が含まれている場合、コンテキストアウェア アクセスは API アクセスを拒否します。

  • サービス アカウントでは、スコープ付きアクセスレベルはサポートされていません。

Cloud Build と Cloud Run を使用する場合は、次の組み込みの Virtual Private Cloud(VPC)機能を使用することをおすすめします。

始める前に

  1. Google Cloud 組織と 1 つ以上の Google Cloud プロジェクトがあることを確認します。
  2. Google Cloud アカウントにログインします。 Google Cloudを初めて使用する場合は、 アカウントを作成して、実際のシナリオで Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
  3. Google Cloud CLI をインストールします。

  4. 外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション ID を使用して gcloud CLI にログインする必要があります。

  5. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  6. Google Cloud プロジェクトを作成または選択します。

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトを選択する際に、特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者のロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、 Google Cloud プロジェクト名に置き換えます。

  7. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。

  8. IAM、Access Context Manager、Resource Manager の各 API を有効にします(有効になっていない場合)。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を介してこの権限がすでに付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を介してこの権限を取得できます。ロールを付与する方法を学習する。

    gcloud services enable accesscontextmanager.googleapis.com cloudresourcemanager.googleapis.com iam.googleapis.com
  9. Google Cloud CLI をインストールします。

  10. 外部 ID プロバイダ(IdP)を使用している場合は、まず フェデレーション ID を使用して gcloud CLI にログインする必要があります。

  11. gcloud CLI を初期化するには、次のコマンドを実行します。

    gcloud init
  12. Google Cloud プロジェクトを作成または選択します。

    プロジェクトの選択または作成に必要なロール

    • プロジェクトを選択する: プロジェクトを選択する際に、特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、resourcemanager.projects.create 権限を含むプロジェクト作成者のロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、 Google Cloud プロジェクト名に置き換えます。

  13. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。

  14. IAM、Access Context Manager、Resource Manager の各 API を有効にします(有効になっていない場合)。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を介してこの権限がすでに付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を介してこの権限を取得できます。ロールを付与する方法を学習する。

    gcloud services enable accesscontextmanager.googleapis.com cloudresourcemanager.googleapis.com iam.googleapis.com
  15. Google Cloud CLI のコンポーネントを更新します。
    gcloud components update --quiet
  16. プロジェクトにサービス アカウントがない場合は、サービス アカウントを作成します。このサービス アカウントは、コンテキストアウェア アクセス ポリシーの対象です。

必要なロール

このセクションでは、コンテキストアウェア アクセスの使用に必要な Identity and Access Management(IAM)のロールについて説明します。

プロジェクト レベルのロール

プロジェクト レベルで必要な権限を取得するには、ユーザー アカウントまたはサービス アカウントに対するサービス アカウント管理者 (roles/iam.serviceAccountAdmin)IAM ロールを付与するよう管理者に依頼してください。ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。

この事前定義ロールには、プロジェクト レベルで必要な the required permissions 権限が含まれています。

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

組織レベルのロール

組織レベルで必要な権限を取得するには、ユーザー アカウントまたはサービス アカウントに対する次の IAM ロールを付与するよう管理者に依頼してください。

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

この事前定義ロールには、組織レベルで必要な the required permissions 権限が含まれています。

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

コンテキストアウェア アクセス ポリシーをさまざまなリソースレベルにバインドする

同じ自動適用モードのコンテキストアウェア アクセス ポリシーを、リソース階層の異なるレベルのリソースにバインドできます。リソースがアクセスを試みると、コンテキストアウェア アクセスは、上位レベルのリソースにバインドされているポリシーを使用する前に、そのリソースにバインドされているポリシーを使用します。

たとえば、適用モードのポリシーをサービス アカウントに直接バインドし、別の適用モードのポリシーをサービス アカウントを含むプロジェクトにバインドできます。サービス アカウントがリソースにアクセスしようとすると、コンテキストアウェア アクセスはサービス アカウントにバインドされているポリシーを評価します。ポリシーがバインドされていないプロジェクト内の他のサービス アカウントの場合、コンテキストアウェア アクセスは、プロジェクトにバインドされている自動適用モードのポリシーを評価します。プロジェクト レベルのポリシーとサービス アカウント レベルのポリシーの両方で、自動適用モードがドライランに設定されている場合も同様です。

複数のポリシーを使用して、ポリシーを段階的かつ選択的にデプロイできます。たとえば、次のことができます。

  1. プロジェクト レベルでドライラン モードのポリシーをバインドし、Cloud Audit Logs でアクセス拒否イベントを確認して、想定どおりに動作していることを確認します。
  2. 自動適用モードのポリシーを特定のサービス アカウントにのみバインドします。
  3. プロジェクト レベルで自動適用モードのポリシーをバインドし、必要に応じて、制限の緩い自動適用モードのポリシーを特定のサービス アカウントにバインドします。

サービス アカウントのアクセスレベル属性

このセクションでは、サービス アカウントでサポートされているアクセスレベルの属性について説明します。

サービス アカウントでは、次の属性がサポートされています。

  • IP サブネットワーク。パブリック IP アドレスに基づいています。
  • VPC ネットワーク(プライベート IP アドレスに基づく)。
  • パブリック IP アドレスに基づく位置情報。

    サービス アカウントが Google CloudAPI にリクエストを送信すると、コンテキストアウェア アクセスはリクエストを評価し、リクエストの IP アドレスをコンテキストアウェア アクセス ポリシーで指定された IP アドレスと比較します。IP アドレスが一致すると、コンテキストアウェア アクセスによって API 呼び出しが許可されます。 IP アドレスが一致しない場合、コンテキストアウェア アクセスは API 呼び出しを拒否します。

  • Common Expression Language(CEL)式を使用したカスタム アクセスレベル。式は、アクセスを許可する場合は true、アクセスを拒否する場合は false と評価される必要があります。

    次の CEL 式は、サービス アカウントによるアクセスを制限する場合に便利です。

    リクエストが指定された 1 つ以上のプロジェクト番号から送信された場合、式は true と評価されます。

        expression: "originatesFromProjects(origin, ['projects/PROJECT_NUMBER'])"
        

    originatesFromProjects は、リクエストが指定されたプロジェクトに関連付けられたネットワークから送信されているかどうか、またリクエストがプライベート IP アドレスから送信されているかどうかを確認します。

  • 時刻。指定されたタイムゾーンでのリクエストの日時に基づきます。

    詳細については、日時アクセス条件の構成をご覧ください。

アクセスレベルを作成する

このセクションでは、組織内にアクセスレベルを作成する方法について説明します。アクセスレベルは、アクセスが許可される条件を定義します。

  1. 手順に沿って、ベーシック アクセスレベルを作成するか、カスタム アクセスレベルを作成します。

  2. アクセスレベルの完全な名前をメモします。形式は accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME です。

アクセス バインディングを作成する

選択したサービス アカウントにアクセスレベルをバインドします。これにより、アクセスレベルで定義された条件が適用されます。アクセスレベルは、単一のサービス アカウントまたはプロジェクト内のすべてのサービス アカウントにバインドできます。

アクセスレベルを特定のサービス アカウントにバインドする

このセクションでは、アクセスレベルを特定のサービス アカウントにバインドする方法について説明します。

gcloud

gcloud CLI を使用して、アクセスレベルをサービス アカウントにバインドします。

gcloud access-context-manager cloud-bindings create \
    --organization=ORGANIZATION_ID \
    --service-account=SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com \
    --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

次のように置き換えます。

  • ORGANIZATION_ID: 実際の Google Cloud組織 ID。
  • SERVICE_ACCOUNT_NAME: ターゲット サービス アカウントの ID(メールアドレスの @ 記号の前の部分)。
  • SERVICE_ACCOUNT_PROJECT_ID: ターゲット サービス アカウントを含むプロジェクトの ID。
  • POLICY_ID: Access Context Manager アクセス ポリシーの ID。
  • ACCESS_LEVEL_NAME: 作成したアクセスレベルの名前。

    アクセスレベルを適用せずにアクセスを許可しないコンテキストアウェア アクセスを使用するには、ドライラン モードでアクセスレベルをバインドします。

REST API

REST API を使用してアクセスレベルを特定のサービス アカウントにバインドするには、次のコマンドを実行します。

  1. 次の内容の request.json ファイルを作成します。

    {
      "principal": {
        "serviceAccount": "SERVICE_ACCOUNT_NAME@SERVICE_ACCOUNT_PROJECT_ID.iam.gserviceaccount.com"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    次のように置き換えます。

    • SERVICE_ACCOUNT_NAME: ターゲット サービス アカウントの ID(メールアドレスの @ 記号の前の部分)。

    • SERVICE_ACCOUNT_PROJECT_ID: ターゲット サービス アカウントを含むプロジェクトの ID。

    • POLICY_ID: Access Context Manager アクセス ポリシーの ID。

    • ACCESS_LEVEL_NAME: 作成したアクセスレベルの名前。

  2. 次のコマンドを実行します。

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json; charset=utf-8" \
      -d @request.json \
      "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    次のように置き換えます。

    • PROJECT_ID: API 呼び出しに使用するプロジェクトの ID。

    • ORGANIZATION_ID: 実際の Google Cloud組織 ID。

アクセスレベルをプロジェクト内のすべてのサービス アカウントにバインドする

このセクションでは、アクセスレベルをプロジェクト内のすべてのサービス アカウントにバインドする方法について説明します。

gcloud

gcloud CLI を使用して、プロジェクト内のすべてのサービス アカウントにアクセスレベルをバインドするには、次のコマンドを実行します。

gcloud access-context-manager cloud-bindings create \
  --organization=ORGANIZATION_ID \
  --service-account-project-number=PROJECT_NUMBER \
  --level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

次のように置き換えます。

  • ORGANIZATION_ID: 実際の Google Cloud組織 ID。
  • PROJECT_NUMBER: アクセスをバインドするすべてのサービス アカウントを含むプロジェクトのプロジェクト番号。
  • POLICY_ID: Access Context Manager アクセス ポリシーの ID。
  • ACCESS_LEVEL_NAME: 作成したアクセスレベルの名前。

REST API

REST API を使用して、プロジェクト内のすべてのサービス アカウントにアクセスレベルをバインドするには、次の操作を行います。

  1. 次の内容の request.json ファイルを作成します。

    {
      "principal": {
        "serviceAccountProjectNumber": "PROJECT_NUMBER"
      },
      "accessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
    }
    

    次のように置き換えます。

    • PROJECT_NUMBER: アクセスをバインドするすべてのサービス アカウントを含むプロジェクトのプロジェクト番号。
    • POLICY_ID: Access Context Manager アクセス ポリシーの ID。
    • ACCESS_LEVEL_NAME: 作成したアクセスレベルの名前。
  2. 次のコマンドを実行します。

    curl -H "X-Goog-User-Project: PROJECT_ID" -X POST \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    -d @request.json \
    "https://accesscontextmanager.googleapis.com/v1/organizations/ORGANIZATION_ID/gcpUserAccessBindings"
    

    次のように置き換えます。

    • PROJECT_ID: API 呼び出しに使用するプロジェクトの ID。
    • ORGANIZATION_ID: 実際の Google Cloud組織 ID。

アクセスレベルを適用してアクセスを拒否せずにコンテキストアウェア アクセスを使用するには、ドライラン モードでアクセスレベルをバインドします。

バインディング作成オペレーションの API レスポンスには、一意のバインディング ID を含むバインディングの名前が含まれます。

ドライラン モードを使用する

アクセスレベルはドライラン モードでバインドできます。ドライラン モードを使用すると、サービス アカウントは適用なしでリソースに引き続きアクセスできます。ただし、サービス アカウントがアクセスレベルに違反するアクセスを試みると、コンテキストアウェア アクセスは違反を Cloud Audit Logs に記録します。

ドライラン モードでアクセスレベルをバインドする

gcloud

ドライラン モードでアクセスレベルをバインドするには、--level パラメータを --dry-run-level に置き換えます。形式は次のとおりです。

--dry-run-level=accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME

REST API

ドライラン モードでアクセスレベルをバインドするには、次の内容を含む request.json ファイルを作成します。

{
"principal": {
  "serviceAccountProjectNumber": "TARGET_PROJECT_NUMBER"
},
"dryRunAccessLevels": ["accessPolicies/POLICY_ID/accessLevels/ACCESS_LEVEL_NAME"]
}

次のように置き換えます。

  • TARGET_PROJECT_NUMBER: ターゲット プロジェクトのプロジェクト番号。
  • POLICY_ID: Access Context Manager アクセス ポリシーの ID。
  • ACCESS_LEVEL_NAME: アクセスレベルの名前。

Cloud Audit Logs を確認する

このセクションでは、サービス アカウントのドライラン モードのアクセス拒否を Cloud Audit Logs で確認する方法について説明します。Cloud Audit Logs でドライラン モードのエントリを検索する方法については、ドライラン モードのログを表示するをご覧ください。

コンソール

Google Cloud コンソールを使用して、Cloud Audit Logs のドライラン モードのサービス アカウント アクセス拒否を表示するには、次の操作を行います。

Google Cloud コンソールで、 [ログ エクスプローラ] ページに移動します。

[ログ エクスプローラ] に移動

検索バーを使用してこのページを検索する場合は、小見出しが [Logging] の結果を選択します。

  1. Google Cloud コンソールで、プロジェクトまたは組織を選択します。

  2. [ログクエリ] フィールドに次のクエリを入力します。

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    protoPayload.metadata.dryRunEvaluationResult:DENIED
    SEARCH("SERVICE_ACCOUNT_NAME")
    
  3. 期間セレクタで、[過去 30 分]、[過去 1 時間]、[過去 24 時間] などの事前定義された相対時間を選択するか、カスタム範囲を指定します。

gcloud

gcloud CLI を使用して Cloud Audit Logs のドライラン モードのサービス アカウント アクセス拒否を表示するには、次の操作を行います。

gcloud logging read \
'protoPayload.serviceName="contextawareaccess.googleapis.com" AND
 protoPayload.metadata.dryRunEvaluationResult:DENIED AND
 SEARCH("SERVICE_ACCOUNT_NAME")' \
  --organization=ORGANIZATION_ID

次のように置き換えます。

  • ORGANIZATION_ID: 組織の ID。
  • SERVICE_ACCOUNT_NAME: サービス アカウントの ID(メールアドレスの @ 記号の前の部分)。

gcloud logging read コマンドは、相対的な期間のロギング情報を表示する --freshness フラグをサポートしています。たとえば、コマンドに --freshness=3h を追加すると、過去 3 時間のドライラン モードのログエントリを表示できます。

次のステップ