Google CloudのIAMについて

# はじめに
Google Cloudの資格の一つである、「Professional Data Engineer」の勉強メモとしてまとめようと思っています。
今回は[出題範囲](https://cloud.google.com/learn/certification/guides/data-engineer?hl=ja)になっている、Cloud IAMについてまとめます。
また、Professional Cloud Architectの[出題範囲](https://cloud.google.com/learn/certification/guides/professional-cloud-architect?hl=ja)でもあり、今年更新しないといけないので復習がてらまとめておこうと思います。
何かおかしなことを書いていたりしていた場合はご指摘いただければ幸いです。

## 更新履歴
2024.02.24 新規作成

## [IAM](https://cloud.google.com/iam/docs/overview?hl=ja)
### 概要
IAMとはIdentity and Access Managementの略で、以下公式ドキュメントからの引用ですが、誰(ID)がどのリソース(サービスやプロジェクトなど)に対してどのようなアクセス権を持つかを定義可能な「認可」に使用するものです。

>IAM では、誰（ID）がどのリソースに対してどのようなアクセス権（ロール）を持つかを定義することにより、アクセス制御を管理します。たとえば、Compute Engine の仮想マシン インスタンス、Google Kubernetes Engine（GKE）クラスタ、Cloud Storage バケットはすべて Google Cloud のリソースです。リソースの整理に使用する組織、フォルダ、プロジェクトもリソースになります。

::: note 
IDのことをIAMでは、
「プリンシパル(Principal)」
もしくは
「メンバー(Member(s))」
と呼んでいるそうです。
:::

-----

###  構成要素
IAMでは以下3つの構成要素があります。
簡単に概要を記載すると以下のようになります。

* プリンシパル Principal
誰(ID)を指しており、一意の識別子(通常はメールアドレス)があります。
* ロール Role
権限を一つにまとめたものです。
プリンシパル(ID)に対して権限を直接割り当てることはできず、ロールを割り当てるようになっています。
また、権限は細部まであるため、Google Cloud側でまとめて定義(事前定義ロール)してもらっているものを使うことができます。
ただ、[事前定義ロール一覧](https://cloud.google.com/iam/docs/understanding-roles#predefined_roles)を見ていただければわかりますが、事前定義ロールが多いのと、一つのロール内の権限が多いので、アクセス制御設計する際は苦労すると思われます。
<details><summary>例：「BigQueryデータ閲覧者」ロールの権限(17個)</summary>

bigquery.datasets.get
bigquery.datasets.getIamPolicy
bigquery.models.export
bigquery.models.getData
bigquery.models.getMetadata
bigquery.models.list
bigquery.routines.get
bigquery.routines.list
bigquery.tables.createSnapshot
bigquery.tables.export
bigquery.tables.get
bigquery.tables.getData
bigquery.tables.getIamPolicy
bigquery.tables.list
bigquery.tables.replicateData
resourcemanager.projects.get
resourcemanager.projects.list
</details>


* [ポリシー(許可)](https://cloud.google.com/iam/docs/policies?hl=ja) - Allow policy
1つ以上のプリンシパル(ID)を個々のロールにバインドするロールバインディングの集合体です。
ロールバインディングは1つ以上のプリンシパル(principals)とロールをひとまとめにするものと読み替えたほうがわかりやすそうです。
また、リソースタイプによりますが、条件付きロールバインディングをつけ、期限付きのロールにするなどといったことも可能です。

以下、公式の各構成要素を図にしたものを引用します。
>![各構成要素の図式](https://cloud.google.com/static/iam/img/iam-overview-basics.svg?hl=ja)

* [ポリシー(拒否)](https://cloud.google.com/iam/docs/deny-overview?hl=ja)
Google Cloudのリソースへのアクセスに対し、ガードレール(望ましくない利用のみを制限)を設定することができます。
拒否ポリシーを使用すると、誰(プリンシパル)かが特定の権限を使えないようにすることが可能になります。
※拒否ポリシーはまた別で記事書こうと思います。

#### プリンシパル(ID)の種類について
プリンシパルには以下のタイプがあり、要件に基づいて「誰」を特定するために使います。

* Googleアカウント
一般的に使っている、Gmailを利用したりする際に必要なアカウントなどを指します。
* サービスアカウント
個々のエンドユーザーではなく、サーバでアプリケーションを動作させるなどといった場面で用いるアカウントを指します。
apacheやcronでシェルを動作させる際に使用するアカウントのイメージです。
* Googleグループ
Googleアカウントやサービスアカウントをまとめることができるものです。
認証自体はできませんが、複数のGoogleアカウントをまとめて権限付与できたりします。1つ1つに適用しなくていい分、簡単になります。
個人で使用していない限り、権限付与はGoogleグループを使用すると想定されます。
* Google Workspaceアカウント
Googleグループと似ていますが、企業ドメイン自体をグループにしたイメージとなります。
企業ドメイン(組織)自体に権限を付与する場合に使用します。
* Cloud Identityドメイン
IAMのプリンシパルという意味では、Google Workspaceと同じ意味合いになります。
* 認証済みのすべてのユーザー
allAuthenticatedUsersという特殊な識別子です。
**すべてのGoogleアカウントやサービスアカウントで認証されたもの**という意味合いを持ちます。
:::note warn
**注意**
自社ドメインで運用している場合に、これを**自社ドメインのすべての承認ユーザー**と勘違いすると情報漏洩などにつながります。
個人用のGoogleアカウントや別の会社のドメインのユーザーでも該当しますので、よっぽどの要件がない限りは使用しないほうがいいです。
自社ドメインで運用している場合には組織ポリシーによる制御を検討したほうがいいと思われます。
:::
* すべてのユーザー
インターネット上のすべてのユーザーを指します。
Google Cloud Storageで静的サイトを全ユーザーに見せるなどの用途で使うことはあると思われますが、そういう要件がない場合には制御を検討したほうがいいです。

#### ロールのタイプについて
ロールには以下のタイプがあります。

* 基本ロール
Google Cloud Consoleで使用されているロールで、「オーナー」「編集者」「閲覧者」の3つがあります。
※個人のGoogleアカウントでプロジェクトを作成している場合はそのプロジェクトには自身に「オーナー」ロールがついてます。
::: note warn
公式にも記載がありますが、個人でやってたり特別な要件がない限りはこのロールを使わないほうがいいです。
機密データを扱っていて特定の人物しか閲覧許可を与えていない場合に、意図せず見えてしまうなど、様々なリスクがあります。
後述する「事前定義ロール」または「カスタムロール」を使うべきです。
:::
* 事前定義ロール
Google Cloud側で用意されている、基本ロールより詳細にアクセス制御をするためのロールです。各サービスごとに様々なロールが用意されていますので、要件に応じて選択していくといいと思われます。
ただ、このロール数が多いのと、本当に要件を満たしているかの確認が必要になります。これで満たせず、欲しいものがない場合は後述する「カスタムロール」を使用しますが、事前定義ロールはGoogle Cloud側で新しい権限や機能・サービスを追加した場合、**Google側で更新してくれる**といったメリットがあります。

* [カスタムロール](https://cloud.google.com/iam/docs/roles-overview?hl=ja#custom)
1つ以上の[サポートされている権限](https://cloud.google.com/iam/docs/custom-roles-permissions-support?hl=ja)をユーザ側でまとめて1つのロールとして定義できます。
※権限の中にはサポートではなく「TESTING」というカスタムロールとの互換性をテストしているものもあるため、基本的には「SUPPORTED」の権限を使用します。
また、カスタムロールはGoogle Cloud側で新しい権限や機能・サービスを追加した場合、**Google側で更新してくれない**といったデメリットがありますので、カスタムロールを使う場合は作成したロールの維持・管理といった運用が発生することになります。
::: note warn
このカスタムロールはユーザ側でいかようにも組み合わせることが可能なため、少数のプリンシパル(ID)にのみカスタムロールの作成・編集許可を与えてください。
※作成および編集許可をプロジェクトレベルで許可する場合は[ロール管理者](https://cloud.google.com/iam/docs/creating-custom-roles?hl=ja#required-roles)が必要です。
:::

## リソースについて
ここまで誰(プリンシパル)がどのようなアクセス権を持つかとそれらをバインディングする許可ポリシーを記載しましたが、最終的には**許可ポリシー**は**リソース**に紐づけます。
そのリソースとそれがどのような階層になっているかについて簡単に記載します。

:::note info
リソースは別で記載したほうがいいと思うので本当に簡単に記載しました。
:::

### リソース
* 組織
必ずしも持ってるものではありませんが、会社などを表す最上位のルートノードリソースです。
一般的にはCloud IdentityやGoogle Workspaceで使用するドメインがこの組織に該当します。
* フォルダ
プロジェクトをグループ化し、まとめることができるリソースです。
本番環境と開発環境、製品毎や部署毎などのまとまった意味を持たせて分けやすくするものです。
* プロジェクト
Google Cloud Service(Google Cloud StorageやPub/Subなど)の各リソースを管理する単位をプロジェクトといいます。
* リソース
各Google Cloud Serviceを指します。

### リソース階層
先ほどのリソースは以下のような階層になっており、どこにポリシーを割り当てるかによって、適用範囲を変えることができます。
>![リソース階層](https://cloud.google.com/static/iam/img/policy-inheritance.svg?hl=ja)

上位の組織やフォルダに適用すると下位のまで継承されていくので、適用する先に注意してアクセス制御設計をする必要があります。
個人などで実施している場合は、プロジェクトおよびリソースにどのようなポリシーを割り当てるかを考えればいいかと思われます。