クマ松です。
突然ですが、S3バケットのバケットポリシーの設定を誤り、バケットをロックアウトさせてしまった経験はありますでしょうか。
私はあります。
今回はAWSを勉強したての頃に誰もが一度躓くであろうポリシーの話を、銀魂のキャラを使って説明しようと思います。
わかっているようでわからない、アイデンティティベースのポリシーとリソースベースのポリシーのお話です。
※ちなみにバケットポリシーの設定をミスしたらこう↓↓なります。
こうなったらIAMユーザでは何もできないので、ルートユーザにバケットポリシーを消してもらうしかありません。


IAMユーザにAdministratorAccessを付与して作業していると、AWSコンソール画面で何でも出来てしまうと錯覚してしまいます。
しかし実際はAdmin権限を持ったIAMユーザも最強というわけではなく、AWSサービスの設定次第では設定変更はおろかリソースの閲覧すらできなくなります。
アイデンティティベースのポリシー
IAMアイデンティティって何?
AWSのホワイトペーパーに「IAMアイデンティティ」という単語が出てきます。
IAMの勉強をしていた頃この言葉が何を指すのかよくわかっていなかったのですが、IAMユーザ・IAMグループ・IAMロールの総称です。
| IAMの用語 | 意味 |
|---|---|
| IAMユーザ | AWSアカウントにログインしたりAWSサービスを利用する為に必要な名前と認証情報。 |
| IAMグループ | 1人以上のIAMユーザを論理的にまとめたグループ。 |
| IAMロール | AWSサービス(EC2・Lambda)等に、異なるAWSサービス(S3・DynamoDB等)を操作させたい場合に付与するもの。 |
IAMポリシーって何?
IAMユーザ・IAMグループ・IAMロールというIAMアイデンティティは、それ単体では何の操作権限もありません。
私たちが普段コンソールで色々とAWSサービスを操作できるのは、そうできるようなIAMポリシーをIAMユーザにアタッチしているからです。
IAMユーザ・IAMグループ・IAMロールは、IAMポリシーがアタッチされていないと何も出来ませんし、何にもアタッチされていないIAMポリシーは無価値な存在です。
3つのIAMポリシー
IAMポリシーには3つの種類があります。
| IAMポリシー | 意味 |
|---|---|
| AWS管理ポリシー | 様々なユースケースを想定してAWSが準備してくれたIAMポリシー。 |
| ユーザ管理ポリシー | AWSではなく、ユーザが用途に応じて作ったIAMポリシー。 複数のIAMアイデンティティにアタッチできる。 |
| インラインポリシー | AWSではなく、ユーザが用途に応じて作ったIAMポリシー。 複数のIAMアイデンティティにアタッチできない。 単体のIAMアイデンティティに組み込む刺青のイメージ。 |
AWS管理ポリシーとユーザ管理ポリシーは、IAMポリシーのコンソール画面で確認が出来ます。
AWS管理ポリシーはポリシー名の左側に黄色い四角いマークがつきます。ユーザ管理ポリシーにはつきません。
またこの画面でインラインポリシーを確認することは出来ません。

ユーザ管理ポリシーがアタッチされたIAMロールを見てみると、ポリシー名がリンクになっていることが分かります。
このリンクを押すとポリシー一覧の画面に飛び、ポリシーの変更やポリシーを他のIAMアイデンティティにアタッチすることが出来ます。
一方インラインポリシーがアタッチされたIAMロールを見てみると、ポリシー名がリンクになっていないことがわかります。
これはポリシーの変更がこのIAMロールの画面でしか出来ないことを意味します。
以下のfirehose_delivery_roleはこのIAMロールにアタッチされていて、他のIAMアイデンティティにアタッチすることは出来ません。
リソースベースのポリシー
IAMにはアイデンティティベースのポリシー以外にもリソースベースのポリシーがあります。
リソースベースのポリシーとは、そのリソースの利用許可・閲覧許可をリソース自身で定義できるポリシーのことです。
リソース自体に埋め込むポリシーということでこちらのポリシーもインラインポリシーの1つです。
例えるなら武士は幕府から帯刀が許されていたが、妖刀村真紗を抜刀し使いこなせたのは土方十四郎だけだった。
そんなイメージです。刀も主を選びます。
Principalという項目
リソースベースポリシーを利用できるAWSリソースが誰に自分自身を使わせたいかを決めるためには、自分に組み込まれたポリシー内にPrincipalという項目を付与します。
このPrincipalですが、アイデンティティベースのポリシーには設定できない項目です。
| ポリシー | "誰にリソースを使わせたいか"の定義方法 |
|---|---|
| アイデンティティベースのポリシー | ポリシーをIAMアイデンティティにアタッチ |
| リソースベースのポリシー | ポリシー内のPrincipal項目で指定 |
リソースベースポリシーを利用できるAWSサービス
全てのサービスがリソースベースポリシーを利用して利用者を制限できるわけではありません。
どのサービスがリソースベースポリシーを利用できるかは、以下のサイトから確認できます。
以下の表を見ると、S3はリソースベースポリシーを利用でき、ESは利用できないことが分かります。

