サインインできても、入れるかはGoogle Cloudが別に決めている
Microsoft Entra ID のアカウントで、Google Cloud 上のアプリを開けるようにできます。ただし「Entra ID でサインインできた」は「アプリを見られる」を意味しません。
認証と認可が、別のシステムで動いているからです。私はこの構成を Terraform で組んだあと、仕組みを人に説明する機会がありました。そこで「どこで誰が判定しているのか」が伝わりにくいと分かったので、整理し直したのがこの記事です。
設定手順ではなく、中で何が起きているかを扱います。
本記事のまとめ
- 認証は Entra ID、認可は Google Cloud の IAM。判定しているのはアプリではなく IAP(Identity-Aware Proxy。アプリの手前で通すか止めるかを決める Google Cloud の仕組み)である。
- プールは利用者名簿ではない。Google Cloud 側に利用者もグループも登録しない。
- 所属グループは保存されず、アクセスのたびにトークンで運ばれてくる。
- プール ID は後から変えられない。構築前に決めておく必要がある。
入れないときの切り分けは、「Entra IDでサインインは通るのにGoogle Cloudが403|原因はグループ」で扱います。

認証と認可の違い|身分証の提示と、入室許可の判断
認証と認可は、別のシステムが別のタイミングで行っています。この 2 つはよく混ざりますが、担い手が違います。
| 答える問い | 例えるなら | 担い手 | |
| 認証 | この人は誰か | 受付で身分証を見せて本人確認する | Entra ID |
| 認可 | その人はこれを見てよいか | どの部屋に入れるかを入館ルールで決める | Google Cloud の IAM |
大事なのは、身分証そのものに「どの部屋に入れるか」は書かれていないということです。サインインは通ったうえで「権限がありません」と止められることがあります(HTTP 403)。これは故障ではなく、認証と認可が分かれていることの現れです。
この分担には利点があります。パスワード、多要素認証、アカウントの有効と無効は、すべて Entra ID 側の設定がそのまま適用されます。Google Cloud 側は認証に関与せず、利用者のパスワードを持ちません。
この橋渡しをするのが、Google Cloud の Workforce Identity 連携(Workforce Identity Federation)です。詳しくは Google Cloud の公式ドキュメント 「Workforce Identity 連携の概要」にまとまっています。
この設定は IAP のページではなく、Cloud Run のサービス一覧で対象のサービスを開き、「セキュリティ」タブを選ぶと出ます。

登場人物と、それぞれが決めていること
ルールを持つのが IAM、判定するのが IAP です。役割が分かれているので、まず誰が何を決めているかを並べます。
| 登場人物 | 何を決めているか | どこにあるか |
| Entra ID | この人が本人かどうか。どのグループに所属しているか | 利用者側のテナント |
| Workforce Identity 連携(プール) | Entra ID から届いた情報を、Google Cloud が扱える形に読み替える | Google Cloud 組織 |
| IAP | アプリの手前で、通すか止めるかを判定する | Google Cloud プロジェクト |
| IAM | 誰に何を許可するかのルールを保持する | Google Cloud プロジェクト |
| アプリ(Cloud Run) | —(判定に関与しない) | Google Cloud プロジェクト |
アプリは「誰が来たか」を知ることはできますが、許否の判断には関わりません。そのためアプリ側に認証の仕組みを実装する必要がありません。既存のアプリをそのまま置けるのが、この構成を選ぶ理由のひとつになります。
この一覧はWorkforce Identity 連携のページで組織を選ぶと出ます。見出しは「Workload Identity プール」と表示されますが、ここに並ぶのは Workforce のプールです。見分けるなら、表示名ではなくログイン URL が auth.cloud.google/signin で始まるかを見てください。

Workforce Identityプールに利用者は登録しない
プールは利用者名簿ではありません。ここが一番誤解されるところです。
Google Cloud は Entra ID のアカウントをそのまま理解できません。そこで「Entra ID から来た人を受け入れる窓口」を Google Cloud 側に 1 つ置きます。これが Workforce Identity プールです。プールは「どの Entra ID テナントを信頼するか」を知っているだけです。
| 中身 | |
| プール本体が持つもの | プール ID、表示名、サインインセッションの有効期間、誤削除防止の設定 |
| プールの下の Provider が持つもの | どの Entra ID テナントを信頼するか、クライアント ID とシークレット、属性の読み替え規則 |
| プールに登録しないもの | 利用者とグループ |
Google Cloud 側にグループを作る作業は存在しません。グループの実体は Entra ID 側にあり、そこが唯一の正本です。これが、利用者の追加と削除が Entra ID 側の操作だけで済む理由です。同じ名簿を 2 か所に持たないので、二重管理が起きません。
Workload Identityとは別物
名前がよく似た別の機能があり、会話や資料で混ざります。Workforce は人間の利用者、Workload は CI/CD などのマシンが対象です。GitHub Actions から Google Cloud へキーなしで認証する構成は Workload のほうで、この記事で扱うものとは別系統です。
プールIDは後から変えられない
プール ID は Google Cloud 全体で一意で、他の組織を含めて重複できません(公式ドキュメント)。調べた時点では、空きを事前に確認する方法は見つかりませんでした。作成後に ID を変更できないため、変えるなら作り直しになり、Entra ID 側の設定もアクセス許可もすべて再設定になります。
理由は、プール ID がサインイン用の URL と、Entra ID 側に登録する戻り先の URL に埋まるからです。Terraform の出力を見ると、どちらも組み立て規則が決まっています。
サインイン用の URL: https://auth.cloud.google/signin/locations/global/workforcePools/<プール ID>/providers/<Provider ID>?continueUrl=...
Entra ID 側に登録する戻り先の URL: https://auth.cloud.google/signin-callback/locations/global/workforcePools/<プール ID>/providers/<Provider ID>プール ID を変えると、この 2 つの URL が両方変わります。Entra ID 側の登録も直す必要があるため、命名は構築前にすり合わせておくことをおすすめします。
この画面は、同じ Workforce Identity 連携のページでプールを開き、プロバイダの名前をクリックすると出る「プロバイダの詳細」です。

