はじめに
アソビューのデータ基盤チームでデータエンジニアをやっている米澤です。
今回は、Google Cloudのサービスアカウントのキーに対して有効期限を設定する方法、および、IP制限を行う方法をご紹介したいと思います。
背景
まず、この対応を行うに至った背景をご説明します。
サービスアカウントはご存知の方が多いと思いますが、通常ユーザが使うアカウントとは異なり、例えば何かしらのツールからBigQueryへアクセスしたい、などの用途に使われる個人に紐づかないアカウントです。アカウントに付与する権限は通常ユーザのアカウントと同様に様々なロール/パーミッションが設定できます。ロールやパーミッションについては以前書いたブログに記載していますので、ご存じない方は良ければご一読ください。
このサービスアカウントはGoogle Cloudのコンソールから鍵(キー)を作成することで「JSONキー」をダウンロードすることができ、このJSONキーを使えば、基本的にはどんな環境からでも権限付与されたGoogle Cloudのリソースにアクセスすることができるようになります(例えば、ローカル環境から自身で作成したプログラムでBigQueryのデータ取得が可能になる、など)。
しかし、セキュリティ観点からすると、あまり使われるのが好ましいものではありません。 セキュリティが緩い会社だと、退職後もそのJSONキーで会社のリソースにアクセス可能、かつ、サービス関連の数値まで閲覧されてしまう大きなリスクがあります。
本来だと、アソビュー社もツールに設定するケース以外ではキー作成する運用は極力行わないようにしています。
(キー作成も限られたメンバーに限定)
今回は特定のユースケースで、アプリケーション以外からのサービスアカウントを利用するケースが発生したため、セキュリティ対応を行いつつ利用可能な状態を作ることにしました。
セキュリティの担保
前述したセキュリティリスクがあるため、そのまま何の制限も設けずにJSONキーを使ってもらうわけにはいきません。
方法を検討した結果、セキュリティを担保するために以下の制限を設けることにしました。
- サービスアカウントのキーに対して有効期限を設定する
- IPアドレス制限を行う
1はタイトル通り、サービスアカウントのキーに対して有効期限を設定します。
また、2は社内IPアドレス以外からはアクセスできないようにする対応です。
2の制限を設けておけば、仮に退職した場合アクセスは不可能になり、最低限のセキュリティは担保できます。 その上で、1の制限を設けてキーローテーションを行うことで、複数人でのキーの使い回し等のリスクも低減できます。
有効期限の設定方法
本来Google Cloudのサービスアカウントに有効期限を設定する機能はありません。
しかし、「プロジェクト全体」に対して「作成するサービスアカウントに有効期限を設定する」方法があります。
「組織ポリシー」を使う方法です。
サービス アカウントの使用の制限 | Resource Manager | Google Cloud
上記ページに記載されていますが、設定は「組織/フォルダ/プロジェクト」に対して行うことができます。 「組織」や「フォルダ」への設定だと影響範囲が大きすぎるため、特定の「プロジェクト」に対して設定を行うことにしました。
なお、サービスアカウントには設定対象プロジェクトに対してBigQueryのジョブ実行権限を付与し、かつ、BigQueryの実データがある別プロジェクトに対する閲覧権限も付与しています。
(プロジェクト名は仮称)
具体的な設定方法
- 該当プロジェクトを選択
- [IAM と 管理] - [組織のポリシー] を選択
- 「iam.serviceAccountKeyExpiryHours」でフィルタをかける
- 「Service account key expiry duration in hours」を選択する
- 「ポリシーを管理」を押す
- 以下のように設定する
- ポリシーのソース:親のポリシーをオーバーライドする
- ポリシーの適用:交換
- ルール(ポリシーの値):カスタム
- ルール(ポリシータイプ):許可
- ルール(カスタム値):任意の値
⇒ なお、ヘルプに記載ある通り、選択肢は 1h / 8h / 24h / 168h / 336h / 720h / 1440h / 2160h の8種類のみ
IP制限の設定方法
IPアドレスの制限は、本来であれば対象のサービスアカウントに対して設定できれば話が早いです。
実際、AWSであればアカウントに対してIAMポリシーを適用することでIP制限をすぐに設定することができます。 しかし、Google CloudのIAMにはこの機能がありません。
サービスアカウントに対してIP制限を適用する方法を検討しましたが良い方法が見つからず、最終的にプロジェクト全体に対してIP制限を行う形にしました。

なお、弊社のプロジェクト構成上、run-job01プロジェクトはBigQueryのジョブ実行だけを担っており、実データはdata-view01、data-view02にあります。 単にrun-job01プロジェクトにIP制限の境界を作るだけだと、外部プロジェクトに一切アクセスができなくなり、data-view01やdata-view02プロジェクトのテーブル閲覧が出来なくなってしまいます。よって、境界の外向き(Egress)のアクセスを許可する設定を行いました。
具体的な設定方法
1つ1つ細かい手順を説明するとかなり長くなってしまうので概要だけ記載します。
- Access Context Manager からIPアドレス制限をかけるアクセスレベルを作成
- VPC Service Controls から境界を作成
- 保護するリソース:対象プロジェクト
- 制限付きサービス:bigquery.googleapis.com
- アクセスレベル:上記1で設定したアクセスレベル
- 下り(外向き)ルール:許可するプロジェクトとサービス
詳細は、以下のGoogleページを参考にしてください。
ベーシック アクセスレベルの作成 | Access Context Manager | Google Cloud Documentation
サービス境界を作成する | VPC Service Controls | Google Cloud
注意点
それぞれの対応で注意点があります。
有効期限
有効期限の設定は、設定した瞬間から適用されます。
つまり、設定前に作成した鍵には適用されません。
よって、既に作成済の鍵はすべて削除して、新たに鍵を作り直す必要があります。
IP制限
IP制限で使っているVPC Service Controlsという機能は非常に強力です。 設定次第では、プロジェクトのリソースに完全にアクセスできなくなるような設定も可能です。
プロジェクトの使い方によっては、自分では認識できないくらい広い範囲に影響を与えてしまう可能性もあります。
よって、当たり前な対応ではありますが、ステージング環境等でしっかりと実行&影響範囲の確認を行ってから本番環境に反映するよう注意してください。
まとめ
最終的に以下の構成で対応しました。

セキュリティリスクを低減できるよう二重の鍵をかけるような設定にしましたが、本来であればJSONキーを個人に提供するような運用はお勧めしません。 しかし、要望があれば、選択肢の中から可能な手段を検討&提供することもデータエンジニアとしては重要なスタンスだと思います。
この事例が、同じような課題に直面されている方の一助になれば幸いです。
最後に
アソビューでは「生きるに、遊びを。」をミッションに、一緒に働くメンバーを募集しています。 ご興味がありましたらお気軽にご応募いただければと思います。