Storageサービス以外のIAMを使った認証・認可の仕様についてはユーザガイドをご確認ください。
出典:AWS services that work with IAM AWS UserGuide
明示的Deny・明示的Allow・暗黙的Denyを説明する為の例え話
AWS SAA受験の為にIAM関連の勉強をしていると、明示的Deny・明示的Allow・暗黙的Denyという用語に出くわします。
そもそも勉強したての頃は覚えることが多くて、Resource・Effect・Action…何が何だか…
とりあえず「明示的Deny>明示的Allow>暗黙的Deny」と覚えていれば試験は通りますが、これがどういうことなのかを銀魂を使って説明していきます。
前提
アイデンティティベースのポリシーとリソースベースのポリシーを例え話を使って説明しますが、ここからはIAMアイデンティティとリソースは同一AWSアカウント内にあるという前提で読んでください。
キャラにアタッチするポリシーの説明
まず土方十四郎にアタッチするIAMポリシー(アイデンティティベースのポリシー)と、妖刀村真紗に組み込むリソースベースポリシーを定義します。
土方十四郎はあらゆる刀を使うことが許され、タバコも吸うことを許可されています。
一方で村真紗は土方以外の人間が帯刀することも使うことも出来ないです。
坂田銀時は主人公なのでAdministratorAccessを付与します。

明示的Deny ~銀さんは村真紗を使えるか~
ではAdministratorAccessを付与された坂田銀時は村真紗を使うことが出来るでしょうか。
答えはNOです。
これが明示的Deny>明示的Allowと呼ばれる評価論理による制御です。
アイデンティティベースのポリシーかリソースベースのポリシーのどちらかでDenyが書かれていたらDenyが優先されます。
この理解が無いと、冒頭のS3バケットのようなミスが発生します。
リソースベースポリシーのDeny設定は細心の注意を払って設定しなくてはなりません。
明示的Allow ~洞爺湖の仙人の木刀を追加~
では銀さんの愛刀洞爺湖の仙人からもらった木刀に以下のようなリソースベースポリシーを設定してみましょう。
洞爺湖の木刀は「帯刀・人を守るために使う」ことに加えて醤油差しとしての機能を持っています。
一方で、「人を殺すために使う」ことは明示していません。
またPrincipalには坂田銀時と土方十四郎を設定しています。
では問題です。
- 坂田銀時は洞爺湖の仙人の木刀を**「人を殺すために使う」**目的で利用できますか
- 土方十四郎は洞爺湖の仙人の木刀を**「刃先から醤油を垂らす」**目的で利用できますか
正解はどちらもYesです。
これがアイデンティティベースのポリシーとリソースベースポリシーの評価理論における明示的Allow>暗黙的Denyの制御によるものです。
皆さんがAdministrator権限を持つIAMユーザで、特にバケットポリシーの設定が無いS3の設定変更をできるのはこの評価論理の為です。
アイデンティティベースのポリシーとリソースベースポリシーにAllowが書かれている場合、双方に記載されたAllowが評価対象となり、両ポリシーの和集合で制御が認可されます※。
上の例で言うと坂田銀時のAdministratorの「"Action":"*"」は全ての動作が含まれます。
そして「"Resource":"*"」には全ての刀が含まれることになります。
よって坂田銀時は洞爺湖の木刀を「人を殺すために使う」ことが出来るのです。
土方十四郎が洞爺湖の仙人の木刀を「刃先から醤油を垂らす」目的で利用できるのも同じ理由です。
土方十四郎のActionには「刃先から醤油を垂らす」がなく、暗黙的にDenyされています。
しかし洞爺湖の仙人の木刀側では土方十四郎が「刃先から醤油を垂らす」目的で利用することを明示的にAllowしています。
よって土方十四郎は、彼自身が意図しなかったとしても洞爺湖の木刀で刃先から醤油を垂らして卵かけご飯に醤油をかけることができます。
※あるIAMアイデンティティが異なるAWSアカウントのリソースにアクセスする場合や、AWS OrganizationsのService Control Policyが掛かっている場合等は、勝手が変わってきます。SAPやSecurity Specialtyの試験ではむしろこのような条件下でのIAMに関する知識が問われるますので注意してください。
S3バケットで確認
本当に自分自身のIAMユーザに権限が無くても、リソースを操作出来てしまうんでしょうか。
S3バケットとIAMユーザを使って検証します。
S3バケットポリシー
パスワードの変更権限のIAMポリシーをアタッチしたIAMユーザ「nobody」を作成します。
Resourceにはバケット名を設定し、EffectにAllow、Principalにnobodyを加えます。
バケット一覧では閲覧できない
nobodyでログインしてバケットの一覧を表示しようとしましたが、該当のバケットは表示されませんでした。
上記のバケットポリシーの設定の感じから、testバケットのみ表示されても良さそうなところですが実は現時点で一部のS3バケットのみGUIで表示することはできません。
ですのでtestバケット以外を閲覧する権利の無いnobodyは以下のようなエラーが表示されます。
バケットのURLを使って直接アクセス
ではnobodyはtestバケットに対して何もできないのかというと、そういうわけではありません。
仕様上バケット一覧から個々のバケット名のリンクを押す形でバケットの詳細画面に飛ぶことはできませんが、飛ぶためのURLさえ分かっていれば、ブラウザにURLを打ち込んでバケットの詳細画面に飛ぶことが出来ます。
※URLはこんな感じです。
https://s3.console.aws.amazon.com/s3/buckets/test-************?region=ap-northeast-1&tab=objects
バケットに対してオブジェクトをアップロード
この画面まで来れれば、オブジェクトのアップロードが出来ます。
以上です。