アクセス1回で何が起きているか
所属グループは、アクセスのたびに Entra ID から届きます。先に用語を 2 つ決めておきます。
ID トークンは、サインインが成功したときに Entra ID が発行する署名付きの小さなデータです。改変すると署名が合わなくなるため、受け取った側は「確かに Entra ID が発行したもの」と判定できます。
クレームは、その ID トークンに入っている「この利用者はこういう属性を持つ」という申し立て 1 項目です。「主張」という意味の語です。中身はこうなっています(値はすべて架空の例で、実環境のものではありません)。
{
"iss": "https://login.microsoftonline.com/8f4c2b17-5a93-4d6e-b0c1-7e2d9a84f531/v2.0",
"aud": "a37d9e42-6c18-4b05-9f73-2e8c41d6b907",
"iat": 1790880000,
"exp": 1790883600,
"oid": "5d2a7c64-91e3-4f80-a6b5-c83f107e9d42",
"name": "山田 太郎",
"preferred_username": "taro.yamada@example.com",
"groups": [
"2b85f3d1-47ac-4e29-8d60-1f9c53a7b0e8",
"7e14c9a6-3d58-42b7-95f1-6a0b82dc43fe"
]
}oid は利用者のオブジェクト ID で、テナント内で変わらない識別子です。groups は所属グループのオブジェクト ID の一覧で、表示名ではありません。見てのとおりグループ名も部署名も入っておらず、並んでいるのは ID だけです。
残りは出どころと宛先です。iss が発行元の Entra ID テナント、aud が受け取り手として登録されたクライアント ID、iat と exp が発行時刻と有効期限を表します。
この ID トークンが、アクセスのたびに次の順で運ばれてきます。矢印に振った番号は、このあとの表と同じ番号です。

各ステップで起きていることは次のとおりです。
| # | 起きていること |
| 1 | 利用者がアプリの URL を開く。IAP が「まだ認証されていない」と判定する |
| 2 | IAP がサインイン用の URL へ転送する。この URL にプール ID と Provider ID が含まれる |
| 3 | 転送された利用者のブラウザがプールへサインインを要求する。このために専用の OAuth クライアントが必要 |
| 4 | プールが、信頼先として登録された Entra ID テナントへ転送する |
| 5 | 利用者が Entra ID でサインインする。多要素認証などは Entra ID 側の設定に従う |
| 6 | Entra ID が引換券(認可コード)を、事前登録された戻り先 URL へ返す。トークン自体をブラウザに流す方式は使わない |
| 7 | プールが、引換券をクライアント ID とクライアントシークレットと引き換えに ID トークンを受け取る |
| 8 | 足りない属性を補うため、Entra ID の別のエンドポイントから得た情報をマージする |
| 9 | 読み替え規則に従って、oid と groups を Google Cloud 側の属性として組み立てる |
| 10 | IAP が IAM を評価する。届いたグループ一覧と、許可設定に書かれたグループを照合する |
| 11 | 許可ならアプリを表示する。不許可なら 403 |
#7 がクライアントシークレットを使う箇所です。ここで使うため、シークレットの有効期限が切れると全利用者がこの段階で止まります。IAP 側の設定については Google Cloud の公式ドキュメント 「Workforce Identity 連携で IAP を使用する」に手順があります。
#4 と #5 のあいだで、画面は Microsoft に切り替わります。Google アカウントでログイン済みのブラウザでも、Google を選ぶ画面は出ません。アプリごとに認証元が 1 つに固定されているためです。実際の画面はCloud RunをEntra IDで認証|IAP×Workforce Identity Federationに載せています。
この番号は、入れないときに「どこが切れたか」を指す目印になります。症状と番号の対応は別記事にまとめました。
まとめ
Workforce Identity 連携は、Entra ID が本人確認した結果を毎回トークンで受け取り、Google Cloud の IAM と照合する仕組みです。名簿を持ち合うのではありません。
- 認証は Entra ID、認可は Google Cloud の IAM。判定しているのはアプリではなく IAP なので、アプリ側に認証を実装しなくてよい。
- プールに利用者とグループは登録しない。Google Cloud 側にグループを作る作業は存在せず、Entra ID 側が唯一の正本になる。
- 所属グループは保存されず、アクセスのたびに ID トークンで運ばれてくる。
- プール ID はサインイン URL と戻り先 URL に埋まるため、後から変えられない。構築前に決めておく。
なお、コンソールの画面構成やタブの名前、プール ID の制約は変わります。実際に設定するときは、最新を公式ドキュメントで確認してください。
ここまでが「正しく動いているときに何が起きているか」です。サインインは通るのに 403 で止まる、あるいは特定の人だけ入れない、という状態になったら、「Entra IDでサインインは通るのにGoogle Cloudが403|原因はグループ」で症状ごとの切り分けを扱っています。

