[AWS]管理ポリシーとインラインポリシーの違いが分からなかったので改めてIAMポリシーのお勉強をする


#3年越しの加筆

このqiitaの記事を書いたのは2017年ですが、その内容を取り込んで、2020年に以下の記事を書きました。

[IAMポリシーの管理画面で出てくる「AWS管理のジョブ機能」って何?｜クラスメソッドブログ]
https://dev.classmethod.jp/cloud/aws/iam-job-function/#toc-iam1

併せてお読みいただけると、より理解が深まるかと思います。

---

#はじめに
これまで私がIAMユーザーへ「ポリシー」を付与する際には、
下記の一辺倒でしか闘ってきませんでした。

- IAMグループに「ポリシー」をアタッチする
- IAMグループにIAMユーザーを追加する


ポリシーの種類を深く考えることがなかったので、おさらいも兼ねて整理していきます。

#0.IDベースかリソースベースか
いきなり少し脱線します。
AWSにおけるアクセス権限を付与する方法は2種類あります。

http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_permissions.html#TypesPermissions

|項番|種類|概要|
|:--|:--|:--|
|①|IDベース|いわばIAMのこと。「誰がどのリソースに対して○○できる」|
|②|リソースベース|例えばS3のバケットポリシー。「このリソースに対して誰が○○できる」|

②に関してはS3のバケットポリシーの他に、
SNSのtopic policyやVPCエンドポイントポリシーが該当します。

詳細は下記ページの[リソースベース]列がYesのものを参照してください。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html

今回はIAMポリシーの話なので、以降の記述はすべて①に該当します。

#1.IAMポリシーの適用先
プリンシパルエンティティと呼ばれる下記3つに、
IAMポリシーを適用することができます。

1. IAMユーザー
2. IAMグループ
3. IAMロール


ここで、「IAMグループに適用したポリシー」が、
「そのIAMグループに参加しているIAMユーザー」に
継承されるというのがひとつのポイントです。

IAMユーザーは「IAMグループから継承したポリシー」と、
「自身に適用されたポリシー」の両方の権限を持つことになります。

さらにそのポリシーも細分化されて…となっていきます。


（これ以降、毎回”IAMユーザーやグループやロール…"というのはカッコ悪いので、すべて「プリンシパルエンティティ」と記載します。）



#2.IAMポリシーの種類
まず、下記2種類に分かれます。

- 管理ポリシー
- インラインポリシー

そしてさらに前者が2種類に分かれます。

- 管理ポリシー
    - AWS管理ポリシー
    - カスタマー管理ポリシー
- インラインポリシー

それぞれの違いを確認します。

##2.1.管理ポリシーとインラインポリシー
|項番|種類|型|概要|
|:--|:--|:--|:--|
|③|管理ポリシー|スタンドアロン型|「ポリシー」単体として存在できて、複数のプリンシパルエンティティにつけたり外したりできる。|
|④|インラインポリシー|埋め込み型|「ポリシー」単体では存在できず、プリンシパルエンティティと1対1の関係にある。|

###両者の使い分け
基本的には、③管理ポリシーを使うことが推奨されているようです。
>管理ポリシーとインラインポリシーの比較
>>各用途向けにさまざまなポリシーが用意されています。通常、インラインポリシーではなく、管理ポリシーを使用することをお勧めします。

http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#choosing-managed-or-inline

- 1対多の関係でプリンシパルエンティティにアタッチできる
- ポリシーの変更時にはアタッチ済みのプリンシパルエンティティすべてに反映される
- ポリシーの変更をバージョン管理できる

こういったところが便利ですね。

④インラインポリシーだとこうはいかず、
プリンシパルエンティティごとに変更を加える必要があります。

逆に、意図しない形でアクセス権の付与や変更が行われないようにしたい場合には、
④を使用するのが良しとされているようです。

##2.2.AWS管理ポリシーとカスタマー管理ポリシー
|項番|種類|概要|
|:--|:--|:--|
|⑤|AWS管理ポリシー|予めAWSによって用意されている管理ポリシー。大まかに各AWSサービスごとにフル権限と読み取り権限が用意されている。|
|⑥|カスタマー管理ポリシー|利用者が独自に作成する管理ポリシー。ジェネレータで作成するか手書きで作成する。|

###両者の使い分け
これはどこまで細かく権限を設定したいか、によって変わってくるかと思います。

