オールアバウトTech Blog

株式会社オールアバウトのエンジニアブログです。

Google Cloud でサービス アカウントの権限借用(impersonate)を活用して SRE の権限を縮小させた話

こんにちは。オールアバウト SRE 所属 の@s_ishiiと申します。

Google Cloud にはサービス アカウントの権限借用という機能があります。この機能を活用することで普段の運用をより安全にすることができます。この記事ではオールアバウトが導入・実践しているサービス アカウントの権限借用に関して解説します。

前提

オールアバウトでは SRE が全サービスのインフラを一元的に管理しています。このため SRE は全ての Google Cloud のプロジェクトに対してオーナー権限(roles/owner)を保持していました。 SRE メンバー全員がインフラを自由に変更できてしまうため、普段から Google Cloud のコンソール画面で設定を変更してしまわないよう注意しながら運用する必要がありました。

こうした状況を解決する手段としてサービス アカウントの権限借用の活用を検討し始めました。

サービス アカウントの権限借用とは

サービス アカウントの権限借用とは名前の通り別のサービスアカウントの権限を借用する権限です。これだけだと分かりづらいので例を用いて解説します。

  • Google Cloud へのログイン・アカウント
    • sre@sample.com
    • 閲覧者権限(roles/viewer)
  • サービスアカウント
    • owner@project-id.iam.gserviceaccount.com
    • オーナー権限(roles/owner)

ログイン・アカウント(sre@sample.com)には更新系の権限が付与されていないため、Google Cloud 上で何かしらリソースを作成・変更しようとすると権限エラーになります。 しかしサービスアカウント(owner@project-id.iam.gserviceaccount.com)側でログイン・アカウントに対しサービス アカウントの権限借用を与えている場合、ログイン・アカウントからサービスアカウントに成りすますことができます。 これによってサービスアカウントの権限が利用できるようになり、結果として(参照権限しか持っていない)ログイン・アカウントから Google Cloud のリソースを作成・変更できるようになります。

詳しくは以下公式ドキュメントをご確認ください。
https://cloud.google.com/iam/docs/impersonating-service-accounts?hl=ja

目標

前提でも軽く触れましたがサービス アカウントの権限借用を用いることで以下の実現を目指しました。

  • SRE メンバーの権限縮小
    • コンソール画面から本番環境を変更できないようにする
  • Terraform の実行
    • Terraform は各 SRE メンバーの PC から実行しているため Terraform 経由の場合は本番環境の設定を変更できるようにする
  • 一時的な権限拡大
    • 一時的に権限を強化してコンソール画面から本番環境を変更できるようにする(一例として、障害時に DB をフェイルオーバーしたい等のユースケースが想定されました)

Terraform とサービスアカウントの借用権限

上記で解説したサービスアカウントの借用権限は gcloud コマンドと Terraform で利用できます。オールアバウトでは Google Cloud を Terraform で管理しているため Terraform でサービスアカウントの借用権限を利用しています。

具体的な設定手順は長くなるので割愛しますがこれによって閲覧者権限しか持っていないアカウントからでも Terraform 経由で Google Cloud のリソースを更新できるようになりました。 Terraform におけるサービスアカウントの借用権限の設定手順に関心のある方は以下記事をご覧ください。
https://medium.com/google-cloud/a-hitchhikers-guide-to-gcp-service-account-impersonation-in-terraform-af98853ebd37

一時的な権限拡大

Terraform でサービスアカウントの借用権限を使えるようになったことで運用の大部分が解消されたため、SRE メンバーからオーナー権限を剥奪しました。 しかしいざ閲覧者権限のみになると、当初想定していたよりもコンソール画面から変更作業が多いことに気づきました。Google Cloud は Terraform で管理していると書きましたが、Terraform を導入してから 1 年程度しか経っていないこともあり未だに Terraform 管理されていないリソースもあり、コンソール画面を操作して設定変更する機会は少なくなかったのです。

そこで活用したのが一時的な権限の追加です。Google Cloud IAM では権限を一時的に追加する機能があるのでこれを利用することで必要な権限を短時間だけ与えることにしました。

以下コマンド例です。コマンドを実行した時間から 30 分間指定した権限が追加された状態になります。

gcloud projects add-iam-policy-binding <プロジェクトID> \
    --member='group:sre@sample.com' \
    --condition="expression=request.time < timestamp(\"$(date '+%Y-%m-%dT%TZ' -u -d '30 minute')\"),title=tmp_$(date '+%Y-%m-%d-%T')" \
    --role='<ロール名>' \
    --impersonate-service-account=owner@project-id.iam.gserviceaccount.com

ちなみに最後に付与しているオプション--impersonate-service-accountはサービスアカウントの借用権限用のオプションになります。 ログイン・アカウント(sre@sample.com)には IAM を操作する権限は無いのですが、サービスアカウント(owner@project-id.iam.gserviceaccount.com)に成りすますことで IAM を操作できるようにしています。

Slack ボットを使って

上記までの対応で当初目標としていたことは達成できたのですが、「一時的な権限拡大が面倒」という課題が残りました。 コマンド 1 つ実行するだけですが、Google Cloud のロールに習熟している人でないとどのロールを割り当てて良いのか調べるところから始めないといけません。 roles/owner のような強力なロールを割り当てられれば良いのですが、一時的な権限付与では roles/owner を含む基本ロールは付与できないため、毎回ケースに応じて必要なロールを選択する必要があり思いの外時間がかかるのです。

このため新しく入ってきた人も簡単に作業ができるよう Slack 経由で実行できるようにしました。以下 Slack ボットの利用シーンになります。

まとめ

サービス アカウントの権限借用を活用することでインフラ管理者の権限を縮小し、不意の事故を防止することができます。 加えて上記のような対応を併せて行うことで、運用の安全性を享受しつつ利便性を維持することができますのでお試しください。

以上「Google Cloud でサービス アカウントの権限借用(impersonate)を活用して SRE の権限を縮小させた話」でした。