【完全理解編】理解必須！OCIのIAMポリシー管理について

### はじめに

OCIに限らず、パブリッククラウドにはIAMポリシーと呼ばれるコンポーネントがあります。

簡単にいうと権限管理ですね。正確にはOCI IAM Identity Domainsの中の1機能としてユーザ管理を提供している形になります。

わかりやすく今回はIAMポリシーと勝手に呼称しますことご承知おきください。

当たり前ですがIAMポリシーの運用管理においてパブリッククラウド運用に必須となっております。

過去にコンパートメントについて記載した記事でIAMポリシーについても軽く触れたのですが、久々に触ると便利機能が増えていたり、あまりドキュメントも詳しく読み込んでいなかったので改めて自身の勉強と備忘録のためにまとめてみようと思います。

https://qiita.com/kazunishi/items/39f1952ae0805f956a4e

### IAMポリシーってなんなんだ?

ここからは早速本題に入っていきたいと思います。

そもそもIAMポリシーの定義や使用しなければならない理由や背景を言語化してみます。

#### OCI IAMポリシーとは何か？

IAMポリシーは、Oracle Cloud Infrastructure (OCI)テナンシ内のリソースの制御を管理するコンポーネントです。

* **定義**
  「**誰が（グループやユーザー）、どのリソースに、どんな操作をできるか**」を英語の自然文で記述するアクセス制御ドキュメントです
* **適用範囲**
  Policyは「テナンシ（全体）」または「コンパートメント（論理的なリソースグループ）」単位で設定できます

#### IAMポリシーを使用する理由

極端な話アドミンユーザ、ルートユーザと呼ばれるようなスーパーアカウント1つで作業はできてしまいます。

ですのでIAMポリシーを使用する理由を改めて言語化しました。

* **セキュアな運用**
  Policyを使うことで、ユーザーやグループに必要最小限の権限のみを付与できます。
  不要なアクセス権を排除し、万一アカウントが侵害された場合でも被害範囲を限定できます。
* **運用効率化**
  グループ単位でポリシーを管理できるため、ユーザー追加・削除時の権限調整が容易になり、運用負荷が大幅に軽減されます。
* **柔軟かつ細やかなアクセス制御**
  コンパートメントやリソース単位で細かく権限を設定できるため、組織構造や業務プロセスに合わせたきめ細かい管理が可能です。
* **コンプライアンスとガバナンスの確保**
  ポリシーによるアクセス管理は、各種法令や業界基準（例：GDPR、CCPA）への対応や、監査証跡の確保にも直結します。

#### IAMポリシーを適切に管理しなかった場合のリスク

生成AIに具体的なリスクを聞いてみました。便利な世の中です。

こういったリスクをさけるためにも適切なIAMポリシー管理は必要ですね。

| リスク項目                       | 内容・影響                                                                                                        |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **データ漏洩・情報流出**   | 過剰な権限付与や誤設定により、機密データや重要資産が不正アクセス・流出するリスクが高まります。                    |
| **インサイダー脅威**       | 不要な権限を持つ内部ユーザーによる意図的・偶発的な情報漏洩やシステム破壊が発生しやすくなります。                  |
| **コンプライアンス違反**   | 規制要件に違反し、法的罰則や多額の制裁金、監査指摘を受ける可能性があります。                                      |
| **運用障害・業務停止**     | 不適切なポリシー設定により、正規ユーザーが必要なリソースにアクセスできず、業務が停止する事態が発生します。        |
| **システム全体の乗っ取り** | 管理者権限の誤設定・漏洩により、攻撃者がクラウド環境全体を掌握し、DoSやランサムウェアなどの攻撃を仕掛けるリスク。 |
| **可視性・監査性の低下**   | ポリシー管理が不十分だと、誰がどのリソースにどんな権限を持っているか把握できず、不正の早期発見が困難になります。  |
| **信頼・ブランドの毀損**   | セキュリティ事故が発生すると、顧客や取引先からの信頼を失い、長期的なブランド価値の低下につながります。            |

#### コンパートメントとテナンシの関係について

### Policyの構成要素と書き方

基本構文は以下の通りです。

OCI IAM Policyは"Allow文"のみ記載が可能です。

**Deny（拒否）ポリシーはサポートされておらず**、許可のみを明示します


<pre class="not-prose w-full rounded font-mono text-sm font-extralight"><div class="codeWrapper text-textMainDark selection:!text-superDark selection:bg-superDuper/10 bg-offset dark:bg-offsetDark my-md relative flex flex-col rounded font-mono text-sm font-thin"><div class="-mt-xl"><div><div class="text-text-200 bg-background-300 py-xs px-sm inline-block rounded-br rounded-tl-[3px] font-thin"><br class="Apple-interchange-newline"/></div></div><div class="pr-lg"><span><code><span><span>Allow group <グループ名> to <動作> <リソースタイプ> in <適用範囲>
</span></span><span></span></code></span></div></div></div></pre>

