OCI IAM ポリシーによる権限管理 ～ ケース別チートシート ～

# １．概要
本記事では、Oracle Cloud Infrastructure の認証・認可の仕組みである **IAM (Identity and Access Management)** を利用した OCI の権限設定の例を ケース別に いくつかご紹介したいと思います。
はじめに IAM のおさらいや 設定手順を記載しますが、不要な方は ２については 読み飛ばしてください。

# ２．OCI 権限管理のおさらい
まず始めに OCI の権限管理に関して、おさらいしておきたいと思います。
詳しくは [別の記事](https://qiita.com/Skogkatter112/items/51b619026aa53a9c6069) をご参照頂きたいのですが、OCI のサービスに関して アクセス管理や 権限設定をしたい場合、**IAM (Identity and Access Management) ポリシー** を使って 認可を与えていくことになります。

## 2-1. ポリシーの構文
ポリシーは、次のようなステートメントで構成されます。１つのポリシーに複数のステートメントをまとめて記述することも可能です。
>**allow group <font color="Red">\<group_name></font> to <font color="LimeGreen">\<verb></font> <font color="DeepSkyBlue">\<resource-type></font> in <font color="BlueViolet">tenancy</font>**
**allow group <font color="Red">\<group_name></font> to <font color="LimeGreen">\<verb></font> <font color="DeepSkyBlue">\<resource-type></font> in <font color="BlueViolet">compartment \<compartment_name></font> \[where <font color="Sienna ">\<conditions></font>]**

それぞれ、**<font color="Red"><どのグループが></font> <font color="LimeGreen"><どのような操作を></font> <font color="DeepSkyBlue"><どのリソースに関して></font>** 可能か、
また、**<font color="BlueViolet"><その操作が可能な範囲></font>** を、テナンシー全体 (*in tenancy*) または 個別のコンパートメント (*in compartment ～*) という形で指定しています。
<font color="Sienna">**<条件>**</font> のオプションを指定することで、更に細かく権限を絞ることも可能です。

<font color="Silver">※ OCI IAM には「管理者ロール」や「ネットワーク管理者ロール」といった抽象的な、予め用意されたロールというものはありません。その為、**最小権限の原則に則りながら、こういった構文を組み合わせて権限を与えていく** という流れになります。
※ 何のポリシーも設定していない状態であれば、全ての操作が拒否されます。</font>

## 2-2. ポリシーの割当て
ポリシーは、ユーザーに対して直接与えることは出来ません。必ず **グループを通して認可を与える** ことになります。
従って、あるユーザーに認可を与えたい場合、大まかな流れは次のようになります。(順番は前後しても問題ないです。)  
>１．グループ"A"を作成
２．IAM ユーザー"X"を作成
３．IAM ユーザー"X"を グループ"A"に追加
４．（必要に応じて）コンパートメント"N" を作成
５．ポリシーを作成（グループ"A"にどのような権限を与えるか記述、ポリシーの範囲はテナンシーorコンパートメントを指定）

![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384668/9c2785b3-e030-555c-67dc-6cf0140d5f3a.png)

具体的な手順については、下記の Web ページが 分かり易いと思います。

- Oracle Cloudを使う、その前に！覚えてほしい３つのポイント：  
[https://www.ashisuto.co.jp/db_blog/article/N0023_OracleCloud_20200710.html](https://www.ashisuto.co.jp/db_blog/article/N0023_OracleCloud_20200710.html)



# ３．ケース別ポリシー設定例
よく設定しうるステートメントや、こんな権限設定はできないの？といった部分について、例を挙げます。マニュアルにも「よく使用される可能性のある一般的なポリシーの例」がありますので、本記事の最後に載せている「参考URL」をご参照ください。

## case1. コストや予算を閲覧させたくない
テナントに設定した予算や使用状況などは、多くのユーザーには閲覧させたくない、というケースがあるかと思います。そういうケースにおいては、対象のグループに対して、**下記権限を "与えない" ように** 留意してください。

```:《コスト分析》機能に関する権限
Allow group <group_name> to read usage-reports in tenancy
```
>・この権限を与えると《コスト分析》機能が利用できるようになります。
・このステートメントは `in tenancy` で設定する必要があります。
・**あるグループに、あるコンパートメントに関する使用状況のみ見せる、といったことは出来ません**。※ where target.compartment.name = 'xxxx' などで絞れそうですが、この設定を行うと そもそもフィルタの実行自体が出来なくなってしまうため、実現できませんでした。(2020/09/10 時点)

```:《使用状況のレポート》に関する権限
define tenancy usage-report as ocid1.tenancy.oc1..aaaaaaaaned4fkpkisbwjlr56u7cj63lf3wffbilvqknstgtvzub7vhqkggq
endorse group <group_name> to read objects in tenancy usage-report
```
>・この権限を与えると、使用状況レポート（テナント内の各リソースの使用量データに関する日次ファイル）の利用が可能になります。
・このステートメントは、必ずポリシーの先頭に定義する必要があります。

```:《予算》に関する権限
Allow group <group_name> to <verb> usage-budgets in tenancy
```
>・この権限を与えると、コンパートメント毎の予算の作成や その一覧の閲覧 が可能になります。

```:テナントの全体管理者権限
Allow group <group_name> to manage all-resources in tenancy
```
>・この権限を与えると、テナント内での全ての操作が可能になります。当然コストや予算の閲覧も可能になります。
・最小権限の原則に則る観点から、多くのケースにおいてこの権限を付与するのは避けた方が良いです。

## case2. 特定のグループにのみユーザー追加・削除を許可したい
例えば developerグループに所属するユーザーに、自分の所属するグループへのユーザー追加・削除は 自由にやらせたいが、それ以外のグループ (例えばAdministratorsグループ等) への操作は許可したくない場合があると思います。
そういったケースにおいては、対象のグループに対して、下記権限を 与えることで 実現可能です。

```:グループの操作に関する権限
Allow group developer to inspect groups in tenancy
Allow group developer to manage groups in tenancy where target.group.name = 'developer'
```
>・この権限を与えると、"developer" グループに所属するユーザーは、テナント内に存在する全てのグループの一覧が確認できます。
・ユーザーの追加・削除は target.group.name で指定したグループに対してのみ、可能となります。
・この権限だけでは、テナント内に新たにグループを作ることも許可されません。

## case3. テナントレベルでのポリシー変更をさせたくない
あるコンパートメント（例えばprojectコンパートメント等）レベルでのポリシー定義に関しては 自由にやらせたいが、テナントレベルでのポリシー設定はさせたくない、といった場合があるかと思います。
そういった場合は、「ルートコンパートメントに作成するポリシー」および「あるコンパートメントに作成するポリシー」の２つのポリシーを作成し、下記の設定を行う事によって実現可能です。

```:ポリシーに関する権限（ルートコンパートメントに作成）
Allow group developer to inspect policies in tenancy
```
>・この権限を与えると、"developer" グループに所属するユーザーは、テナント内に存在する全てのポリシーの一覧を確認できます。
・ルートコンパートメント上で新たなポリシーを追加することは出来ません。

```:ポリシーに関する権限（あるコンパートメントに作成）
Allow group developer to manage policies in compartment project
```
>・この権限を与えると、"developer" グループに所属するユーザーは、project コンパートメントにかかるポリシーの作成・変更が可能になります。
・"in tenancy" のように、テナントレベルにかかるポリシーの追加は出来なくなります。

## case4. ポリシーの削除をさせたくない
既存のポリシーの誤った削除を避けるため、ポリシーの削除を行えないようにしたい場合、下記の設定を行います。

```:ポリシーに関する権限
Allow group <group_name> to manage policies in tenancy where request.permission != 'POLICY_DELETE'
```
>・この権限を与えると、対象のグループに所属するユーザーは、テナント内のポリシーに対する削除が行えなくなります。

## case5. ユーザーの資格証明に関する操作を行わせないようにしたい
資格証明（APIキーや、認証トークン、顧客秘密キーなど）を むやみに利用できるようにしてしまうことで、思わぬアクセスを許可してしまう、ということのないよう、資格証明に関する操作権限を絞りたいケースがあるかと思います。
そういった場合には、下記のように条件を絞ることで、資格証明に関する操作を行わせないようにすることが可能です。

```:資格証明に関する権限
Allow group <group_name> to manage all resources in tenancy
 where all {request.operation!='ListApiKeys',
            request.operation!='ListAuthTokens',
            request.operation!='ListCustomerSecretKeys',
            request.operation!='UploadApiKey',
            request.operation!='DeleteApiKey',
            request.operation!='UpdateAuthToken',
            request.operation!='CreateAuthToken',
            request.operation!='DeleteAuthToken',
            request.operation!='CreateSecretKey',
            request.operation!='UpdateCustomerSecretKey',
            request.operation!='DeleteCustomerSecretKey'}
```
>・この権限を与えると、対象のグループに所属するユーザーは、API キーや認証トークンなど、資格証明の発行や削除に関する操作が行えなくなります。

## case6. あるグループに対して ある程度自由な権限を持たせたい
最小権限の原則に則ると言えど、検証段階では ある程度 自由な権限を持たせたい場合があります。とはいえ権限が大きすぎるが為に 無用なトラブルが発生することは避けたいと思います。
下記の権限は、そういった場合に与えることを検討しても良いと考えられる権限の一覧です。
あくまで一例ですので、必要に応じて検討してください。

```:特定のコンパートメント内の全リソースに関する権限
Allow group <group_name> to manage all-resources in compartment <compartment_name> 
where all{request.permission != 'TRANSFER_JOB_CREATE',
 request.permission != 'TAG_NAMESPACE_CREATE',
 request.permission != 'COMPARTMENT_CREATE'}
```
>・この権限を与えると、対象のコンパートメント配下の全てのリソースに関する管理権限が付与されます。
・ただし、条件文によって、「転送ジョブの作成」「タグ・ネーム・スペースの作成」「コンパートメントの作成」操作については禁止しています。（これらは、作成されると削除に手間がかかる／管理が煩雑になるため、除外する条件を追加しました。必要に応じて削除しても問題ありません。）

```:テナント内のサービス制限を閲覧する権限
Allow any-user to inspect limits in tenancy
```
>・この権限を与えると、テナント内のサービス制限が閲覧できます。
・この権限を与えることにより、ユーザーがサービスの作成に失敗した場合に、サービス制限によるものか否かを自分で確認できます。

```:通知を閲覧する権限
Allow any-user to read announcements in tenancy
```
>・この権限を与えると、テナント内のメンテナンス情報などが閲覧できます。

```:動的グループを作成する権限
Allow any-user to manage dynamic-groups in tenancy
```
>・この権限を与えると、インスタンス・プリンシパルに認可を与えるための動的グループを作成できるようになります。


#４．参考URL
- **共通ポリシー**
組織内で使用する可能性がある一般的なポリシーに関するリファレンスです。
本記事で紹介したケース以外に豊富なリファレンスとなっていますので是非ご参照ください。
 
 - [https://docs.oracle.com/cd/E97706_01/Content/Identity/Concepts/commonpolicies.htm](https://docs.oracle.com/cd/E97706_01/Content/Identity/Concepts/commonpolicies.htm)

- **ポリシーリファレンス**
verb や resource type に関する詳細なリファレンスです。
  - [https://docs.cloud.oracle.com/ja-jp/iaas/Content/Identity/Reference/policyreference.htm](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Identity/Reference/policyreference.htm)

- **IAM・認可に関するベスト・プラクティス**
Oracle が公式で記載している、認可に関するベスト・プラクティスです。MFA を強制するポリシー例などもあります。運用する上で是非一度ご確認ください。
  - [https://docs.oracle.com/ja/solutions/oci-best-practices/manage-identities-and-authorization.html#GUID-ECDA4F04-3010-4E40-A93F-CD516869A24F](https://docs.oracle.com/ja/solutions/oci-best-practices/manage-identities-and-authorization.html#GUID-ECDA4F04-3010-4E40-A93F-CD516869A24F)
  - [https://docs.cloud.oracle.com/ja-jp/iaas/Content/Security/Reference/iam_security.htm#SecurityPolicyExamples](https://docs.cloud.oracle.com/ja-jp/iaas/Content/Security/Reference/iam_security.htm#SecurityPolicyExamples)

- **コンパートメント割当て**
コンパートメント割当てに関するリファレンス
※本記事では紹介していませんが、ポリシーとは別に、サービス別の使用可能な割当て制限を設定することが可能です。詳細については上記リンクをご参照ください。
  - [https://docs.oracle.com/cd/E97706_01/Content/General/Concepts/resourcequotas.htm#four](https://docs.oracle.com/cd/E97706_01/Content/General/Concepts/resourcequotas.htm#four)