3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Cloud の IAP + WIF + IdP (Keycloak) でログイン実装

3
Last updated at Posted at 2026-05-12

はじめに

Google Cloud環境でのログイン機能を実装するとき、何を使っていますか?

「すでに社内で Okta や Keycloak、Microsoft Entra ID などの IdP を運用しているのに、Google Cloud 用に別のユーザー管理をしたくない…」と悩んだことはないでしょうか。

今回は、そんな「社内 IdP をアプリケーションのログインとしてそのまま使いたい」という方に向けた内容となります。

既存の社内 IdP(今回は Keycloak)と Identity-Aware Proxy (IAP)、Workforce Identity Federation (WIF) を組み合わせ、社内アカウントによるアプリケーションログインを実装しました。

なぜ Identity Platform ではなく Workforce Identity Federation (WIF) か

Google Cloud で外部 IdP と連携する際、Identity Platform という選択肢もあります。

しかし、すでに社内 IdP でユーザーやグループの管理が統合されている場合、Identity Platform の採用には以下の課題があります。

  • シャドウアカウントの発生(二重管理の懸念): Identity Platform では、ログイン時に Google Cloud 側にユーザーのレコードが作成されてしまいます。退職者のレコードがクラウド上に残り続けるなど、ガバナンス上の管理対象が増えてしまいます。
  • 権限管理の二度手間: Identity Platform 単体では、社内 IdP 側の「グループ情報」を使った柔軟なアクセス制御(IAP との連携)を構築するのが難しく、アプリ側や Google 側で別途権限を管理する手間が生じがちです。

Workforce Identity Federation (WIF) を使えば、Google Cloud 側にユーザー情報を一切作らず、社内 IdP を直接信頼する「ステートレス」な構成が取れます。
ユーザーの追加・削除はもちろん、IAP のアクセス権限(ポリシー)も社内 IdP のグループ情報に直接マッピングできるため、Google Cloud 側の運用負荷を最小限に抑え、すべての権限管理を社内 IdP に集約できます。


アーキテクチャ

主要コンポーネント

コンポーネント 機能 役割
IAP Google Cloud リソースへのアクセスを保護するリバースプロキシ。認証済みユーザーのみ通過させる アプリへのアクセス制御。未認証ユーザーを認証フローへ誘導する
WIF 外部 IdP のアイデンティティを Google Cloud の ID に変換するフェデレーション基盤 社内 IdP の SAML アサーションを Google トークンに変換する
OAuth Client OAuth 2.0 の認可フローでクライアントを識別するための認証情報(Client ID / Secret) IAP が WIF と連携するための認証情報
社内 IdP ユーザー認証・認可を一元管理する IdP / SSO ソリューション SAML SP(WIF)からの AuthnRequest を処理する

今回は社内 IdP として Keycloak(SAML) を使用します。

全体構成

認証フロー


WIF 設定手順

WIF の設定は Organization レベルの権限(roles/iam.workforcePoolAdmin)が必要です。

前提: 社内 IdP が起動しており、SAML メタデータ XML ファイルが取得できる状態であること。

必要な情報

項目 説明
Organization ID Google Cloud Organization ID(数字のみ) 123456789012
IdP メタデータ 社内 IdP の SAML メタデータ XML ファイル IdP から取得した .xml ファイル

Step 1: Workforce Identity プールの作成

Google Cloud Console で操作します。

  1. [IAM と管理] > [Workforce Identity の連携] を開く

  2. [プールを作成] をクリック

  3. 以下を入力する:

    • 名前: myapp WIF Pool
    • プール ID: myapppool
    • 説明: myapp用 Workforce Identity Federation Pool(任意)
  4. [次へ] をクリック

    スクリーンショット 2026-05-12 11.59.37.png

Step 2: SAML プロバイダの追加

