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

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

制限事項

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

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

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

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

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

Cloud Build と Cloud Run を使用する場合は、次の組み込み 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. Google Cloud CLI をインストールします。

  9. 外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。

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

    gcloud init
  11. 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 プロジェクトの名前に置き換えます。

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

  13. Google Cloud CLI のコンポーネントを更新します。
    gcloud components update --quiet
  14. まだ作成していない場合は、プロジェクトにサービス アカウントを作成します。このサービス アカウントは、アクセス ポリシーのターゲットです。

必要なロール

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

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

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

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

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

組織レベルのロール

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

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

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

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

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

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

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

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

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

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

このセクションでは、サービス アカウントでサポートされているアクセスレベルを一覧表示します。

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

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

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

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

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

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

        expression: "originatesFromProjects(origin, [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: ターゲット サービス アカウントの名前(メールアドレスではない)
  • SERVICE_ACCOUNT_PROJECT_ID: ターゲット サービス アカウントを含むプロジェクトの ID
  • POLICY_ID: アクセス ポリシーの 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: ターゲット サービス アカウントの名前(メールアドレスではない)

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

    • POLICY_ID: アクセス ポリシーの 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 CloudID。

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

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

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: アクセス ポリシーの 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: アクセス ポリシーの 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: アクセス ポリシーの 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: サービス アカウントの名前

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

トラブルシューティング

このセクションでは、サービス アカウントのコンテキストアウェア アクセスのトラブルシューティング方法について説明します。

一般的なトラブルシューティング

  1. Cloud Audit Logs を確認します。

    次のログクエリを使用して、ログエントリを確認してください。

    protoPayload.serviceName="contextawareaccess.googleapis.com"
    
  2. コンテキストアウェア アクセスが適用イベントをログに記録するときに報告するアクセスレベルのリソース名を確認します。

  3. アクセスレベルが組織レベルのリソースであることを確認します。

  4. アクセス ポリシーのアクセスレベルが、サービス アカウントでサポートされている属性に基づいていることを確認します。

  5. アクセス ポリシーが目的のサービス アカウントにバインドされていることを確認します。

  6. アクセス ポリシーによってユーザー ID のアクセスが制限されていないことを確認します。これは、ユーザー ID がバインドされたアクセス ポリシーを持つ Google グループのメンバーである場合に発生する可能性があります。このポリシーによりユーザーのアクセスが制限され、サービス アカウントへの呼び出しフローが妨げられる可能性があります。

  7. セキュリティ管理者にお問い合わせください。

アクセスが拒否されました

次の理由によりアクセスが拒否されます。

  • アクセス ポリシーは、ドライラン モードではなく適用モードでバインドされています。

    強制適用ではなく、ドライラン モードを使用すると、サービス アカウントがリソースにアクセスし、リソースへのアクセスを実際に拒否することなく強制適用イベントをログに記録できます。また、一般的なトラブルシューティングの手順に沿って対応することもできます。

  • アクセスレベルを更新して、より多くのソースを含める必要があります。たとえば、アクセスレベルの作成時に含まれていなかった IP アドレスが使用されている場合などです。

次のステップ