Chrome Enterprise Premium による Google Cloud コンソールへのアクセス制御

Google Cloud では、Chrome Enterprise Premium というサービスの一部として「Google Cloud Console と Google Cloud APIs へのアクセス制御」の機能があり、Google Cloud Console にアクセスできるユーザアカウントや送信元 IP アドレスを制限することができます。

今回は、この機能に関連する最近のアップデートをふまえ、Google Cloud Console (以下、コンソール) へのアクセス制御の挙動を見ていきたいと思います。

セットアップ

今回は、「指定された送信元 IP アドレスからのみコンソールへのアクセスを許可する」という条件でアクセス制御を実装していきます。

現在のコンソールでは Chrome Enterprise Premium のメニューから [CLOUD コンソールと API へのアクセスを管理] のボタンをクリックすることで「Google Cloud Console と Google Cloud APIs へのアクセス制御」の設定画面に進めるようになっています。

Google Cloud Console と Google Cloud APIsへのアクセス制御」の機能を使うだけであれば Chrome Enterprise Premium のサブスクリプション契約は不要です(アクセスレベルの条件を CEL(Common Expression Language)で記述したい場合など、使い方によってはサブスクリプションが必要になるようです)。

さて、以下の画面ではコンソールへのアクセス制限を設定するために Google グループとアクセスレベルを事前に定義しておき、それらのバインディングを定義します。

冒頭では、「Google Cloud Console と Google Cloud APIs へのアクセス制御」は Chrome Enterprise Premium というサービスの一部であると書きましたが、もう少し具体的に説明すると、Cloud Identity や Google Workspace で定義する Google グループと、Access Context Manager で定義するアクセスレベル(アクセスの条件となる属性)という、2 つのリソースのバインディング(公式ドキュメントでは access binding と表記)を定義することで、各 Google グループに所属するユーザアカウントに対してコンソールや API へのアクセス時にアクセスレベルで定義された条件を強制する(必須とする)、という感じになります。

まずは Google グループの定義から。

Google グループは、Web アプリ (groups.google.com) や その API からの設定だけでなく、コンソールの「IAM と管理」のサブメニューからも設定が可能です。

次にアクセスレベルの定義です。

アクセスレベルの送信元 IP アドレスには IPv4, IPv6 のどちらも指定することが可能です。
クライアントが IPv4/IPv6 デュアルスタックの環境※である場合は、IPv6 で送信元 IP アドレスが評価されます。 この場合、IPv4 で割り当てられている IP アドレスをアクセスレベルの属性に定義しても判定されない点に注意が必要です。

※ 端末やネットワーク機器がデュアルスタックに対応していても実際にデュアルスタックになっていない(e.g. IPv6 アドレスが払い出されていない)場合は IPv4 接続しかできないため IPv4 アドレスで評価されます。ここでいう「クライアントが IPv4/IPv6 デュアルスタックの環境である場合」というのは、もう少し詳しく書くと「端末やプロバイダがデュアルスタックに対応していて、実際に IPv4, IPv6 のどちらの IP アドレスも払い出されており、サーバーとの通信がどちらの IP アドレスでも成立できる場合」という感じになるかと思います

今回はクライアントが IPv6 接続に対応している環境と、そうでない(IPv4 接続のみ)環境の両方のパターンを試しました。

「Cloud コンソールと API のアクセスの管理」の画面に戻り、アクセスバインディングを作成します。

今回はコンソールからの設定を紹介しましたが、バインディングAPI への http リクエストで定義する場合は Chrome Enterprise Premium の API ではなく、Access Context Manager API のメソッド(accesscontextmanager.googleapis.com/v1/organizations/ORG_ID/gcpUserAccessBindings)を通じて設定します。
gcloud コマンドで定義する場合は gcloud access-context-manager cloud-bindings create コマンドを用います。

以上でセットアップは完了です。

動作確認

アクセスレベルの条件に合致する送信元 IP アドレスからコンソールにアクセスした場合

以下のとおり、問題なくコンソールにアクセスできることがわかります。

アクセスレベルの条件に合致しない送信元 IP アドレスからコンソールにアクセスした場合

以下のとおり、コンソールへのアクセスが制限されました。

追加検証 : サービスアカウントのアクセス制御