プール作成後、続けてプロバイダを追加します。
今回は社内 IdP として Keycloak(SAML) を使用します。

  1. IdP のベンダー [Keycloak] を選択する

  2. プロトコルとして [SAML] を選択する

  3. 以下を入力する:

    • 名前: myapp SAML Provider

    • プロバイダ ID: myapp-saml-provider

    • IdP メタデータ: 社内 IdP のメタデータ XML ファイルをアップロード

      スクリーンショット 2026-05-12 11.58.17.png

  4. [続行] をクリックし、URL2つをメモしておく(後で使います)

    スクリーンショット 2026-05-12 12.13.29.png

  5. [続行] をクリックし、属性マッピングを設定する:

    • google.subjectassertion.subject
    • attribute.emailassertion.attributes.email[0]

    属性マッピングのポイント:

    • google.subject: SAML の NameID(メールアドレス)をユーザー識別子として使用する

    • attribute.email: SAML アトリビュートの email を Google 側の email にマッピングする

      スクリーンショット 2026-05-12 12.02.56.png

  6. [プロバイダを追加] をクリック

Step 3: 社内 IdP 側に SAML クライアントを登録

WIF の SAML プロバイダ作成後、社内 IdP 側にも WIF を SAML SP(サービスプロバイダ)として登録する必要があります。

スクリーンショット 2026-05-12 12.16.32.png


OAuth 追加手順

IAP が WIF を使って認証するための OAuth Client を作成します。

注意: ここで作成する OAuth Client は、WIF(IAP)専用のものです。gcloud iam oauth-clients で管理される WIF 用 OAuth Client であり、通常の Google OAuth 2.0 クライアント(APIs & Services > Credentials で作成するもの)とは別物です。IAP の認証フローでのみ使用します。

必要な情報

変数名 説明
PROJECT_ID Google Cloud プロジェクト ID

Step 1: プロジェクト設定

gcloud config set project "<PROJECT_ID>"

Step 2: OAuth Client の作成

Client ID は Google Cloud が払い出すため、まずダミーの Redirect URI で作成します。

gcloud iam oauth-clients create "myapp-iap-oauth-client" \\
  --project="<PROJECT_ID>" \\
  --location="global" \\
  --client-type="confidential-client" \\
  --allowed-grant-types="authorization-code-grant,refresh-token-grant" \\
  --allowed-scopes="<https://www.googleapis.com/auth/cloud-platform,openid>" \\
  --allowed-redirect-uris="<https://iap.googleapis.com/v1/oauth/clientIds/placeholder:handleRedirect>" \\
  --display-name="myapp IAP OAuth Client" \\
  --description="myapp IAP用 OAuth Client"

Step 3: Client ID の取得

OAUTH_CLIENT_ID=$(gcloud iam oauth-clients describe \\
  "projects/<PROJECT_ID>/locations/global/oauthClients/myapp-iap-oauth-client" \\
  --format="value(clientId)")
echo "OAuth Client ID: ${OAUTH_CLIENT_ID}"

出力された値を OAUTH_CLIENT_ID として記録します。

Step 4: Redirect URI の更新

gcloud iam oauth-clients update \\
  "projects/<PROJECT_ID>/locations/global/oauthClients/myapp-iap-oauth-client" \\
  --allowed-redirect-uris="<https://iap.googleapis.com/v1/oauth/clientIds/${OAUTH_CLIENT_ID}:handleRedirect>"

Step 5: Credentials の作成

gcloud iam oauth-clients credentials create "myapp-iap-oauth-credential" \\
  --oauth-client="myapp-iap-oauth-client" \\
  --location="global" \\
  --display-name="myapp IAP OAuth Credential"

出力の clientSecret フィールドを OAUTH_CLIENT_SECRET として記録します。後から確認したい場合は以下で取得できます:

gcloud iam oauth-clients credentials describe "myapp-iap-oauth-credential" \\
  --location="global" \\
  --oauth-client="myapp-iap-oauth-client"

IAP 設定手順

WIF と OAuth Client を IAP のバックエンドサービスに紐付けます。

必要な情報

変数名 説明
PROJECT_ID Google Cloud プロジェクト ID
BACKEND_SERVICE_NAME IAP 保護対象のバックエンドサービス名
WIF_POOL_ID myapppool(WIF 設定担当者から受領)
OAUTH_CLIENT_ID OAuth 手順 Step 3 で取得した値
OAUTH_CLIENT_SECRET OAuth 手順 Step 5 で取得した値

Step 1: IAP 設定ファイルの作成

以下の内容を /tmp/iap_settings.yaml として保存します:

access_settings:
  identity_sources: ["WORKFORCE_IDENTITY_FEDERATION"]
  workforce_identity_settings:
    workforce_pools: ["locations/global/workforcePools/<WIF_POOL_ID>"]
    oauth2:
      client_id: "<OAUTH_CLIENT_ID>"
      client_secret: "<OAUTH_CLIENT_SECRET>"