⑤AWS管理ポリシーは、あくまでざっくりと下記のような権限付与だけができます。

- EC2すべてに対して何でも操作可能
- S3バケットすべてに対して読み取りだけ可能


それに対して⑥カスタマー管理ポリシーは、もう少しきめ細かい権限付与が可能です。

- 特定のタグがついたEC2に対して、起動停止だけ可能
- 特定のS3バケットに対してPUTのみ可能


⑤と⑥を複数アタッチすることも可能（デフォルトで最大10まで）なので、
セキュリティ要件によって適切にポリシーを設定しましょう。

###ちょっとだけ補足事項
- ポリシー一覧を見た時に、チェックボックスの隣にAWSのアイコンが表示されているのが⑤です。
- ⑤は新サービスの開始などによって適宜内容が（AWSによって自動的に）修正され、「編集時刻」からアップデートされことを確認できます。

![IAMポリシー.JPG](https://qiita-image-store.s3.amazonaws.com/0/155963/d4651923-41e9-76a9-60e2-a5515d81f2d1.jpeg)


#3.ポリシーの評価論理
ここまで見てきたようにポリシーには様々な種類があります。
複数のポリシーを同一のプリンシパルエンティティにアタッチした場合、
どういった風に権限が制御されるかを確認します。

簡単に言えば、下記の通りになります。

- デフォルトでは拒否
- デフォルトの拒否より明示的な許可が強い
- 明示的な許可より明示的な拒否が強い

そしてこれは、IAMポリシーに限定した話ではありません。
①のIDベース、②のリソースベース合わせての考え方となります。

http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#policy-eval-denyallow

>リクエストに適用可能なユーザーベースおよびリソースベースのポリシーすべてを、リソース、プリンシパル、アクション、および条件に基づいて評価します。

実際の評価の流れを見ていきます。

特定のAWSリソースに対してリクエストがなされた時に、
①②を含めて評価が行われ、許可もしくは拒否が決定されます。

１. (デフォルト拒否でスタート)
　　　　↓
２. 明示的な拒否があるか→＜yes＞→【拒否】
　　　　↓
　　　＜no＞　　　　　　
　　　　↓
３. 明示的な許可があるか→＜yes＞→【許可】
　　　　↓
　　　＜no＞　　　　　　
　　　　↓
４.　【拒否】


##実例
S3バケット「Backet」と、IAMユーザー「Batchi」で考えます。
「Backet」内のオブジェクトを「Batchi」が参照したい場合。

●両者ともポリシー設定なし
　→デフォルト拒否により参照できません。

●「Backet」ポリシーなし／「Batchi」参照を許可するIAMポリシー付与
　→明示的な許可により参照可能です。

●「Backet」"Batchiを拒否する"ポリシー付与／「Batchi」参照を許可するIAMポリシー付与
　→明示的な拒否により参照できません。

###"NOT A"の場合に注意
では次のケースではどうでしょうか。

●「Backet」"Batchi以外は許可する"ポリシー付与／「Batchi」参照を許可するIAMポリシー付与

答えは、「参照可能」です。

"Batchi以外は許可する"というのはつまり"NOT A"ですが、
これは「明示的な拒否」ではなく「デフォルト拒否」として扱われます。

よってIAMポリシーによる「明示的な許可」によって評価は「許可」になります。

ここのあたりは要注意ですね。

ドキュメントでは分かりやすいような分かりにくいような例が載っています。
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_evaluation-logic.html#AccessPolicyLanguage_Interplay


#おわりに
というわけでIAMポリシーの話でした。
IAMポリシーの話のはずでしたが、リソースベースのポリシーの話も含まれてきました。

ここらへんはうっかり「デフォルトの拒否」が発生しないように、
明示的な拒否と許可を意識して付与していったほうが良さそうですね。

インラインポリシーと管理ポリシーは、基本的に管理ポリシーを使う。

AWS管理ポリシーとカスタマー管理ポリシーは、
完全に「要件によりけり」ですが、個人的には、

- IAMユーザーにはAWS管理ポリシー多少広めに権限付与
- IAMロールにはカスタマー管理ポリシーでギッチギチの権限付与

というのを見かける機会が多いかなと感じています。
（おすすめの割り方があれば教えてください）

##蛇足
こちらのryo0301さんの記事に、
今回書いたようなことがみっちり書いてあって少し凹みました。
http://qiita.com/ryo0301/items/791c0a666feeea0a704c

以上です。