Google Cloud の土台
IAM の基本
IAM は「誰に、どのロールを、どのリソースで」付けるかを許可ポリシーとして書く仕組みです。ロールは事前定義ロールを基本にし、人にはグループ経由で、ワークロードにはサービスアカウントで権限を渡します。
Identity and Access Management (IAM) では、プリンシパル (誰が) にロール (何ができるか) を付け、その組をリソースの許可ポリシーとして保存します。許可ポリシーはリソース階層を下へ継承され、効く権限は祖先すべてのポリシーの和になります。試験の答えの基本形は「事前定義ロールを、グループかサービスアカウントに、一番下の階層で付ける」です。
許可ポリシーは、ロールとプリンシパルの組の一覧
プリンシパルは、人 (Google アカウント、Google グループ、Workforce Identity 連携の外部ユーザー) とワークロード (サービスアカウント、Workload Identity 連携の外部ワークロード) に分かれます。外部との連携はセキュリティの設計で扱います。
ロールは事前定義ロールから選ぶ
ロールは storage.objects.get のような権限 (サービス.リソース.操作) の束です。
| 種類 | 例 | 広さ | 使う場面 |
|---|---|---|---|
| 基本ロール | Admin、Writer、Reader。旧来の Owner、Editor、Viewer | ほぼ全サービス | 個人の検証環境だけ |
| 事前定義ロール | roles/storage.objectViewer | 1 つのサービスの特定の作業 | ほとんどの場合 |
| カスタムロール | 自分で権限を選ぶ | 選んだ権限だけ | 事前定義ロールが広すぎるとき |
基本ロールは、Owner (roles/owner)、Editor (roles/editor)、Viewer (roles/viewer) が「旧来の基本ロール」になり、新しく Admin (roles/admin)、Writer (roles/writer)、Reader (roles/reader) が加わりました。Reader は読み取り、Writer は作成と削除まで、Admin はロールと権限の管理までできます。旧来の 3 つには IAM Conditions を付けられないので、基本ロールを使うなら新しい 3 つを選ぶよう公式は勧めています。試験の選択肢の Editor や Owner は、多くが「広すぎる誤答」です。
カスタムロールは組織かプロジェクトで作り、フォルダには作れません。Google が足した新しい権限は反映されず、保守は利用者の責任です。
参考: ロールの概要 (公式)
許可は和で効き、取り上げるのは拒否ポリシー
効く権限は、そのリソースと祖先すべての許可ポリシーを足したもの (effective allow policy) で、フォルダで付けた権限をプロジェクトで打ち消すことはできません。取り上げるには拒否ポリシーを組織、フォルダ、プロジェクトに付けます。拒否ポリシーも下へ継承され、許可より先に評価されます。「特定のグループ以外はプロジェクトを削除できない」ようにする用途に向きます。
足し算で効くので、ロールは必要な一番下の階層で付けます。バケット 1 つを読むだけなら、バケットに付けます。
人にはグループ経由で、ワークロードにはサービスアカウントで
個人にロールを付けると、異動のたびに許可ポリシーを書き換えます。ロールはグループに付け、人の出入りはメンバーの追加と削除で済ませます。
サービスアカウントは VM や Cloud Run のような人ではないものの ID で、誰が使えるかを決める許可ポリシーを持つリソースでもあります。
| 種類 | 作る人 | 注意点 |
|---|---|---|
| ユーザー管理 | 利用者 | アプリごとに作り、必要なロールだけを付ける |
| デフォルト | 一部の API の有効化で自動 | Compute Engine と App Engine のものは作成時にプロジェクトの Editor が付く |
| サービスエージェント | Google のサービスが利用者のリソースを操作するためのもの |
公式はこの Editor の自動付与を組織ポリシーで止めるよう勧めており、本番には専用のサービスアカウントを割り当てます。サービスアカウントキー (JSON の鍵ファイル) は漏れると悪用されます。Google Cloud の中では鍵なしで認証でき、外部からも Workload Identity 連携か権限借用 (impersonation) を先に検討します。
職務の分離は、ロールを付ける人と使う人を分けること
職務の分離 (separation of duties) は、不正や誤操作を 1 人で完結させない考え方です。許可ポリシーを変える人 (roles/resourcemanager.projectIamAdmin など) と操作する人、請求先アカウントとプロジェクトの管理者を別にし、本番へのデプロイはパイプラインのサービスアカウントに限ります。roles/iam.serviceAccountUser を持つ人はそのサービスアカウントの権限でワークロードを動かせるので、強いサービスアカウントほど付ける相手を絞ります。
試してみる
学習用の環境を作るのプロジェクトで、サービスアカウントにバケット 1 つだけのロールを付けます。
PROJECT_ID=$(gcloud config get-value project)
SA_NAME=pca-reader
SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"
BUCKET="gs://${PROJECT_ID}-iam"
# ロールに含まれる権限を見る
gcloud iam roles describe roles/storage.objectViewer
# サービスアカウントとバケットを作る
gcloud iam service-accounts create "$SA_NAME" --display-name="PCA reader"
gcloud storage buckets create "$BUCKET" --location=us-central1 --uniform-bucket-level-access
# バケットにだけロールを付ける
gcloud storage buckets add-iam-policy-binding "$BUCKET" \
--member="serviceAccount:${SA_EMAIL}" --role=roles/storage.objectViewer
# バケットには入り、プロジェクトには入っていないことを確かめる
gcloud storage buckets get-iam-policy "$BUCKET"
gcloud projects get-iam-policy "$PROJECT_ID" \
--flatten="bindings[].members" \
--filter="bindings.members:${SA_EMAIL}" \
--format="table(bindings.role)"
最後のコマンドで何も出なければ、権限はバケット 1 つに閉じています。
最後に片付けます。
gcloud storage buckets remove-iam-policy-binding "$BUCKET" \
--member="serviceAccount:${SA_EMAIL}" --role=roles/storage.objectViewer
gcloud storage buckets delete "$BUCKET"
gcloud iam service-accounts delete "$SA_EMAIL" --quiet
試験で問われる判断
自作の例です。実際の試験問題ではありません。
- 「分析チームに BigQuery のデータセットを読ませたい。メンバーはよく入れ替わる」なら、Google グループに事前定義の閲覧ロールを付けます。個別に付ける案とプロジェクトの Viewer は選びません。
- 「VM のアプリが 1 つのバケットに書き込む」なら、専用のサービスアカウントにそのバケットの書き込みロールを付けて VM に割り当てます。デフォルトのサービスアカウントは Editor 付きなので選びません。
- 「オンプレミスのバッチから API を呼びたい」なら、サービスアカウントキーより Workload Identity 連携を選びます。鍵の保管と更新が要りません。
- 「フォルダで付けた権限を、特定のプロジェクトでだけ無効にしたい」は許可ポリシーではできません。拒否ポリシーを使うか、プロジェクトを別のフォルダへ移します。