Step 2: IAP 設定の適用

gcloud iap settings set /tmp/iap_settings.yaml \\
  --project="<PROJECT_ID>" \\
  --resource-type="backend-services" \\
  --service="<BACKEND_SERVICE_NAME>"

Step 3: WIF ユーザーへのアクセス権付与

WIF Pool に属するすべてのユーザーへ IAP アクセス権を付与します:

gcloud iap web add-iam-policy-binding \\
  --member="principalSet://iam.googleapis.com/locations/global/workforcePools/<WIF_POOL_ID>/*" \\
  --role="roles/iap.httpsResourceAccessor" \\
  --project="<PROJECT_ID>" \\
  --resource-type="backend-services" \\
  --service="<BACKEND_SERVICE_NAME>"

補足: 上記は Pool 内の全ユーザーにアクセスを許可する設定です。実運用では、SAML 属性(グループ情報など)を使って principalSet://iam.googleapis.com/locations/global/workforcePools/<WIF_POOL_ID>/group/admin-team のように特定のグループのみに制限することも可能です。


動作確認

アプリケーションURLにアクセス

アプリケーションURLにアクセスすると、何回かリダイレクトが走った後、IdPのログイン画面が出れば、IAP, WIFの設定が成功しています。

そこからログイン後、アプリケーションが表示されれば全て成功となります。

スクリーンショット 2026-05-12 12.34.50.png


苦労したこと

1. WIF Pool は Organization レベルのリソース

WIF Pool は Google Cloud Organization に紐づくリソースであり、特定のプロジェクトには属しません。作成には roles/iam.workforcePoolAdmin組織レベル で持つアカウントが必要です。プロジェクトレベルの Owner でも作成できないため、注意が必要です。

2. WIF Pool 内の Provider は 1 つに限定する

IAP 対応のアプリケーションごとに構成できる Workforce プールは 1 つのみで、Workforce プールに含めることができるプロバイダは 1 つのみです。

Pool 内に Provider を複数作成すると、アプリへのアクセス時に 701 エラーが発生します。

IAP が認証フローを開始する際、WIF Pool 内のどの Provider にリダイレクトするかを一意に決定できないためエラーになる。IAP + WIF の構成では、1 Pool につき Provider は 1 つに留める。

3. ここで作る OAuth Client は通常の OAuth 2.0 クライアントとは別物

gcloud iam oauth-clients で管理される WIF 専用の OAuth Client です。通常の Google OAuth 2.0 クライアント(APIs & Services > Credentials で作成するもの)とは異なり、IAP の認証フロー以外では使用できません。

4. WIF Pool を無効化→有効化すると IAP が 401 を返すようになる

症状:

WIF Pool を一度無効化してから再度有効化すると、その後アプリへのアクセス時に IAP が 401 エラーを返すようになる。社内 IdP のログイン画面へのリダイレクトすら起きない。

根本原因:

WIF Pool の無効化→有効化操作により、IAP と OAuth Client の紐付けが失われる

解決策:

iap_settings.yaml を使って全バックエンドサービスの IAP 設定を正しい OAuth Client で上書きする:

access_settings:
  identity_sources: ["WORKFORCE_IDENTITY_FEDERATION"]
  workforce_identity_settings:
    workforce_pools: ["locations/global/workforcePools/<WIF_POOL_ID>"]
    oauth2:
      client_id: "<OAUTH_CLIENT_ID>"
      client_secret: "<OAUTH_CLIENT_SECRET>"
gcloud iap settings set /tmp/iap_settings.yaml \\
  --project="<PROJECT_ID>" \\
  --resource-type="backend-services" \\
  --service="<BACKEND_SERVICE_NAME>"

WIF Pool を操作した後は、必ず IAP の OAuth Client 設定を確認する習慣をつけておくとよい。

5. Keycloak のログイン操作で 431 が発生する

注: 以下は今回の検証で使用した Keycloak(Cloud Run)での事例です。

症状:

Keycloak のログイン画面は表示されるが、ログインボタンを押すと 431 Request Header Fields Too Large になる。

根本原因:

IAP + WIF アーキテクチャでは、WIF が生成する state パラメータに IAP のコンテキスト(redirect URI・code challenge 等)が丸ごと埋め込まれるため、Keycloak に届くリクエストラインが 7.5KB 前後になる。Keycloak(Quarkus HTTP サーバー)のデフォルト上限は約 4KB であるため、この組み合わせでは常に上限を超えてしまう。

解決策:

Keycloak の Cloud Run 環境変数でヘッダーサイズ上限を引き上げる:

環境変数
QUARKUS_HTTP_LIMITS_MAX_INITIAL_LINE_LENGTH 65536
QUARKUS_HTTP_LIMITS_MAX_HEADER_SIZE 65536
QUARKUS_HTTP_LIMITS_MAX_HEADER_LIST_SIZE 65536

Terraform で管理している場合は必ず IaC に反映させること。手動で gcloud run services update した場合、次回の terraform apply で環境変数が消えてしまう。


6. IdP のログイン画面で「Cookie not found」エラーが発生する

注: 以下は今回の検証で使用した Keycloak(Cloud Run)での事例です。社内 IdP の種類や構成によっては異なる原因・対処が必要になる場合があります。

スクリーンショット 2026-05-11 18.28.24.png

症状:

IAP → WIF → IdP のリダイレクトは成功し、ブラウザに IdP のログイン画面が表示される。しかしログインボタンを押すと Cookie not found エラーが返り、認証が完了しない。

根本原因:

HTTP レスポンスに Set-Cookie ヘッダーが含まれていなかった。Keycloak はログインセッションを Cookie で管理するため、Cookie が設定されないとセッションが成立せずエラーになる。

調査過程:

IAP → WIF → Keycloak というリダイレクトの連鎖の中で、state パラメータ等が暗号化・エンコードされ、URL 文字列が非常に大きくなっていた。これが Cookie の設定に何らかの影響を与えている可能性があった。

検証のため、Cloud Run ではなく GCE(Compute Engine)上に Keycloak を立てたところ、同じ認証フローで問題なく動作した。つまり原因は Keycloak 自体や認証フローの設定ではなく、Cloud Run 側の通信プロトコルにあると判断した。

解決策:

Cloud Run のポートプロトコルを h2c(HTTP/2 cleartext)に変更したところ、Set-Cookie が正しくレスポンスに含まれるようになり、ログインが成功した。

スクリーンショット 2026-05-12 11.38.30.png

h2c(HTTP/2)に変更することで改善される技術的な理由:

HTTP/1.1 では、Keycloak が発行する複数の大きな Cookie(AUTH_SESSION_IDKC_RESTARTKEYCLOAK_SESSION 等)をプレーンテキストのヘッダーとして送信する。ロードバランサーやプロキシにはヘッダーサイズの上限があり、合計サイズが上限を超えると Set-Cookie ヘッダーが欠落・切り捨てされることがある。

HTTP/2(h2c)では以下の 2 つの仕組みによりこの問題が解消される:

  1. HPACK によるヘッダー圧縮: HTTP/2 は HPACK 形式でヘッダーを圧縮して送受信する。同じ Cookie 情報をより小さいサイズで伝送できるため、サイズ起因の欠落リスクが減る。
  2. HEADERS / CONTINUATION フレームによる分割伝送: HTTP/2 はヘッダーをフレーム単位で扱う。1 フレームに収まらない大きなヘッダーは CONTINUATION フレームで分割して送信され、受信側で確実に結合される。HTTP/1.1 にはこの仕組みがなく、サイズ超過時に単純に切り捨てられる。
[HEADERS frame]      → Set-Cookie ヘッダーの先頭部分
[CONTINUATION frame] → Set-Cookie ヘッダーの続き
[DATA frame]         → レスポンスボディ

まとめ

フェーズ 主な作業
① WIF 設定 WIF Pool と SAML Provider を作成し、WIF Pool ID を共有する
② OAuth 設定 OAuth Client と Credentials を作成する
③ IAP 設定 IAP に WIF + OAuth を紐付け、ユーザーへアクセス権を付与する

この構成により、社内 IdP のユーザー管理を変えるだけでアプリへのアクセス制御を一元管理できます。既存の社内 IdP を活用するため、IdP 自体の新たな構築は不要で、WIF・OAuth・IAP の設定のみで導入できる点が大きな利点です。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?