* **グループ名** ：対象となるユーザーグループ
* **動作（Verb）** ：許可する操作（inspect, read, use, manage など）
* **リソースタイプ** ：対象リソース（all-resources, instance-family, volume-family など）
* **適用範囲** ：tenancy または compartment名

**動作（Verb）の種類**

| Verb    | 権限内容                           |
| ------- | ---------------------------------- |
| inspect | リスト表示などの閲覧               |
| read    | inspect + 詳細情報の取得           |
| use     | read + 既存リソースの操作          |
| manage  | 全操作（作成・削除・設定変更など） |

**リソースタイプ例**

OCIのIAMポリシーで指定するリソースタイプは、アクセス権限を付与したい対象のリソースを示します。

リソースタイプには「個別リソースタイプ」と「ファミリーリソースタイプ」があり、用途に応じて使い分けます。

* 個別リソースタイプ
  個別リソースタイプは、特定のリソース種別だけにアクセス権限を与えたい場合に使います。
  例えば「インスタンス（instances）」や「バケット（buckets）」など、1つのリソースカテゴリだけをピンポイントで指定できます。


* ファミリーリソースタイプ
  ファミリーリソースタイプは、複数の関連する個別リソースタイプをまとめて指定できるグループ名です。
  ネットワークやストレージなど、同じカテゴリに属するリソース全体を一括で管理したい場合に便利です。

以下が個別リソースタイプとそれに紐づくファミリータイプの一覧になります。

あくまでも一部ですが参考になれば。

| 個別リソースタイプ         | 説明・対象リソース例                     | ファミリータイプ           |
| -------------------------- | ---------------------------------------- | -------------------------- |
| `all-resources`          | すべてのリソース                         | -                          |
| `instances`              | コンピュートインスタンス                 | `instance-family`        |
| `volumes`                | ブロックボリューム                       | `volume-family`          |
| `volume-backups`         | ボリュームのバックアップ                 | `volume-family`          |
| `vcns`                   | 仮想クラウドネットワーク（VCN）          | `virtual-network-family` |
| `subnets`                | サブネット                               | `virtual-network-family` |
| `route-tables`           | ルートテーブル                           | `virtual-network-family` |
| `security-lists`         | セキュリティリスト                       | `virtual-network-family` |
| `internet-gateways`      | インターネットゲートウェイ               | `virtual-network-family` |
| `nat-gateways`           | NATゲートウェイ                          | `virtual-network-family` |
| `service-gateways`       | サービスゲートウェイ                     | `virtual-network-family` |
| `drg`                    | ダイナミック・ルーティング・ゲートウェイ | `virtual-network-family` |
| `local-peering-gateways` | ローカルピアリングゲートウェイ           | `virtual-network-family` |
| `load-balancers`         | ロードバランサー                         | `load-balancer-family`   |
| `buckets`                | オブジェクトストレージのバケット         | -                          |
| `autonomous-databases`   | Autonomousデータベース                   | `database-family`        |
| `database-systems`       | データベースシステム                     | `database-family`        |
| `vaults`                 | キー管理用ボールト                       | `kms-family`             |
| `kms-keys`               | キー管理サービスの鍵                     | `kms-family`             |

#### 【参考】具体的なポリシー文の例

想定ユースケースのポリシー文の例

* **開発者グループに特定コンパートメント内のインスタンス管理権限を付与**

<pre class="not-prose w-full rounded font-mono text-sm font-extralight"><div class="codeWrapper text-textMainDark selection:!text-superDark selection:bg-superDuper/10 bg-offset dark:bg-offsetDark my-md relative flex flex-col rounded font-mono text-sm font-thin"><div class="-mt-xl"><div><div class="text-text-200 bg-background-300 py-xs px-sm inline-block rounded-br rounded-tl-[3px] font-thin"><br class="Apple-interchange-newline"/></div></div><div class="pr-lg"><span><code><span><span>Allow group Developers to manage instance-family in compartment DevCompartment
</span></span><span></span></code></span></div></div></div></pre>

用途: 「Developers」グループが「DevCompartment」内のコンピュートインスタンス関連リソースをすべて管理可能にする

* **監査担当者にリソースの閲覧（Read）権限のみ付与**

