Google Cloud のクレデンシャルを安全に扱うアップデート振り返り2022
Service Account の credential json を始め Google Cloud を使う上でクレデンシャルの取り扱いを改善するアップデートについて弊社Ubieでの事例も踏まえまとめてみます。去年以前にリリースされたものも含みます。
TL;DR;
- GKE から Google API を操作するときはWorkload Identity
- Google Cloud外からは Workload identity federation
- どうしても扱う場合はSecret Managerを利用
まずクレデンシャルと言ってもいろいろあるので、Google Cloud の Service Account のクレデンシャルについて取り扱います。これらは各種 Google Cloud のAPI を利用する際に利用します。例えばアプリケーションなどが Cloud Spanner や Cloud Storage といったリソースを利用する場合です。
Workload Identity
セキュリティの全体設計にはあまり触れませんが、Ubie では基本的に「必要最低の権限」のみを「必要な Actor」に「安全に」付与するという方針で運用を行っています。少し抽象的なので GKE 上にアプリケーションを動かす例をとって解説します。
「必要最低の権限」と「必要な Actor 」というのはワークロードごとにGoogle Service Account (以後 GSA) を用意し権限を付与すればOKです。例えばfooとbarというアプリケーションがあれば、共通の GSA を使い回さずそれぞれ専用のものを作成し、それぞれに必要なロールを割り当てることで満たします。(これは GKE に限った話ではないです)
ちなみにこの2つの対極にあるのは Compute Engine deafult service account です。デフォルトだとプロジェクトレベルで roles/editor という強力な権限を持っているので不用意に使わないようにしましょう。
では次に「安全に」はどうすればいいでしょうか?そこで有用なのが Workload Identity です。GKE (Kubernetes) には namespace ごとにServiceAccount(以後 KSA)があり、実行の基本的な単位であるPod(実務ではDeploymentやJobで作成することが多いでしょう)を起動するときに指定することができます。(namespace ごとに default という KSA があり特に指定しないとこの default で起動します)
Workload Identity は KSA が GSA として Google API の認証ができるようになります。つまり fooというKSA/GSAが適切に設定されていればアプリケーションはfooの権限で各種リソースが使えるようになります。
これがなぜ安全かというとこの機能がない場合は GSA の credential json を作成しSecretに入れ特定のパスにファイルとしてマウントする必要がありました。その場合ワークロードの脆弱性やランタイムの設定不備、オペミスなど漏洩しないように気にするポイントが増えるだけでなく、ローテートやCI/CDでの扱いも慎重に考慮する必要が出てきます。
Workload Identity は 2020年3月にGAしましたが、Ubie では beta (現Preview) 段階から検証し早期に移行を行いました。現在ではGKE上のすべてのワークロードがこの機能を使用しています。
ちなみに 2021年2月に登場した GKE Autopilot では Workload Identity がデフォルトで有効化されています(無効化はできません)。
他のランタイム
では他のランタイム(Cloud RunやCloud Functionsなど)はどうかというと基本的に実行時のサービスアカウントを指定することができます。同じように専用のService Account(GSA)を作成しそれを利用するようにデプロイしましょう。(逆に指定しないとCompute Engine default service accountで動きます)
// e.g.
gcloud deploy foo --service-account=foo@bar-project.iam.gserviceaccount.com
Workload identity federation
Google Cloud のリソースを利用するのがすべて Google Cloud 内に収まっていれば Workload Identity のみで平和になりますが実際にはそうは行かない場合もあるかと思います。他のクラウドやオンプレ、CIのSaaSなどでも利用するケースです。
この場合、以前は妥協をし Service Account の credential json を作成する必要がありました。(Workload Identityのところにも書いたとおり credential jsonを扱うと考慮事項が増えます)
弊社では GitHub Actions からGoogle Cloudのリソースにアクセスする場合に利用をします。e.g. Artifact Registryからdocker imageを取ってくるなど。GitHub は Org/Repoどちらにも Actions 用に Secret を登録することができますが Org に登録するとどのRepoから使われるかわからない、Repo に登録する場合 Repo ごとに登録する必要がある、monorepo だとどのワークフローから使われるかわからないなどの問題があります。
Workload identity federation は利用側がOIDC に対応していれば、credential jsonを使わずに認証をすることができます。(OIDCについては GitHub Actions のページ で解説されているのでそちらを参照ください)
GitHub Actions の場合 公式のActions も提供されており簡単にGoogle APIに認証できます。Org/Repo/Branch/Workflowなど条件を指定して許可することもできるのでより安全にアクセスを許可できます。例えば main ブランチのみ許可するなど。
Workload identity fedaration は 2021年4月にGAしました。Ubieでもほとんどの部分で利用をしています。以前は gsutil や bq コマンドが対応していませんでしたが、現在はどちらも対応してます。
オンプレミス
また AWS や GitHub Actions だけでなくオンプレミスの Kubernetes 環境での実装事例もあります。
Cloud Build
GitHub Actions ではなく Cloud Build を利用するのも一つの手です。GitHub App triggers などを利用すると credential json を作成する必要はありません。GitLab / GitLab Enterprise / GitHub Enterprise なども対応しています。
Workforce identity federation
Workload identity federation と似た名前で Workforce identity federation というものがあります。これは人に対する権限をクレデンシャルレスに付与するというものです。Google Account (Google Workspace or Gmail) を利用している場合は関係ないですが、 Azure AD など外部の IdP を利用しているユーザーに権限を付与したいケースで利用します。Cloud Identity を使う手もありますが、ちゃんとした IdP がある場合そちらを直接利用したいケースが情シス観点ではあるのだと思います。
2022年7月に登場し12月時点でもまだPreviewです。
Cloud SQL / AlloyDB
さてここまで Service Accountのクレデンシャルを中心に扱ってきましたが、データベースのパスワードについても少し触れます。Cloud Spanner や Cloud Firestore など Google Cloud Native なデータベースはAPIベースでの通信なのでIAM認証です。Workload Identity を使いましょう。
Cloud SQLやAlloyDB などの OSS ベースの DB は VPC 通信を行うため従来のUser/Passwordで認証するのが通常だと思います。これに加えてIAM Authenticationを利用することでパスワードの管理から開放されます。
アプリケーションが実装できない場合もそれぞれCloudSQL Proxy/AlloyDB Auth Proxyをサイドカーとしてデプロイすることで利用可能になります。(どちらもcredential jsonを渡すこともできますが、こちらも Workload Identityを利用しましょう)
Alloy DB 自体はつい先日 GA しましたが、Preview 段階からIAM Authenticationが提供されています。
個人的には、欲を言うとユーザーの権限もIAMで管理できるようになると嬉しいです。
おまけ
Fastly
UbieではFastlyをCDN/WAFとして利用しています。またログをBigQueryに転送していますが、こちらもIAMで認証することが可能になりました。
Secret Manager
最後にどうしてもなにかのクレデンシャルや秘匿値を扱う必要がある場合です。外部の API キーや salt 等を扱うことは頻繁にあると思います。Kubernetes の Secret を直接利用することも可能ですが個人的には Secret Manager をおすすめしています。Secretをバージョン管理しローテートできるのが大きな理由です。
External Secret やberglas を利用すると GKE からも利用可能です。現在は Cloud Run や Cloud Functions も連携がります。
2020年3月にGAしましたがその後も機能が拡充されています。expiration やnotificationはおすすめの機能です。
まとめ
簡単に Google Cloud でクレデンシャルを取り扱う方法についてアップデートを振り返りながらまとめてみました。いろんなレイヤーでセキュリティが意識され、より生存期間の短いトークンの利用が推奨されているかと思います。Google Cloud をより安全に利用するために参考になれば幸いです。
余談
プロダクトによっては Getting Started で強めの権限 (roles/owner)を要求したり、Service Account の credential json を作成する記載がある場合もありますが、あくまでも Getting Started でありベストプラクティスではないことを留意ください。