アーキテクチャで複数のサービスを使用している場合、これらのサービスは同期または非同期で相互に通信する必要があります。これらのサービスの多くは非公開で、アクセスには認証情報が必要です。
非同期通信では、次の Google Cloud サービスを使用できます。
- Cloud Tasks(1 対 1 の非同期通信を行う場合)。
- Pub/Sub(1 対多、1 対 1、多対 1 の非同期通信を行う場合)
- Cloud Scheduler(定期的にスケジュール設定された非同期通信を行う場合)
- Eventarc(イベントベースの通信を行う場合)
いずれの場合も、使用中のサービスが、設定した構成に基づいて受信側のサービスとの通信を管理します。
ただし、同期通信の場合は、サービスがエンドポイント URL を使用して HTTP 経由で別のサービスを直接呼び出します。このユースケースでは、各サービスが特定のサービスに対してのみリクエストを送信できるようにします。たとえば、login
サービスの場合、user-profiles
サービスにはアクセスできますが、search
サービスにはアクセスできません。
この場合は、IAM と、その作業に必要な権限の最小セットが付与されたサービスごとのユーザー管理サービス アカウントに基づいてサービス ID を使用することをおすすめします。
さらに、リクエストで呼び出し側サービス ID の証明を提示する必要があります。これを行うには、Google 署名付き OpenID Connect ID トークンをリクエストの一部として追加するように呼び出し側サービスを構成します。
サービス アカウントを設定する
サービス アカウントを設定するには、呼び出し元のサービス アカウントを受信側サービスのプリンシパルにすることで、呼び出し側サービスからのリクエストを受け入れるように受信側サービスを構成します。そのサービス アカウントに Cloud Run 起動元(roles/run.invoker
)のロールを付与します。該当するタブの手順に沿って、これらの作業を行います。
コンソール UI
Google Cloud Console に移動します。
受信側のサービスを選択します。
右上隅にある [情報パネルを表示] をクリックして、[権限] タブを表示します。
[プリンシパルを追加] をクリックします。
呼び出し側のサービスの ID を入力します。これは通常、デフォルトでメールアドレス
PROJECT_NUMBER-compute@developer.gserviceaccount.com
です。[ロールの選択] プルダウン メニューから、
Cloud Run Invoker
ロールを選択します。[保存] をクリックします。
gcloud
gcloud run services add-iam-policy-binding
コマンドを使用します。
gcloud run services add-iam-policy-binding RECEIVING_SERVICE \ --member='serviceAccount:CALLING_SERVICE_IDENTITY' \ --role='roles/run.invoker'
ここでは、RECEIVING_SERVICE
は受信側サービスの名前で、CALLING_SERVICE_IDENTITY
はサービス アカウントのメールアドレス(デフォルトでは PROJECT_NUMBER-compute@developer.gserviceaccount.com
)です。
ID トークンの取得と構成
呼び出し側のサービス アカウントに適切なロールを付与したら、次の操作を行う必要があります。
受信側のサービスの URL に設定されたオーディエンス クレーム(
aud
)を使用して、Google 署名付き ID トークンを取得します。aud
値は、特定のトラフィック タグにリクエストを送信する場合でも、サービスの URL として残す必要があります。受信側サービスに対するリクエストの
Authorization: Bearer ID_TOKEN
ヘッダーに ID トークンを含めます。
このプロセスを最も簡単かつ信頼性の高い方法で管理するには、以下に示すように認証ライブラリを使用してこのトークンを生成し、適用します。このコードは、ライブラリによって認証情報が取得される Google Cloud 外のあらゆる環境で機能します(ローカル アプリケーションのデフォルト認証情報をサポートする環境を含む)。
Node.js
Python
Go
Java
メタデータ サーバーの使用
なんらかの理由で認証ライブラリを使用できない場合は、コンテナが Cloud Run で実行されている間、コンピューティング メタデータ サーバーから ID トークンを取得できます。この方法は、ローカルマシンからなど、Google Cloud の外部では機能しないことに注意してください。
curl "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=[AUDIENCE]" \
-H "Metadata-Flavor: Google"
AUDIENCE は、起動しているサービスの URL です。
このサービス間の認証方式を使用するアプリケーションのエンドツーエンドのチュートリアルは、安全な Cloud Run サービスのチュートリアルをご覧ください。
認証済みリクエストの受信
受信側のプライベート サービス内で、Authorization ヘッダーを解析して署名なしトークンによって送信される情報を受信できます。
Python
Google Cloud の外部からの呼び出し
Workload Identity 連携を使用するか、ダウンロードしたサービス アカウント キーを使用して、Google Cloud の外部からプライベート サービスを呼び出すこともできます。以降のセクションでは、この両方の方法について説明します。
Workload Identity 連携を使用する
Workload Identity 連携でサポートされている ID プロバイダを環境で使用している場合は、次の方法で Cloud Run サービスの認証を安全に行うことができます。
このページのサービス アカウントの設定の説明に従ってサービス アカウントを設定します。
Workload Identity 連携の構成の説明に従って ID プロバイダの Workload Identity 連携を構成します。
外部 ID にサービス アカウントの権限借用を許可するの手順を行います。
REST API を使用して有効期間の短いトークンを取得します。ただし、
generateAccessToken
を呼び出してアクセス トークンを取得する代わりに、generateIdToken
を呼び出して ID トークンを取得します。cURL の使用例を次に示します。
ID_TOKEN=$(curl -0 -X POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT:generateIdToken \ -H "Content-Type: text/json; charset=utf-8" \ -H "Authorization: Bearer $STS_TOKEN" \ -d @- <<EOF | jq -r .token { "audience": "SERVICE_URL" } EOF) echo $ID_TOKEN
ここで、
SERVICE_ACCOUNT
は Workload Identity プールがアクセスするように構成されているサービス アカウントのメールアドレスです。SERVICE_URL
は、呼び出す Cloud Run サービスの URL です。この値は、特定のトラフィック タグにリクエストを送信する場合でも、サービスの URL として残す必要があります。$STS_TOKEN
は、Workload Identity 連携の前の手順で受信したセキュリティ トークン サービス トークンです。
ID トークンを取得したら、受信側のサービスに対するリクエストの Authorization: Bearer ID_TOKEN
ヘッダーにそのトークンを含めます。
ダウンロードしたサービス アカウント キーを使用する
環境で Workload Identity 連携の使用が適切でない場合は、ダウンロードしたサービス アカウント キーを使用して認証できます。上記のように、アプリケーションのデフォルト認証情報で認証ライブラリを使用するようにクライアント コードを更新します。
自己署名 JWT を使用して Google 署名付き ID トークンを取得できますが、作業はかなり複雑になり、エラーが発生しやすくなります。基本的な手順は次のとおりです。
target_audience
クレームを受信側サービスの URL に設定して、サービス アカウント JWT に自己署名します。target_audience
値は、特定のトラフィック タグにリクエストを送信する場合でも、サービスの URL として残す必要があります。Google によって署名された ID トークンと自己署名された JWT を交換します。このトークンでは、
aud
クレームに上の URL が設定されています。サービスに対するリクエストの
Authorization: Bearer ID_TOKEN
ヘッダーに ID トークンを含めます。
上記の手順のサンプルについては、この Cloud Functions の例で確認できます。