🔒

Cloud Run で Identity-Aware Proxy (IAP) を使う

7 min read

執筆時点で Public Preview な内容を扱っています。GA になった際に内容に誤りが生じる場合があるため、最新の一次情報も確認してください。

Cloud Run は Google Cloud Platform (GCP) で提供されている Serverless Computing の1つで、Container のフルマネージドホスティングサービスです。

Identity-Aware Proxy (IAP) は GCP で提供されている、アプリケーションレベルの認証、承認のためのアクセス制御サービスです。

これまで、IAP は GCEGKEGAE でしか使えませんでした。
そのため Cloud Run で認証を行う場合はアプリケーションに実装するか、Cloud Endpoints と ESPv2 を用いる 必要がありました。

2020年5月3日に Cloud Run (フルマネージド) で IAP が 使えるようになった ので、試してみたいと思います。

https://cloud.google.com/iap/docs/concepts-overview?hl=en

現時点では Public Preview です。

TL;DR

Serverless NEG を使い HTTPS LB と Cloud Run を紐付け、HTTPS LB に IAP を設定することで、Cloud Run で IAP を使うことができます。

もちろん、Cloud Run で提供されるエンドポイントへの外部からのトラフィックを拒否する設定ができるので、IAP をバイパスされることはありません。

残念ながら、Cloud Functions でも Cloud Run で IAP を有効化する際と同様の手順を試しましたが、設定はできるものの現時点では正しく動作しませんでした。ドキュメントにも機能しないと記載されています。

経緯

Serverless NEG が2020年10月14日に GA になりました。

https://cloud.google.com/load-balancing/docs/release-notes#October_08_2020

これにより、Cloud Run や Cloud Functions、Google App Engine (GAE) といった Serverless Computing に於いても、ロードバランサと紐付けることができるようになりました。

さらに、Cloud CDN、Cloud Armor が利用できるようになりました。

https://cloud.google.com/load-balancing/docs/https/setting-up-https-serverless?hl=ja

Cloud Run に関しては、遂に IAP を使うことができるようになりました。

前提知識

Serverless NEG については、こちらの記事が参考になります。

https://medium.com/google-cloud-jp/4f9cebd2780f

手順

利用するリージョンは東京(asia-northeast1)、設定項目は変更する必要がある箇所を除いて基本的にコンソールのデフォルト値を用いました。

Terraform で構築する場合は、こちらの記事を参照してください。

https://cloud.google.com/blog/ja/products/application-development/new-terraform-module-serverless-load-balancing

Cloud Run サービスの作成

コンソールにログインした状態で次のページを開き、Cloud Run サービスを作成します。

https://console.cloud.google.com/run/create


今回は検証のために us-docker.pkg.dev/cloudrun/container/hello をデプロイします。

内部のトラフィックと Cloud Load Balancing からのトラフィックのみを許可し、IAP をバイパスされないようにします。
認証を必要とすることで、内部のトラフィックであっても認証されているリクエストのみ許可されます。


作成ボタンを押下して、Cloud Run サービスの作成を完了します。

HTTPS ロードバランサの作成

次のページを開き、HTTPS ロードバランサを作成します。

https://console.cloud.google.com/net-services/loadbalancing/add


HTTP(S) 負荷分散を選択して構成を開始します。


外部 HTTPS ロードバランサを作成するため、前者を選択します。

バックエンドの構成


バックエンドの構成を選択します。


バックエンドサービスを作成します


ここで、事前に作成した Cloud Run サービスを選択します。


バックエンドサービスの作成画面に戻るので完了を押下します。


バックエンドの構成は完了です。今回の検証ではホストとパスのルールは変更しません。

フロントエンドの構成

検証にしか使わないロードバランサなので、今回はエフェメラル外部 IP アドレスを使用しますが、必要な場合は静的外部 IP アドレスを予約します。


HTTPS ロードバランサを作成するのでプロトコルを選択します。


証明書のドロップダウンメニューを開き、新しい証明書を作成します。

画像では空欄になっていますが、ドメインの箇所には後々 DNS レコードを設定する FQDN を記載します。


証明書を作成してフロントエンドの構成画面に戻り、完了ボタンを押下します。

ロードバランサの作成と確認


構成を確認したら作成ボタンを押下します。


ロードバランサが作成されます。


ロードバランサの詳細を開くと、証明書の準備がまだできていません。

ここでロードバランサの IP アドレスが分かるので、証明書作成時に登録した FQDN に A レコードを設定します。


証明書の詳細を開くと PROVISIONING であることが分かります。

プロビジョニングが完了するまではある程度時間が掛かるので、気長に待ちます。
プロビジョニングを待っている間に IAP の有効化を進めることもできます。

IAP 有効化

※OAuth 同意画面の構成を済ませていない場合は、次のページを参考にしてください。プロジェクト毎に1度だけ設定が必要です。

https://cloud.google.com/iap/docs/enabling-compute-howto?hl=ja#oauth-configure

次のページを開き、Backend Service に対して IAP を有効化します。

https://console.cloud.google.com/security/iap


ロードバランサ作成時に作成した Backend Services が表示されていることを確認し、トグルボタンで有効にします。


チェックボックスを選択し、有効にします。


少し時間がかかりますが、有効になります。

IAM で権限付与

次のページを開き、ユーザーに権限を付与します。

https://console.cloud.google.com/iam-admin/iam


"IAP で保護されたウェブアプリ ユーザー" roles/iap.httpsResourceAccessor を付与します。

https://cloud.google.com/iap/docs/managing-access?hl=ja#roles

動作確認

先程 DNS レコードを設定した FQDN をブラウザで指定して開き、次の画面が表示されていれば成功です 🎉

まとめ

Cloud Run で IAP が使えるようになったことで、管理画面など限られたユーザーだけが利用するページや API 等を手軽かつ安全に Cloud Run で稼働させることができるようになりました。

まだ試せていませんが、Identity Platform を組み合わせることで、OIDC、SAML、外部のアカウントを用いた認証を、自身で実装するよりも容易に導入できるようです。Google アカウント以外の ID ソリューションを利用したい場合や、不特定多数のコンシューマー向けの認証として有用です。
Firebase Authentication と似ていますが、Identity Platform は有料のサービスで SLA も提供されています。

https://cloud.google.com/iap/docs/external-identities?hl=ja

トラブルシューティング

ページが表示されない

証明書のプロビジョニングが完了していない状態で開くと、このような表示になります。
プロビジョニングが完了するまで待ってください。

403 が返る

Cloud Run サービスで 認証を必要とする 設定にした上で IAP を有効化していない場合に、このような表示になります。
IAP を有効化しているか確認してください。

You don't have access が表示される

認証しようとしたユーザーに "IAP で保護されたウェブアプリ ユーザー" roles/iap.httpsResourceAccessor が付与されていないと、このような表示になります。
IAM でロールを付与してください。

Discussion

ログインするとコメントできます