キャディでの Google Cloud PAM 導入および運用の工夫

こんにちは、Infrastructure Teamの宮本(@m1yam0t0)と申します。
本記事では、キャディの権限昇格システムの取り組みを紹介します。

目次

はじめに

みなさんは、パブリッククラウドの権限はどのように管理されていますか?
IAMでメンバーに必要な権限を付与していますでしょうか?TerraformでIaC管理されていますでしょうか?

キャディでは、最小権限の原則に従って、開発者には閲覧系の必要最低限の権限のみを付与しています。*1
開発・運用で追加の権限が必要になった場合は、Just-In-Time(JIT) Accessの仕組みで一定期間だけ権限昇格できるようになっています。
開発者が権限を申請し、承認者が承認してはじめて権限が付与されます。

最小権限の原則を徹底することで、昨今利用が広がっているAIエージェントを活用した場合にも、本番環境の権限を持っていないため、誤って操作してしまうリスクを低減できます。

本記事ではこのJIT Access Systemを内製システムからGoogle Cloud Priviledged Access Manager(PAM)に移行したお話を紹介いたします。

内製システムから Google Cloud PAM への移行

キャディでは、2022年より内製のJIT Access Systemを運用しておりました。
しかし、この内製のJIT Access Systemについて、認可制御に課題があったため、IAM Condition を組み合わせて権限が付与できるように改修を検討していました。

そんな中、Google Cloud PAM のアップデートで、権限のスコープが設定可能になったことを知り、検証をしてみたところ、内製のシステムを改修しづつけるより、効率良く目的を達成できることがわかりました。

IAM release notes  |  Identity and Access Management (IAM)  |  Google Cloud Documentation

上記を踏まえて、以下の理由から、キャディのJIT Access SystemをGoogle Cloud PAMへ移行する価値があると判断し、移行を実施いたしました。

  • 権限のスコープを細かく設定でき、取得する権限を必要最小限に抑えられる
  • Cloud Loggingに監査ログが残るため、通知や監査に活用できる
  • Google Cloudマネージドのサービスであるためメンテナンス不要

PAM の利用資格の設定

Google Cloud PAMでは、取得したい権限のセットを利用資格として定義し、必要な権限に対応する利用資格を選択して申請します。

Terraform Provider が公式で提供されているため、IaCで管理できます。

利用資格はユースケースごとに複数作成するため、
以下のようなTerraform moduleを定義し、変数を入力することで容易に設定できるようにします。

resource "google_privileged_access_manager_entitlement" "entitlement" {
  provider = google-beta

  entitlement_id = var.entitlement_id
  location       = var.location
  parent         = var.parent

  max_request_duration = var.max_request_duration

  eligible_users {
    principals = var.eligible_users
  }

  privileged_access {
    gcp_iam_access {
      resource_type = var.resource_type
      resource      = var.resource

      dynamic "role_bindings" {
        for_each = toset(var.roles)
        content {
          role = role_bindings.value
        }
      }
    }
  }

  approval_workflow {
    manual_approvals {
      require_approver_justification = var.require_approver_justification
      steps {
        approvers {
          principals = var.approvers
        }
        approvals_needed          = var.approvals_needed
        approver_email_recipients = var.approver_email_recipients
      }
    }
  }

  additional_notification_targets {
    admin_email_recipients = var.notification_emails
  }

  requester_justification_config {
    unstructured {}
  }
}

実際に利用する箇所では以下のようにTerraform moduleを呼び出して定義しています。
申請・承認するユーザを設定できるため、チームによって申請可能な利用資格を設定できます。

module "pam_org_gcs_bucket_read_access" {
  source = "../../modules/pam"

  # 利用資格名
  entitlement_id = "gcs-bucket-read-access"

  # Organization, Folder, Project 単位で指定可能
  parent         = "organizations/${local.organization_id}"
  location       = "global"
  resource_type = "cloudresourcemanager.googleapis.com/Organization"
  resource      = "//cloudresourcemanager.googleapis.com/organizations/${local.organization_id}"

  # 取得したい role を定義
  roles = [
    "roles/storage.bucketViewer",
    "roles/storage.objectViewer",
  ]

  # 申請可能なユーザ
  eligible_users = [
    "group:users@caddi.com",
  ]

  # 承認可能なユーザ
  approvers = [
    "group:approvers@caddi.com",
  ]

  # 最大の申請期間
  max_request_duration = "14400s"

  # 必要な承認の数
  approvals_needed     = 1
}

PAM の運用で工夫していること

Slack 通知機能の実装

PAMの通知機能はメール通知のみでSlackへの通知には標準では対応していません。
しかし、既存のJIT Access SystemではSlack通知するようにしていたため、利用者体験が変わらないようにする必要がありました。
そこで、PAMの監査ログの内容をパースしてSlack通知するAPIを実装しました。

以下のような仕組みで動作しています。

  • Pub/Subを経由して、実装したSlack通知APIに送信
    • Cloud Loggingに保存されているPAMの監査ログをLog routerでPub/Subに転送
    • Pub/Subの Push Subscription を使ってCloud Runで動作しているSlack通知APIにHTTP POST

実際の構成図は以下です。

PAM通知機能の構成図

上記のSlack通知APIを利用して、既存システムの使用感はそのままに、SlackでPAMの申請・承認を通知できるようにしました。

PAMのSlack通知

Slack通知の内容についても、利便性を上げるために様々な改善をしています。

  • 承認結果のメッセージを申請したメッセージのスレッドに紐づけて投稿
  • 申請内容に不備がある場合は、申請内容の修正を促すように警告文を自動で投稿
  • 申請のステータスによって、SlackのAttachmentの色を変更

Devin による利用資格設定の自動化

PAMの利用資格の中に取得したい権限が存在しない場合、利用資格を修正する必要があります。
PAMの移行当初は取得できる権限が不足しており、利用者から多く依頼を受けていました。
その度にTerraformの定義を修正しレビューするのは大変です。

そこで、Devinを使って、Terraformの修正からPRの作成を自動でしてもらうようにしました。
Devin Playbook で利用資格を修正するPR作成作業を定型化しています。
利用者がSlack Workflowで追加してほしい権限を入力するとDevinが呼び出され自動でPRを作成します。
あとは、チームメンバーがPRをレビュー、マージして反映するだけです。

Devin による利用資格の変更PRの作成

まとめ

権限の最小化を徹底するために導入していたJIT Access Systemを、内製システムからGoogle Cloud PAMに移行しました。
PAMに移行したことで最小粒度の認可制御が可能になり、より安全にGoogle Cloud を運用できるようになりました。
また、AIエージェントの活用により運用の改善を効率良く実施できました。本当に便利なものですね。

みなさんがGoogle Cloud PAMを導入するときの参考になれば幸いです。

*1:Terraformで管理