<pre class="not-prose w-full rounded font-mono text-sm font-extralight"><div class="codeWrapper text-textMainDark selection:!text-superDark selection:bg-superDuper/10 bg-offset dark:bg-offsetDark my-md relative flex flex-col rounded font-mono text-sm font-thin"><div class="-mt-xl"><div><div class="text-text-200 bg-background-300 py-xs px-sm inline-block rounded-br rounded-tl-[3px] font-thin"><br class="Apple-interchange-newline"/></div></div><div class="pr-lg"><span><code><span><span>Allow group Auditors to read all-resources in compartment ProdCompartment
</span></span><span></span></code></span></div></div></div></pre>

用途: 「Auditors」グループが「ProdCompartment」内のすべてのリソースを閲覧できるが、変更はできない

### IAM ポリシーの作成 / 設定方法

ポリシー（権限）管理はユーザ作成と切っては切り離せないのでユーザ作成含めて記載しようと思います。

※今回は"ユーザに対して"という観点で記載します

#### 作成の流れ

以下のような流れでユーザ作成とポリシー作成を実施します。

1. グループの作成
   →ポリシー・ステートメント（=ポリシー文)の群を格納するための箱
2. ユーザの作成、及びグループの付与
   →ユーザに対してグループ
3. ポリシーの作成
   →実際にどのような権限を与えるかを1で作成したグループ内に対して作成

※グループ作成とユーザ作成は順不同です。どちらの画面からでも追加が可能なため

イメージとしては以下の絵のようなものです。
注意点というか特徴は

* Userに直接Policyを付与することは不可
* PolicyはUser Groupに付与
* UserはUser Groupに所属することでPolicyを付与

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/17ebdba3-4f45-46b9-95f7-3146fdf065dd.png)

#### ユーザ作成及び、ポリシー作成について

##### **ユーザー & グループの作成**

* 「**アイデンティティとセキュリティ > ドメイン**」にアクセス


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/ceb0b276-d830-4041-880e-cdb3d3fe5b8a.png)

* Defaultを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/1e8505b4-e975-4499-a7fc-533fe3481153.png)

* 「**グループ > グループの作成**」をクリック
グループ名（test-dev-group）を入力して作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/85b3a891-6859-4ed0-b0bc-4b7a0f654d71.png)


* 「**ユーザ > ユーザの作成**」をクリック
姓名、メールアドレスの入力を実施
画面下部で先ほど作成したグループ（test-dev-group）を選択し、作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/92fec2ef-7589-418f-8ac7-b06d4fa908ac.png)


##### ポリシーの作成

* **「アイデンティティとセキュリティ > ポリシー**」をクリック
  [ポリシーの作成]を選択
  以下を入力して作成

1. 名前・説明・適用するコンパートメントを指定
2. **ポリシー・ビルダー**でテンプレートから選択、もしくは「手動エディタ」で直接記述
3. アイデンティティ・ドメイン：Default
   グループ：先ほど作成したグループ（test-dev-group）
   場所：適用したいコンパートメントを指定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/6c154be5-460e-4d53-8abd-252c768eaba6.png)

作業自体はこれで完了となります。

#### 【参考】ポリシー・ステートメントの記述・集約について

ポリシーステートメント（ポリシー文）を記載する時に1つ1つポリシー・ビルダーからユースケースを選択するのは煩雑です。

ポリシー・ビルダー内で選択できるものであれば、選択後、[手動エディタの表示]を押すとポリシーステートメントが表示されます。

それを別途メモっておき、またポリシー・ビルダーから別のユースケースを選択し、、、ということを繰り返します。

必要なポリシーステートメントが集まれば[手動エディタ]に張り付けることでポリシーを集約できます。

※1つのポリシー内に記載できるポリシーステートメントは50個までなのでそれを超える場合は複数ポリシー作成する必要があります。

* ポリシー・ユース・ケースから必要なポリシーを設定した後、[手動エディタの表示]をクリック]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/0a0d8eeb-1f42-4bf8-99fd-e31040a109d8.png)


* ポリシーステートメントを別途メモしておく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/5d796f3a-f5eb-4e39-b5d3-2a61ea6cbd00.png)


* 上記を繰り返し、必要なポリシーステートメントを集めた後、[手動エディタ]に張り付け、作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2471135/d579ca97-4a79-44d0-9c84-8a3367038697.png)


### まとめ

OCIのPolicyは、英語の自然文で「誰が・何を・どこで」操作できるかを柔軟かつ明確に定義できる仕組みです。

ポリシービルダー機能やテンプレートにより、初学者でも直感的に設定可能であり、運用者には強力なアクセス制御を提供できるのかなと個人的に感じました。

他クラウドと比較しても、シンプルかつコンパートメントを活用した階層的な管理が特徴です。

今回あらためてOCI IAM Policyについてまとめました。

自己学習の備忘録となりますが、OCIをはじめたばかりの方などの一助になればと思います。