今回このテーマでの検証に思い至った理由のひとつとして、サービスアカウントは上記のアクセス制御の対象にできるのか、という点が気になっていました。
以前の Beyondcorp Enterprise では、サービスアカウントを「Google Cloud Console と Google Cloud APIs へのアクセス制御」の対象とすることはできませんでした。
公式ドキュメントでは(Chrome Enterprise Premium に変わった現在でも)サービスアカウントがこのアクセス制御の対象となるか否かについては言及がないため、少し前に Google グループのサービスアカウント対応が GA したこと、そして今回 Beyondcorp Enterprise が Chrome Enterprise Premium に変わったことで、現状の挙動を確認しておきたいと思った次第です。

Google グループにサービスアカウントを追加してみます。

上記のとおり、Google グループの Web アプリからはサービスアカウントを追加できないようです。
一方、Google Cloud のコンソールの [IAM と管理] - [グループ] のメニューからはサービスアカウントを Google グループに追加することができました。

ひとたび追加できれば、Google グループの Web アプリからもサービスアカウントが対象の Google グループのメンバーになっていることが確認できます。

さて、サービスアカウントの権限を使って、アクセスレベルの条件に合致する環境と、そうでない環境から API へのアクセスを試み、「Google Cloud Console と Google Cloud APIs へのアクセス制御」の対象となるのかを確認してみます。

通常、gcloud コマンドから API にリクエストを送る際は認証したユーザアカウントの IAM 権限に基づいて認可が行われますが、サービスアカウントの権限借用 を利用することで、サービスアカウントの権限を使って API にリクエストを送ることができます。

アクセスレベルの条件に合致する送信元 IP アドレスからコンソールにアクセスした場合

問題なく API にアクセスできていることがわかります。

$ gcloud storage buckets list --impersonate-service-account=temporary-service-account@************-436912-a4.iam.gserviceaccount.com
WARNING: This command is using service account impersonation. All API calls will be executed as [temporary-service-account@************-436912-a4.iam.gserviceaccount.com].
WARNING: This command is using service account impersonation. All API calls will be executed as [temporary-service-account@************-436912-a4.iam.gserviceaccount.com].
---
default_storage_class: STANDARD
location: US
location_type: multi-region
metageneration: 1
name: sample-bucket-98374******
public_access_prevention: enforced
...

アクセスレベルの条件に合致しない送信元 IP アドレスからコンソールにアクセスした場合

ユーザアカウントと同様の動作を期待するのであればアクセスが拒否されるシチュエーションですが、API へのアクセスは可能となっています。

$ gcloud storage buckets list --impersonate-service-account=temporary-service-account@************-436912-a4.iam.gserviceaccount.com
WARNING: This command is using service account impersonation. All API calls will be executed as [temporary-service-account@************-436912-a4.iam.gserviceaccount.com].
WARNING: This command is using service account impersonation. All API calls will be executed as [temporary-service-account@************-436912-a4.iam.gserviceaccount.com].
---
default_storage_class: STANDARD
location: US
location_type: multi-region
metageneration: 1
name: sample-bucket-98374******
public_access_prevention: enforced
...

やはり現時点では、Google グループに追加したとしてもサービスアカウントを「Google Cloud Console と Google Cloud APIs へのアクセス制御」の対象にはできないようですね。

余談1

現在は Chrome Enterprise Premium というサービスの一部として提供されている Google Cloud Console と Google Cloud APIs へのアクセス制御 ですが、以前は BeyondCorp Enterprise というサービスの一部として提供されていました。
さらに遡ると、BeyondCorp 登場以前には Context-Aware Access と呼ばれていた機能でした(Google Workspace では今でも Context-Aware Access という名称で同様の機能が提供されています)。

余談2

公式ドキュメント には、サービスアカウントをGoogle グループに追加するのは避けましょうという言及がありますが、こちらはどちらかというと IAM の管理におけるあるべき姿に基づいた話で、上記のアクセス制御の適用可否について示しているものではありません。

まとめ

Chrome Enterprise Premium を使った「Google Cloud Console と Google Cloud APIs へのアクセス制御」をご紹介しました。
IPv4/v6 のデュアルスタック環境においてはアクセスレベルの属性に指定する IP アドレスに注意が必要です。
また、従来の Beyondcorp Enterprise の頃と同様、サービスアカウントは上記アクセス制限の機能の対象外となるため、要件に応じて VPC Service Controls を利用するなど他の方法を考えていく必要があります。